Skip to main content

A problem is a dot. An attacker draws the line.

Vulkro Red is the red team on the same engine as the reviews. It takes what Vulkro and Vulkro for Salesforce found and works out which problems chain into a break-in, stage by stage, reading only the code on the disk. It never sends a request, never touches a live system, and every stage cites a file and a line.

vulkro-red attack . --reportoffline
chain 01Unauthenticated invoice read reaches customer recordsCRIT6 stages
  1. 01recon214 routes inventoried from the router table, 18 with no guardsrc/routes/index.ts:31VULK-0311
  2. 02initial accessInvoice read route is reachable without a sessionsrc/routes/invoice.ts:47VULK-1042CWE-306
  3. 03protection bypassrequireAuth is mounted after the invoice router, so it never runssrc/app.ts:88VULK-1180CWE-284
  4. 04injectionPath parameter reaches the query builder without a bound parametersrc/db/invoice.repo.ts:126VULK-2207CWE-89
  5. 05broken accessLookup carries no owner or tenant predicate, so any id resolvessrc/services/invoice.service.ts:212VULK-1305CWE-639
  6. 06exfiltrationSerializer returns 12 customer fields, including billing addresssrc/serializers/invoice.ts:64VULK-1544CWE-200CRIT
chain trust scoreat or above the reporting gate (70)78/100
  • +30route resolved from the framework router table
  • +24guard absent on this path (checked at src/app.ts:88)
  • +18sink reaches a column set tagged as customer data
  • +12every stage cites a parsed file and line
  • -6no runtime evidence: nothing was executed

noteStatic analysis. No request was sent and no exploit was executed.

One chain as the report draws it: the door, the path, the damage, with the file and line at every stage.

Severity is per problem. Risk is per path.

A list of problems tells you what is wrong. An ordered chain tells you what happens next.

Severity is per problem

A review ranks each problem on its own: how bad it would be if it is real. That is the right question for fixing, and the wrong one for deciding what an attacker does next.

Risk is per path

A medium problem that opens the door for a high one is worse than either alone. Vulkro Red orders what the reviews found into the route an attacker would take, stage by stage.

Every stage is cited

Each stage names the file and the line the engine actually read, or it is not printed. There is no stage that exists only in a model's imagination.

How a chain is built, and where it stops.

Corroboration, not labels. A chain is printed only when the review's own map backs every stage, and it is never called confirmed, because nothing was run.

One signal is not a chain

A high severity is one signal. A chain needs corroboration: an entry point that reaches the code, a path the data can travel, and a place it does damage, each backed by the map the review built.

There is no proven-exploit tier

Nothing is executed, so nothing can be confirmed. The ceiling is a strongly grounded static path, and the report says so on every chain rather than dressing a guess as a result.

The model narrates, the engine decides

A local model on your machine writes the story of a chain at temperature zero. Every claim it makes is checked against the call graph, the endpoint inventory and reachability before it can appear.

Supply chain, Salesforce, and nothing to authorise.

The same reading covers the code you wrote, the code you installed, and the org you deployed into.

Supply chain

Code you never read runs on every machine that installs your product. Hostile package families, hijacked releases and install-time scripts are placed on the chain where they actually enter.

Salesforce

Two half-problems make one path: an Apex query that trusts its caller, and an org setting that lets a guest be that caller. Vulkro Red joins the source review to the live-org posture.

Nothing to authorise

Nothing is attacked. No request is sent, no server is touched, no exploit is run. There is no engagement letter to sign because there is no engagement, only a reading of the code on disk.

The limits, stated first.

The constraints get the same treatment as the results: named, with the reason, before you find them.

What a static red team cannot know, and why.
Not measuredWhat that meansWhy
Runtime behaviourNothing is executed. A defect that only appears while the process is running is out of scope.The scan reads source, configuration and lockfiles on your machine. It never runs your code and never reaches your infrastructure.
Business logicWhether a rule is the right rule is not checked. A price check that is wrong but well written reads as clean.There is no specification to compare the code against, so correctness of intent cannot be decided from the code alone.
Dynamic dispatchCalls resolved at runtime (reflection, string-keyed dispatch, eval) can break the call graph, so a real path can be missed.Static resolution has no value to follow. Where this happens the finding is down-ranked rather than dropped.
Exploitability in your deploymentA finding says a path exists in the code. It does not say an attacker can reach it as you have things deployed.Network position, whatever sits in front of the route, and feature flags are not visible to a static read.
Languages outside the supported setA file in an unsupported language is counted in the inventory and skipped, not analysed.No grammar is loaded for it, so there is no parse tree to walk.
Dependency ecosystems that are not parsedA dependency declared in a manifest format the scanner does not read is absent from the SBOM and from CVE matching.Only the manifest and lockfile formats listed in the docs are parsed. Absence is reported as unread, not as clean.
Reachability without a symbol mapWhere an advisory declares no vulnerable symbols, no reachability claim is made in either direction.There is nothing to look for in the call graph, so the finding keeps the severity it was matched at.
Infrastructure outside the repositoryCloud account posture, running containers and live network rules are not read.The scan is local and offline. It sees the repository and the artifacts in it, and nothing else.
Generated and vendored codeBundled or minified output is parsed but rarely useful, and vendored directories are skipped by default.A finding there points at a build artifact rather than at a line anyone edits.
Source: /docs/known-limits. Maintained beside the detector docs and updated when a limit changes.