Clara Application Security Assessment
Last updated 21 October 2026 (version 1.0)
This page is a public summary of our confidential Application Security Assessment report (version 1.0, 21 October 2026). The full report, including every finding, its fix and our coverage of each attack surface, is available to customers and prospects on request, under NDA. Email miles@xlabs.co.za.
1. Summary
Between 19 and 21 October 2026, xlabs (Pty) Ltd ("xlabs", "we") ran a site-wide security assessment of Clara, acting as an attacker would. The aim was to find weaknesses that could let someone read or change client, policy, health or financial information they should not reach, move money without approval, or cross from one organisation into another, and to fix them.
We found 67 issues: 1 critical, 5 high, 26 medium, 4 low to medium, 28 low and 3 informational. 62 were fixed and verified. The other 5 were closed without a code change: one accepted risk, one made obsolete when passwords were removed, and three withdrawn as business or compliance design choices rather than security weaknesses. No issue is open.
The assessment was carried out internally by the xlabs engineering team using AI-assisted code review and testing. It is not an independent third-party test. Every finding was confirmed before it was logged, and every fix was tested and then checked by a separate reviewer before it went live.
2. Scope
In scope
- The Clara application: every page, API route, webhook, scheduled job and AI assistant tool.
- The databases behind each organisation, as reached through the application and the public database key.
- Database configuration: row-level security, function settings and permissions.
- Third-party packages the application depends on.
Out of scope
- Third-party systems (accounting, payment, messaging, email and provider portals). We tested how Clara handles their callbacks and credentials, not the systems themselves.
- Denial-of-service and load testing.
Rules we worked to
- On the live site, only read-only checks while signed out. No logins, no writes, no load.
- Tests that sign in or write run only on a dedicated test organisation, never on a customer's.
- No real client data was used, changed or sent anywhere.
- Only the product owner can accept a risk, recorded with date and reason.
3. How we tested
The work ran in five steps, repeated in waves until no new issues came up.
- Map the attack surface. A script listed every API route and the access guard it calls. Routes with no recognised guard were traced by hand.
- Review by area. Each attack area (below) was reviewed in the code by its own reviewer, looking for a concrete path from an attacker to a harmful result.
- Confirm. Every claimed issue was checked a second time; anything without a realistic attack path was dropped.
- Fix and prove. Each fix came with automated tests showing the attack refused. We then removed the fix to see the test fail, and put it back. A separate reviewer checked every fix before release.
- Guard against regressions. Checks that run before release now catch the patterns behind several findings: routes with no access guard, raw database errors shown to users, and reads that skip policy-type access.
A signed-out sweep of the live site (980 requests across every route) found no data leaks, no errors and no unsafe cross-site access. A check that every API route calls an access guard now covers all 1,132 route handlers.
4. What we tested
| Area | What we looked for |
|---|---|
| Authentication | Sign-in codes, sessions, cookies, password reset, brute force. |
| Authorisation | Every route checks the user's own module, policy-type and record access, not only the organisation's. |
| Organisation isolation | One organisation cannot reach another's data, hosts or connections. |
| Client portal | Portal clients see only their own information and cannot reach staff functions. |
| Webhooks and callbacks | Signatures, replay windows, size limits and connection callbacks tied to the right organisation and browser. |
| Scheduled jobs | Job secrets, internal endpoints and where secrets are sent. |
| Injection | Search, filters and database queries built from user input. |
| Server-side requests | Outbound fetches that could be pointed at internal addresses. |
| AI assistant | Tool access within the user's scope, prompt injection from emails and documents, data leaks through rendered content, writes without approval. |
| Money and approvals | Payments, invoices and accounting writes only after an approval sign-off. |
| Secrets and configuration | No hard-coded fallbacks, no secrets or raw errors returned to users. |
| Database | Row-level security, function settings and permissions on every project. |
| Web hardening | Security headers, content security policy, cross-site access, cookies, redirects. |
| Files | Upload type and size, files served safely, no scripts run from downloads. |
| Dependencies | Known vulnerabilities in packages the application uses. |
| Audit logging | Changes are recorded and cannot be altered by users. |
5. Rating severity
Each issue was rated on how much harm it could do (to client confidentiality, data integrity, money or availability) and how easily it could be reached.
| Severity | Meaning |
|---|---|
| Critical | Directly reachable and allows serious harm, such as changing records or moving work forward without approval. Fixed immediately. |
| High | Allows access to another organisation's or user's data, or bypasses a key control, with limited conditions. Fixed before anything else. |
| Medium | Exposes data or weakens a control, but needs an account, a specific role or other conditions. |
| Low | Small exposure or a defence-in-depth gap with little direct harm. Low to medium sits between the two. |
| Info | No direct harm today; worth recording or tidying. |
6. Findings by severity
| Severity | Found | Fixed and verified | Closed without fix |
|---|---|---|---|
| Critical | 1 | 1 | 0 |
| High | 5 | 5 | 0 |
| Medium | 26 | 23 | 3 |
| Low to medium | 4 | 4 | 0 |
| Low | 28 | 27 | 1 |
| Info | 3 | 2 | 1 |
| Total | 67 | 62 | 5 |
Fixed means the issue was fixed in code, the same attack was re-run and refused, automated tests were added that fail on the old code, an independent review passed the change, and it was released to every organisation.
We do not publish the details of individual findings. The full report is shared with customers and prospects on request, under NDA.
7. Results by area
| Area | Outcome |
|---|---|
| Sign-in and sessions | Password-free email code sign-in with attempt limits. Sessions held only in secure, script-proof cookies, and fully revoked on sign-out. |
| Access control | Every API route checks access. Module grants, policy-type grants and client and Request ownership are enforced on the server, failing closed. A build check stops a new route going live without an access check. |
| Organisation isolation | The organisation is taken only from the address used, never from anything the browser sends. Platform functions need a platform administrator. |
| Client portal | Portal sessions cannot reach staff functions, and portal responses leave out costs, internal notes and other clients. |
| Webhooks and connections | Inbound webhooks are signed, size-limited and checked for replay. Account-connection flows are tied to the organisation and the browser that started them. |
| AI features | Emails and documents cannot make the AI take actions. AI tools re-check the user's access every time they run, and AI output cannot send data to outside addresses. |
| Money and approvals | Payments, accounting writes and client sends run only after an approval sign-off. Writes into locked accounting periods are refused. |
| Files | Uploads are size- and type-checked. Downloaded files cannot run script in Clara. |
| Data and secrets | Row-level security is on for every table. Stored secrets are never returned by any API, and error messages contain no internal details. |
| Web hardening | Security headers, protection against cross-site requests and safe cross-origin settings are in place on the live service. |
| Dependencies | Known vulnerabilities in runtime packages were upgraded away. A small number of moderate advisories remain that need major version upgrades, and are tracked. |
| Audit logging | Changes to key records and integration settings are logged. Users cannot edit or delete the audit log. |
8. Still to do
- Run the signed-in live checks, including cross-organisation checks, on the dedicated test organisation. Each has passed code review and automated tests.
- Switch the content security policy from report-only to blocking once collected reports are reviewed.
- Run the pre-release security checks on every change.
- Upgrade two document-handling packages with major-version updates pending.
- Repeat this assessment after major changes, and commission an independent third-party test.
9. Ongoing testing
Security testing continues as Clara changes. New findings are logged, fixed and re-tested in the same way, and this summary is updated after each major round. To report a security issue, email miles@xlabs.co.za.
10. Version
| Version | Date | Change |
|---|---|---|
| 1.0 | 21 October 2026 | First issue, covering the assessment of 19 to 21 October 2026. |