Self-conducted security testing #
This is first-party testing. It is performed by the operator, not by an independent assessor, and it does not substitute for the independent external penetration test recorded on Trust. It is published because the substance is useful to a reviewer even where the independence is missing.
Last updated: 2026-10-18.
Testing performed #
| Date | Type | Scope | Outcome |
|---|---|---|---|
| 2026-05-26 | Code-level security assessment | Static analysis, dependency audit, and manual review of authentication, authorization, and file handling | Upload handling identified as the highest-risk area. Findings tracked in the issue tracker and remediated: server-side attachment-count limits, direct-upload authorization, and parameter and IP scrubbing in logs |
| 2026-05-26 | External production test, non-destructive | Response headers, TLS configuration, public pages, and metadata probes against the production host | Response-header coverage gaps and missing security-contact metadata; reliance on third-party asset CDNs assessed as medium risk. Remediated 2026-05-27: security-contact metadata published, content-type sniffing protection extended to static assets |
| 2026-06-09 | Authentication review | Cookie handling, session lifecycle, magic-link and invitation flows | Two informational findings. Remediated 2026-06-14: the pending-authentication cookie moved to an encrypted store so the address is not readable client-side; the session cookie’s stated expiry now matches the 14-day server-side idle timeout. One low-severity finding: whistleblowing channel addresses were derived from sequential identifiers, so the set of customer organizations could be enumerated. Remediated 2026-08-12: each channel has a private random address, and the page shown for an inactive channel no longer names the organization |
| 2026-08-27 | Authenticated graybox test | Cross-tenant access, privilege escalation, mass assignment, within-tenant report access, attachment confidentiality, SCIM isolation, SAML assertion trust | No authorization defects found. Tenant and role boundaries held in every case tested |
| 2026-08-27 | Production exposure review | Network exposure, host hardening, proxy header handling, secret handling | Client-supplied forwarding headers were trusted on a directly internet-facing origin, which would have allowed the per-IP rate limits to be bypassed. Fixed the same day. A per-request server-timing header was also removed. The superseded Feature-Policy header was replaced with Permissions-Policy on 2026-09-05 |
| 2026-09-08 | Authenticated review of file delivery and browser retention | Direct download of data exports and voice recordings, access with known file URLs across tenants and after membership removal, browser Back after sign-out | Three findings, each requiring a user who was already authorized and held a signed file URL, or a shared browser. An expired data export could still be downloaded from a retained URL without fresh authentication. A handler could download an original voice recording before its anonymization completed. After a session was revoked, the browser’s Back button could redisplay a report from its cache. Remediated 2026-09-10: file delivery now enforces the same expiry, re-authentication and processing rules as the page that links to it, and sensitive pages and private files are no longer stored by the browser. Cross-tenant and removed-member access was refused in every case tested |
| 2026-09-26 | Code-level review of session handling | Session identification and its behavior after a database restore | Sessions were identified by their database identifier. A restore rewinds identifiers, so a new sign-in could receive one that a surviving cookie still held and resume that user’s session. Remediated the same day: sessions are identified by a random token, and every existing session was ended |
| 2026-09-28 | Log review of the whistleblowing channel | Application-side logs written while a reporter uses the whistleblowing channel | Two components still wrote reporter IP addresses: the web server’s request log and the spam-protection warning. Both removed the same day. The TLS proxy’s own request log, which records the IP address of every request, is unchanged and described on Security#ip-addresses |
| 2026-10-16 | Code-level review against current Rails attack research | Upload processing, image decoding, signed-message handling, request logs, stored real-time messages, generated authorization code | Metadata stripping chose its method from the type the browser declared, so a photo uploaded as a generic file kept its location and device metadata. The image library’s SVG decoder, blocked at startup, was re-enabled for the whole process once a link-preview image had been generated. Signed and encrypted messages still accepted a serialization format that turns a leaked application secret into code execution. Request logs recorded attachment file names and short-lived download tokens. Real-time notifications, which carry the report’s Case ID, were stored unencrypted for a day. The template for new authorization policies left out the organization filter; no existing policy was affected. All remediated the same day |
| 2026-10-16 | Production forensic check (CVE-2026-66066) | Read-only inspection of every file stored before the fix for crafted image headers, images whose pixels decode as server files, and leftover identifying metadata | No evidence of exploitation in retained data, and no report image still carrying identifying metadata. Files that could have been uploaded through the exposed direct-upload path, open from 2026-04-13 to 2026-05-12, were purged by the daily cleanup of unattached files and can no longer be examined |
| 2026-10-17 | Production exposure review | Reverse-proxy request log, request size limits, container image vulnerability scanning | The reverse proxy logs every request path, and attachment download paths included the file name. Request bodies of up to 1 GB were buffered to disk before the application validated them. The container image was scanned for operating-system vulnerabilities monthly, against a 7-day commitment for critical fixes. Remediated the same day: neither step of an attachment download carries the file name in its path, request bodies are capped just above the largest legitimate report, and the image is scanned weekly |
| 2026-10-17 | Mutation testing of authorization rules | The access policies for reports, report documents and whistleblowing channels, each rule deliberately altered to confirm the test suite detects the change | Every alteration to those policies was detected. No authorization defect found |
| 2026-10-18 | Code-level review ahead of the independent assessment | Upload fields and file access, metadata removal, malware-scan gating, case roles, platform administration, authentication logging, error reporting, reporter passwords | Ten findings. Nine fixed the same day: an upload field accepted the identifier of a file already stored, so a user could attach a file they had not uploaded and then open it (file links now also expire after an hour); removing metadata from a PDF left the original author recoverable from an earlier revision of the file; the data export included files that had not passed the malware scan, and a file whose scan was never queued was served unscanned; a viewer assigned to a case could act on it; the platform admin panel did not require a second factor; one-time sign-in codes and SAML assertions reached the error-monitoring service; failed sign-ins, failed case lookups and rate-limit hits left no record; reporters chose their own six-digit passcode, so a common choice such as 123456 was accepted (new reports get a 16-digit password generated by the system; reports submitted earlier keep theirs, see Known open findings). A read-only check of production found no stored report PDF and no viewer account, so neither of those two had affected a case. The remaining one is listed under known open findings |
Known open findings #
| Finding | Position |
|---|---|
| No web application firewall or CDN in front of the application origin | Deliberate. Direct application and file hosting is in the EU, while the email and telemetry chain may involve downstream processing outside the EEA. Network-level DDoS protection at the hosting provider plus application-layer rate limiting is the current trade-off. |
| Staff profile photos are stored with their original file metadata | Deliberate. Metadata removal protects reporters and their evidence. A profile photo is chosen and uploaded by the staff member it shows. |
| Reports submitted before 18 October 2026 keep the 6-digit password chosen when they were submitted, by the reporter or, for a report staff logged, by the handler | Accepted. These passwords still work and are not replaced. Sign-in allows 10 password attempts per Case ID per 10 minutes, from any IP. |
What this does not establish #
- The operator chose the scope, ran the tests, and reported the results. Nothing here has been independently verified.
- A pass with no findings is evidence about the cases tested, not about the cases that were not tested.
- Control A.5.35 of the ISO/IEC 27001:2022 self-assessment — independent review of information security — remains open for this reason. It is the only Annex A control on that page recorded as in treatment, and the same limitation holds Clause 9.2 (internal audit) at partial; see the internal audit record.
Last updated: