Security Review

Round 2 · backendApi, capExpertApp and dbMigrations · 19 Oct 2026

Verdict: critical. The round-1 fixes that landed hold up. Internal job endpoints are still open, and they now turn out to reach the database directly. Round 2 also found several ways for admin-side and vendor-side users to act beyond their role.

This public page leaves out file locations, endpoints, parameters and reproduction steps on purpose. The full report is kept off the web.

4 critical open1 new · 3 from round 1
+1 fixed in branch, awaiting dev
15 high open5 new · 10 from round 1 (2 partly fixed)
+1 fixed in branch, awaiting dev
53 medium open25 new · 28 from round 1 (4 partly fixed)
+2 not re-checked · 1 fixed in branch
14+ low open14 new · most round-1 lows still open

On this page

What happens next

  1. This week: lock the internal job endpoints. Stop keeping credentials in the email log. Scope the admin-side password and role tools. Pin vendor identity on offers. Add the approver check to budget approval. Remove the leftover public file serving and the production API docs. Fix the front-end security headers.
  2. This sprint: make exported files and signed agreements private. Close the remaining cross-organisation reads. Add attempt limits and session revocation. Add row locks on checkout and offer acceptance. Put expiry on emailed links.
  3. This quarter: one shared tenant-scope guard, strict request validation everywhere, and safe SQL helpers. Rate limiting, least-privilege database and cloud identities, and encryption of stored credentials. Hardened container images and an audit log.
  4. Process: static analysis and secret scanning in CI, dependency gating, per-role authorization tests, and a security checklist in pull requests.
  5. Rotate the token-signing secret and the keys found in git history after the token fixes ship.

Critical and high

IDs starting with R2- are new this round; the others are from round 1.

IDSeverityAreaFindingStatus
B-C3CriticalBackground tasksInternal task endpoints accept unauthenticated requestsOpen, worse
R2-SQL-1CriticalBackground jobsInternal job payloads reach database queries without validationOpen
B-C4CriticalBackground jobsJob runner accepts any Google service accountOpen
B-C7CriticalFile storageSigned links for other organisations' documentsOpen
F-C1, F-H2CriticalFront endStored script injection in rich textFixed in branch
B-H11HighAdmin user managementPartial admins can reset passwordsOpen, worse
B-H14HighCoPilotBids and prices readable across organisationsOpen, worse
R2-AUTHZ-1HighAdmin user managementSome admin roles can change passwords and roles of users above themOpen
R2-DATA-1HighEmail logCredential emails are stored and readable by adminsOpen
R2-STOR-1HighFile storageExported files and signed agreements are stored publicly readableOpen
R2-BIZ-1HighMarketplace offersA vendor can make offers in another vendor's nameOpen
R2-BIZ-2HighCaptAIn / budgetsAssistant actions can approve budgets without approver rightsOpen
B-H2HighEquipment planningSQL injection in an admin bulk updateOpen
B-H6HighLoginPassword change without a session or attempt limitOpen
B-H8HighCaptureRoom import into any projectOpen
B-H10HighChatbotChat file reference reaches any stored fileOpen
B-H15HighDashboardLayouts changeable platform-wideOpen
F-H1HighLoginOrganisation "require 2FA" not enforcedOpen
B-H7HighChatChat rooms readable without membershipPartly fixed
B-H12HighOnboardingRegistration links handed out too widelyPartly fixed
B-H9HighDocument ManagerAny stored file path acceptedFixed in branch

Medium and low

IDs starting with R2- are new this round; the others are from round 1.

IDSeverityAreaFindingStatus
R2-SQL-2MediumEquipment planningSQL injection in an admin-only report filterOpen
R2-AUTHZ-2MediumMarketplaceVendors can read other organisations' equipment componentsOpen
R2-AUTHZ-3MediumTransactionsPlatform margin can be changed without admin rightsOpen
R2-BIZ-3MediumCheckout and offersDouble submission can create duplicate orders and offersOpen
R2-BIZ-4MediumMarketplaceSellers can set their own listing valuationOpen
R2-BIZ-5MediumShipping quotesShipping price can change after the buyer approved itOpen
R2-BIZ-6MediumDocument extractionAI extraction can be pointed at other organisations' filesOpen
R2-AI-1MediumCoPilot AI summaryBid text can steer the AI summary sent to hospitalsOpen
R2-DOS-1MediumAPI-wideList sizes, query time and request rates are not limitedOpen
R2-DOS-2MediumAI featuresNo per-user limit on AI usageOpen
R2-DB-1MediumDatabaseThe application uses the database owner accountOpen
R2-DB-2MediumDatabase / CaptAInThe analytics role's tenant boundary is incompleteOpen
R2-DB-3MediumDatabaseLogin links and third-party credentials are stored unencryptedOpen
R2-INJ-1MediumEmailUser text is inserted into emails as HTMLOpen
R2-PHI-1MediumEquipment photosPhotos flagged as containing patient information are not access-controlledOpen
R2-LOG-1MediumAuditAdmin actions and data reads are not audit-loggedOpen
R2-AUTH-1MediumLoginEmail lookups allow pattern searching of accountsOpen
R2-AUTH-2MediumCoPilot chat emailReply links in chat emails never expireOpen
R2-FE-1MediumFront endRich-text cleaning still allows fake forms and page overlaysOpen
R2-FE-2MediumFront endSecurity headers are missing on the main pageOpen
R2-INFRA-1MediumCloudA long-lived cloud key file is used at runtimeOpen
R2-INFRA-2MediumContainersImages are outdated and run as rootOpen
R2-INFRA-3MediumAPI docsThe API documentation password can be bypassedOpen
R2-INFRA-4MediumDependenciesBackend package lockfile lacks integrity hashesOpen
B-M1–B-M25MediumBackend, variousOf 25: 0 fixed, 4 partly fixed, 19 open (4 confirmed on the local stack, 3 worse than reported), 2 not re-checkedMostly open
F-M2–F-M6MediumFront endContent policy, token handling, captcha, SSO, external linksOpen
F-M1MediumLoginOpen redirect after loginFixed in branch
R2-L1–L14LowVarious14 hardening items: query escaping, retention, stored PINs and 2FA secrets, offer workflow edges, guard composition, third-party document viewersOpen
LowsLowBoth reposNearly all still open; one closed by stricter input handlingMostly open

Scope and method