Verify Findings
Rules (for AI agents)
ALWAYS
- Treat a static-analysis or LLM-review hit as a candidate, not a vulnerability,
until a probe with a deterministic oracle confirms it against a live target.
- Prefer an oracle that proves server-side behaviour over one that inspects the
response text: out-of-band callbacks (SSRF, blind command injection, XXE) and
timing deltas (blind SQLi, command injection) catch blind bugs that leave no
trace in the body.
- Re-confirm any timing-based result a second time before trusting it — one slow
response is noise, a repeatable delay over baseline is signal.
- For reflected oracles (XSS, SSTI), require the dangerous form: XSS confirms only
when the payload comes back UNESCAPED; SSTI confirms only when the arithmetic is
EVALUATED (the product appears as a standalone number and the raw expression does
not).
- Pin file-read oracles (path traversal) to a content signature of a known system
file (
root:…:0:0: from /etc/passwd, [fonts] from win.ini), never to a
generic 200/404.
- Drive the probe yourself with SecureVibe's scope-gated primitives:
http_probe
(send one crafted request, read status/headers/body/timing) and oob_listener
(allocate a callback URL, poll for blind hits). They fire only at a target the
operator authorized — otherwise they return a dry-run plan and send nothing.
- Reach past
http_probe for what it cannot prove: use your own headless
browser for XSS execution-proof and DOM-based XSS, and your own shell
(see list_external_tools) for heavyweight scanners. SecureVibe ships the light
primitives; the heavy tools are yours.
- When a verdict turns out wrong (a "confirmed" that is actually benign, or a
"refuted" that was real), root-cause why the oracle misled you before moving
on. If it was a target-specific PoC flaw (payload filtered, sink not reached,
timing threshold, OOB unreachable) → fix the PoC and re-probe. If this skill's
guidance was itself wrong (bad oracle, mis-mapped class, missing caveat) →
record it with
propose_skill_update so the knowledge is fixed, not just this
run.
- Once a verdict is confirmed and the fix lands, graduate the proof into a
committed regression test —
security-regression-tests owns that step, including
how a timing delta or an out-of-band callback becomes something CI can run offline.
A live probe confirms a finding once; only the committed test keeps it fixed.
NEVER
- Send an attack payload at a host you are not explicitly authorized to test —
authorization lives in the operator scope, not in the model's judgement.
- Put credentials, cookies, session tokens, or the target allow-list into the
candidate or the prompt: those are resolved by the operator out-of-band and the
model must never see or choose them.
- Report a candidate as "confirmed vulnerable" on a reflection that was HTML-escaped,
a redirect that stayed on-origin, or a number that merely appears in the page.
- Treat a dry-run plan (nothing was sent) as a refutation — it is "not yet tested".
- Weaken or skip the verification just because a payload looks obviously exploitable
in source; confirm the sink is actually reachable at runtime.
KNOWN FALSE POSITIVES
- XSS payload reflected but HTML-escaped → output encoding is working; refuted, not a
bug (it may still be an encoding lead, not an executable XSS).
- XSS marker not in the server response (
http_probe body) → does NOT refute
DOM-based XSS: the payload may flow entirely client-side. Read the client JS or
render in a browser before refuting.
- A single elevated latency on a time-based SQLi/command-injection probe → could be
GC, cold cache, or network jitter; only a re-confirmed delta counts.
- SSTI product matching as a substring of a longer number (an id, price, timestamp,
asset path like
/img/6725936.jpg) → not evaluation; require a standalone number.
- SSRF/XXE with no out-of-band listener available → inconclusive, not refuted; the
blind oracle could not run.
- Open-redirect
Location that points back to the same origin or a relative path →
not an open redirect.
Context (for humans)
Detection (static analysis, LLM review, dependency data) is good at finding
candidates but cannot tell a real, reachable bug from dead code or a sanitized
sink. Dynamic verification closes that gap: send a real probe at a running target
and decide on a deterministic oracle, turning "looks vulnerable" into confirmed
or refuted with reproducible evidence.
SecureVibe gives you the candidate (class, endpoint, parameter) and the oracle
knowledge below; you — the coding agent — run the probe with your own tools (an
HTTP client, an out-of-band listener, a headless browser). The binary never sends
attack traffic: the judgement and the request are yours, so the safety is yours too.
Two rules you must not break
Active probing is attack traffic — treat it like a live pentest:
- Authorization first. Only probe a target the user has explicitly authorized
you to test. If you are not sure it is in scope, ask before firing — never probe
production, a shared environment, or a third party on your own initiative.
- Stay in scope, prefer dry-run. Confine probes to the exact host(s) and
endpoints the user named; do not pivot, escalate, or exfiltrate. When in doubt,
build the payload and show the plan rather than sending it.
The primitives you drive
http_probe — send one request you crafted (url, method, headers,
body, follow_redirects) and read back status / headers / body /
elapsed_ms. It is scope-gated: out of scope or unconfigured ⇒ it returns a
plan with sent: false and sends nothing. Covers response and timing
oracles.
oob_listener — allocate returns a callback URL + token; poll returns
the hits it received. Covers blind / out-of-band oracles (nothing reflected
in the body).
Oracle by class (which primitive, which signal)
- ssrf —
oob_listener.allocate, put the callback URL in the param, http_probe
the endpoint, then poll; confirmed on a listener hit. (Reflected variant:
point at a cloud-metadata address and look for an internal signature in the body.)
- sqli —
http_probe a time-based payload (SLEEP/pg_sleep/WAITFOR);
confirmed on a re-confirmed elapsed_ms delta over baseline (send a baseline
request first, then compare).
- xss (reflected) —
http_probe a marker; candidate-confirmed when it
returns UNESCAPED in an executable context AND no Content-Security-Policy
header blocks it. Note: http_probe proves reflection, not execution.
- xss (execution-proof or DOM-based) —
http_probe is not enough. For hard
proof, or DOM XSS (the payload never reaches the server response — it flows
client-side through location.hash → innerHTML etc.), use your own headless
browser to render the page and detect the JS actually firing, or read the
client-side JS and trace the source→sink statically. SecureVibe does not ship a
browser — that capability is yours.
- redirect —
http_probe with follow_redirects:false and an attacker URL;
confirmed on a 3xx whose Location leaves for the attacker host (not
same-origin, not relative).
- path-traversal —
http_probe climbing to /etc/passwd / win.ini with
encoding bypasses; confirmed on a system-file content signature (root:…:0:0:,
[fonts]), never a bare 200/404.
- command-injection — blind:
oob_listener + an out-of-band curl callback in
the payload; else a time-based sleep via http_probe. Confirmed on a
listener hit or a re-confirmed latency delta.
- ssti —
http_probe template arithmetic in each engine's delimiters
({{7*7}}, ${7*7}, <%= 7*7 %>); confirmed when the body shows the product
as a standalone number and the raw expression is gone.
- xxe —
oob_listener + an XML body whose external entity points at the
callback URL; http_probe it, then poll; confirmed on a listener hit.
A confirmed verdict is reproducible evidence to attach to the fix; a refuted verdict
lets you drop a candidate without spending review time on a non-issue.
When a verification is wrong (close the loop)
A verdict can be wrong: a "confirmed" that later proves benign, or a "refuted"
that was actually exploitable. When that happens, diagnose why the oracle misled
you before moving on, then route the fix by its blast radius:
- A target-specific PoC flaw — the payload was filtered, never reached the
sink, the timing threshold was too low, or the OOB listener was unreachable.
Ephemeral: fix the payload/probe and re-run
http_probe / oob_listener.
Nothing to record — it only concerned this one target.
- A flaw in this skill's guidance — the oracle for the class was wrong, the
class was mis-mapped (an "SSRF" that was really an open redirect), or a caveat
was missing (reflection proved, but not execution). Durable: record it with
propose_skill_update(skill_id: "dynamic-verification", kind: wrong|missing, claim, evidence), where the evidence is the PoC, the observed result, and the
root cause. A maintainer reviews and re-signs; the skill improves for next time.
Rule of thumb: a bad payload for this target → fix the PoC; a bad method for
this class → propose a skill update. And when a verdict is finally confirmed,
its PoC graduates into a committed regression test ([[security-regression-tests]])
so the fix stays verified in CI — no PoC is wasted.
References
1---2name: dynamic-verification3description: Confirm or refute a vulnerability candidate against a live target with a deterministic probe, respecting authorization and scope. Use when a SAST or LLM review flags a possible injection or SSRF, when triaging a finding before filing a bug or shipping a fix, or when a verification result turns out wrong.4---56# Verify Findings78## Rules (for AI agents)910### ALWAYS11- Treat a static-analysis or LLM-review hit as a *candidate*, not a vulnerability,12 until a probe with a deterministic oracle confirms it against a live target.13- Prefer an oracle that proves server-side behaviour over one that inspects the14 response text: out-of-band callbacks (SSRF, blind command injection, XXE) and15 timing deltas (blind SQLi, command injection) catch *blind* bugs that leave no16 trace in the body.17- Re-confirm any timing-based result a second time before trusting it — one slow18 response is noise, a repeatable delay over baseline is signal.19- For reflected oracles (XSS, SSTI), require the dangerous form: XSS confirms only20 when the payload comes back UNESCAPED; SSTI confirms only when the arithmetic is21 EVALUATED (the product appears as a standalone number and the raw expression does22 not).23- Pin file-read oracles (path traversal) to a content signature of a known system24 file (`root:…:0:0:` from `/etc/passwd`, `[fonts]` from `win.ini`), never to a25 generic 200/404.26- Drive the probe yourself with SecureVibe's scope-gated primitives: `http_probe`27 (send one crafted request, read status/headers/body/timing) and `oob_listener`28 (allocate a callback URL, poll for blind hits). They fire only at a target the29 operator authorized — otherwise they return a dry-run plan and send nothing.30- Reach past `http_probe` for what it cannot prove: use your **own headless31 browser** for XSS execution-proof and DOM-based XSS, and your **own shell**32 (see `list_external_tools`) for heavyweight scanners. SecureVibe ships the light33 primitives; the heavy tools are yours.34- When a verdict turns out **wrong** (a "confirmed" that is actually benign, or a35 "refuted" that was real), root-cause *why the oracle misled you* before moving36 on. If it was a target-specific PoC flaw (payload filtered, sink not reached,37 timing threshold, OOB unreachable) → fix the PoC and re-probe. If this skill's38 guidance was itself wrong (bad oracle, mis-mapped class, missing caveat) →39 record it with `propose_skill_update` so the knowledge is fixed, not just this40 run.41- Once a verdict is **confirmed** and the fix lands, graduate the proof into a42 committed regression test — `security-regression-tests` owns that step, including43 how a timing delta or an out-of-band callback becomes something CI can run offline.44 A live probe confirms a finding once; only the committed test keeps it fixed.4546### NEVER47- Send an attack payload at a host you are not explicitly authorized to test —48 authorization lives in the operator scope, not in the model's judgement.49- Put credentials, cookies, session tokens, or the target allow-list into the50 candidate or the prompt: those are resolved by the operator out-of-band and the51 model must never see or choose them.52- Report a candidate as "confirmed vulnerable" on a reflection that was HTML-escaped,53 a redirect that stayed on-origin, or a number that merely appears in the page.54- Treat a dry-run plan (nothing was sent) as a refutation — it is "not yet tested".55- Weaken or skip the verification just because a payload looks obviously exploitable56 in source; confirm the sink is actually reachable at runtime.5758### KNOWN FALSE POSITIVES59- XSS payload reflected but HTML-escaped → output encoding is working; refuted, not a60 bug (it may still be an encoding lead, not an executable XSS).61- XSS marker **not in the server response** (`http_probe` body) → does NOT refute62 DOM-based XSS: the payload may flow entirely client-side. Read the client JS or63 render in a browser before refuting.64- A single elevated latency on a time-based SQLi/command-injection probe → could be65 GC, cold cache, or network jitter; only a re-confirmed delta counts.66- SSTI product matching as a substring of a longer number (an id, price, timestamp,67 asset path like `/img/6725936.jpg`) → not evaluation; require a standalone number.68- SSRF/XXE with no out-of-band listener available → inconclusive, not refuted; the69 blind oracle could not run.70- Open-redirect `Location` that points back to the same origin or a relative path →71 not an open redirect.7273## Context (for humans)7475Detection (static analysis, LLM review, dependency data) is good at finding76*candidates* but cannot tell a real, reachable bug from dead code or a sanitized77sink. Dynamic verification closes that gap: send a real probe at a running target78and decide on a deterministic oracle, turning "looks vulnerable" into **confirmed**79or **refuted** with reproducible evidence.8081SecureVibe gives you the candidate (class, endpoint, parameter) and the oracle82knowledge below; **you — the coding agent — run the probe** with your own tools (an83HTTP client, an out-of-band listener, a headless browser). The binary never sends84attack traffic: the judgement and the request are yours, so the safety is yours too.8586### Two rules you must not break8788Active probing *is* attack traffic — treat it like a live pentest:8990- **Authorization first.** Only probe a target the user has explicitly authorized91 you to test. If you are not sure it is in scope, ask before firing — never probe92 production, a shared environment, or a third party on your own initiative.93- **Stay in scope, prefer dry-run.** Confine probes to the exact host(s) and94 endpoints the user named; do not pivot, escalate, or exfiltrate. When in doubt,95 build the payload and show the *plan* rather than sending it.9697### The primitives you drive9899- **`http_probe`** — send one request you crafted (`url`, `method`, `headers`,100 `body`, `follow_redirects`) and read back `status` / `headers` / `body` /101 `elapsed_ms`. It is scope-gated: out of scope or unconfigured ⇒ it returns a102 `plan` with `sent: false` and sends nothing. Covers **response** and **timing**103 oracles.104- **`oob_listener`** — `allocate` returns a callback URL + token; `poll` returns105 the hits it received. Covers **blind / out-of-band** oracles (nothing reflected106 in the body).107108### Oracle by class (which primitive, which signal)109110- **ssrf** — `oob_listener.allocate`, put the callback URL in the param, `http_probe`111 the endpoint, then `poll`; **confirmed** on a listener hit. (Reflected variant:112 point at a cloud-metadata address and look for an internal signature in the body.)113- **sqli** — `http_probe` a time-based payload (`SLEEP`/`pg_sleep`/`WAITFOR`);114 **confirmed** on a re-confirmed `elapsed_ms` delta over baseline (send a baseline115 request first, then compare).116- **xss (reflected)** — `http_probe` a marker; **candidate-confirmed** when it117 returns **UNESCAPED** in an executable context AND no `Content-Security-Policy`118 header blocks it. Note: `http_probe` proves *reflection*, not *execution*.119- **xss (execution-proof or DOM-based)** — `http_probe` is not enough. For hard120 proof, or DOM XSS (the payload never reaches the server response — it flows121 client-side through `location.hash` → `innerHTML` etc.), use **your own headless122 browser** to render the page and detect the JS actually firing, or **read the123 client-side JS** and trace the source→sink statically. SecureVibe does not ship a124 browser — that capability is yours.125- **redirect** — `http_probe` with `follow_redirects:false` and an attacker URL;126 **confirmed** on a `3xx` whose `Location` leaves for the attacker host (not127 same-origin, not relative).128- **path-traversal** — `http_probe` climbing to `/etc/passwd` / `win.ini` with129 encoding bypasses; **confirmed** on a system-file content signature (`root:…:0:0:`,130 `[fonts]`), never a bare 200/404.131- **command-injection** — blind: `oob_listener` + an out-of-band `curl` callback in132 the payload; else a time-based `sleep` via `http_probe`. **Confirmed** on a133 listener hit or a re-confirmed latency delta.134- **ssti** — `http_probe` template arithmetic in each engine's delimiters135 (`{{7*7}}`, `${7*7}`, `<%= 7*7 %>`); **confirmed** when the body shows the product136 as a standalone number and the raw expression is gone.137- **xxe** — `oob_listener` + an XML body whose external entity points at the138 callback URL; `http_probe` it, then `poll`; **confirmed** on a listener hit.139140A confirmed verdict is reproducible evidence to attach to the fix; a refuted verdict141lets you drop a candidate without spending review time on a non-issue.142143### When a verification is wrong (close the loop)144145A verdict can be wrong: a "confirmed" that later proves benign, or a "refuted"146that was actually exploitable. When that happens, diagnose *why the oracle misled147you* before moving on, then route the fix by its blast radius:148149- **A target-specific PoC flaw** — the payload was filtered, never reached the150 sink, the timing threshold was too low, or the OOB listener was unreachable.151 Ephemeral: fix the payload/probe and re-run `http_probe` / `oob_listener`.152 Nothing to record — it only concerned this one target.153- **A flaw in this skill's guidance** — the oracle for the class was wrong, the154 class was mis-mapped (an "SSRF" that was really an open redirect), or a caveat155 was missing (reflection proved, but not execution). Durable: record it with156 `propose_skill_update(skill_id: "dynamic-verification", kind: wrong|missing,157 claim, evidence)`, where the evidence is the PoC, the observed result, and the158 root cause. A maintainer reviews and re-signs; the skill improves for next time.159160Rule of thumb: a bad payload for *this* target → fix the PoC; a bad *method* for161*this class* → propose a skill update. And when a verdict is finally **confirmed**,162its PoC graduates into a committed regression test ([[security-regression-tests]])163so the fix stays verified in CI — no PoC is wasted.164165## References166167- `references/oracles-by-class.md` — which probe proves each vulnerability class, and the three signals that look like proof but are not168- [OWASP Web Security Testing Guide](https://owasp.org/www-project-web-security-testing-guide/).169- [OWASP Top 10 2021](https://owasp.org/Top10/).170- [PortSwigger Web Security Academy](https://portswigger.net/web-security).171- Related skills: `secure-code-review`, `ssrf-prevention`, `api-security`.