How it works
A white-box pentest runs in two linked stages. First the agents read your source code and build a model of it, producing a set of candidate vulnerabilities with the code evidence that explains them. Then the agents probe your live application and confirm which candidates an attacker can actually reach and exploit.
Each stage is itself a multi-agent workflow, and each stage builds on the previous one. The whole run works without human intervention: you start it, the agents do the work, and you review the results when they are ready.
Stage one: static source analysis
The agents acquire your source and build a structural model of the codebase: entry points, frameworks, data flows, and trust boundaries. This model enables taint analysis, call graph traversal, and cross-file data flow tracking.
The analysis follows data flows from source to sink, noting where user input enters the system, where the system sanitizes it (or fails to), and where it reaches a sensitive operation. The agents map authentication checks, authorization boundaries, and configuration to understand where the application enforces security. For each candidate vulnerability, an agent traces the full path from source to sink, checks for sanitization or validation that would block exploitation, and records the code evidence: the vulnerable locations, the taint flow, and a proof-of-concept description.
This stage is what the static source analysis can see that a purely black-box run cannot: latent vulnerabilities and taint flows, unsafe deserialization in library code, weak cryptography, and logic that never surfaces through HTTP. The output is a set of candidates to validate, not confirmed findings.
Stage two: live validation
The agents now treat the running application as a black box. They crawl it, following links and submitting forms to record each endpoint and parameter, respecting your excluded paths and rate limits. They analyze the crawled surface to identify high-value targets: authenticated endpoints, admin interfaces, routes that accept user input, and flows that handle sensitive data.
For each candidate the source analysis raised, an agent crafts a payload, sends the request, and inspects the response. If the response suggests the candidate is exploitable, the agent refines the payload to confirm exploitation and capture proof, iterating until it either confirms the issue or rules it out. Candidates the runtime stage cannot confirm do not become findings.
Sync and report
Version 1 syncs each confirmed candidate straight to the findings list and report. It intentionally skips deduplication and triage. The live check still controls whether a candidate becomes a finding, but no later agent merges related findings or assigns systemic scope.
This means the findings are localized, un-deduplicated, and un-triaged. If the same weakness appears at 12 sites, you receive 12 separate findings rather than one systemic finding with 12 instances. Retaining deduplication while keeping a clear live disposition for every candidate is planned follow-up work.
Live checks run one candidate at a time to keep target load bounded. That is safe for small runs but can be slow and costly when a codebase yields 100 or more candidates. A planned concurrency update will add bounded batches, target-aware limits, and enforced per-run cost and request budgets.
Static route-to-runtime-sink links are separate planned work. AISafe will add them only with a real data producer, an activation counter, and benchmark proof that the links are present often enough to help.
The live phase also keeps three outcomes distinct: a supported assertion failed against a resolved transaction, the leaf produced no result, or the leaf failed. We plan to apply the same Project-row completion rule to code audit so an empty result, a clean audit, and a failed leaf do not look the same.
Why the two sources together
Each stage covers a weakness of the other.
- A source-only audit finds a latent issue but cannot prove an attacker can reach it, because the application never runs.
- A black-box test sees only what surfaces over HTTP, so it cannot reason about the code behind the request.
Reading the code gives the runtime stage a head start: it knows where to probe instead of exploring blind. Probing the live target gives the source findings proof of exploitability. The result is findings that say both where the bug lives in the code and exactly how to trigger it.
Before you start
You need two kinds of input: the source to read, and a live target to validate against. See Prepare your target.