vulkro probe
vulkro probe is a DAST tool. It sends real attack traffic to --base-url,
including payload injection (reflected XSS, SSTI, parameter pollution, JWT
alg=none) and, with --allow-mutations, state-mutating attacks (HTTP request
smuggling, prototype pollution, NoSQL $ne, race replay). It can alter data
and can trip rate limits or WAF blocks.
Run it ONLY against a non-production target you are authorized to test. Use
--safe for the read-only subset. --allow-mutations additionally requires
--i-understand-this-is-active (or an interactive confirmation), and is refused
outright when run non-interactively without it.
Active runtime confirmation of static findings. Hits each discovered endpoint of a running app to confirm auth bypass, CORS reflection, IDOR shape, SSTI, reflected XSS, JWT alg-confusion, prototype pollution, NoSQL operator injection, GraphQL schema leakage, HTTP request smuggling (CL.TE / TE.CL / TE.TE), DNS rebinding, race-replay, and parameter pollution.
13 probes ship with Vulkro.
Usage
vulkro probe . --base-url http://localhost:3000 [FLAGS]
Flags
| Flag | Description |
|---|---|
--base-url <URL> | Required. Base URL of the running app. |
--auth-header <HEADER> | Whole Authorization: Bearer ... header for IDOR-shape probing. |
--safe | Read-only subset: only the benign confirmation probes (auth-bypass, CORS, IDOR shape). Skips every payload-injection probe. Cannot be combined with --allow-mutations. |
--allow-mutations | Allow POST / PUT / PATCH / DELETE and the state-mutating attack classes. Off by default. Requires --i-understand-this-is-active (or interactive confirmation). |
--i-understand-this-is-active | Confirm you are authorized to send active, state-mutating traffic. Required (non-interactively) with --allow-mutations. |
--rate-limit-ms <MS> | Minimum delay between per-endpoint probe bursts. Default 100. Set 0 to disable. |
--format <FMT> | table, json, sarif, junit, etc. Same set as scan. |
Safety
vulkro probe is active DAST. Treat it as a penetration test: only run it
against a target you are authorized to test, and prefer a non-production
environment.
Authorization gate. A destructive run (--allow-mutations) does not start
until it is acknowledged:
- On a terminal, you are prompted to type
yesbefore any traffic is sent. - Non-interactively (CI, scripts), the run is refused with exit code
2unless you pass--i-understand-this-is-active. - The read-only default and
--saferuns do not require the acknowledgement, but you still need authorization to test the host.
--safe mode runs only the three benign confirmation probes (auth-bypass,
CORS reflection, IDOR shape) and sends no attack payloads. Recommended against
an unfamiliar target.
Built-in guard rails. Even with --allow-mutations, request bodies are
empty and destructive-looking paths (/delete, /drop, /purge, /wipe,
/destroy) are always skipped. Hard limits: 5 s per request, 60 s total
wall-clock. A default 100 ms rate-limit backoff (--rate-limit-ms) spaces out
per-endpoint bursts so the probe does not hammer the target.
Don't point this at production unless you own it. Don't point it at hosts you don't own, ever.
How it interacts with scan
probe reads endpoints from the same static extraction pass as scan, then
attempts to confirm each statically-flagged issue. A successful probe
upgrades the finding to:
confidence_reason = "runtime-confirmed via active probe"
This is the highest-confidence tier in the engine. Findings that the probe
disconfirms (e.g. an [Unprotected]-tagged endpoint that actually returns
401) are suppressed.
Probe catalogue
| # | Probe | What it checks |
|---|---|---|
| 1 | auth_bypass | Hit Unprotected endpoints with no auth header - 2xx/3xx confirms the gap |
| 2 | cors_reflection | Send Origin: https://attacker.example and detect reflected ACAO |
| 3 | idor_shape | With auth set, fetch with two synthetic IDs (1, 999999); both 200 with comparable bodies => no per-user scoping |
| 4 | reflected_xss | Reflect an unencoded SVG canary into HTML responses |
| 5 | ssti | Inject {{7*7}} and confirm template evaluation |
| 6 | param_pollution | Send duplicate query params and detect a behavioural delta |
| 7 | smuggling | Raw-TcpStream HTTP/1.1 client; TE-only, CL-only, dual-framing variants |
| 8 | proto_pollution | POST/PUT JSON with __proto__.polluted = true; follow-up GET checks for the polluted property |
| 9 | graphql_suggestions | Send a malformed query and detect schema names leaking via "Did you mean..." |
| 10 | nosql_injection | Login-shaped paths only; operator-injection payload ({"$ne":null}) returning 2xx where baseline returned 4xx |
| 11 | jwt_confusion | Forge alg=none from the user's token; finding fires when accepted |
| 12 | dns_rebinding | Informational unless VULKRO_DNS_REBIND_DOMAIN points at a controlled host |
| 13 | race_replay | Payment / state-mutating paths only; fire N parallel POSTs and flag if more than one returns 2xx |
Probes 7, 8, 10, 13 require --allow-mutations. --safe mode runs only probes
1-3 (auth-bypass, CORS, IDOR shape); probes 4-12 send attack payloads and are
skipped in safe mode.