Verify vulnerability issues
This repo's monitoring action files a GitHub issue for every commit it thinks is a
security patch. Many are genuine; some are false positives (routine dependency
bumps, feature commits, build-tooling changes, AI-misclassified commits). This
skill verifies the unverified ones, comments, and labels each.
Scope & disposition
Target: open issues authored by github-actions[bot] that carry none
of the verdict labels — true-positive, false-positive, or dependency.
An issue carrying any of those, or one already closed (e.g. a dependency
bump closed in an earlier run, or a duplicate), has already been dispositioned
— skip it. prepare.mjs applies exactly this filter.
For every targeted issue: post one analysis comment, then apply the disposition:
| Finding |
Action |
| Genuine security fix |
comment + add true-positive label |
| False positive |
comment + add false-positive label |
| Pure dependency bump |
comment + add dependency label + close (not planned) |
Pure dependency bump = the commit's entire diff is package manifests,
lockfiles, or version changelogs — no hand-written fix code. Close it regardless
of whether the upstream advisory is real; dependency bumps are out of scope for
this tracker.
- Exception — keep it open: if the commit also carries actual
vulnerability-fix code (e.g. it backports/cherry-picks specific fix code into
vendored sources, not merely a version number/lockfile entry), it is a real
finding — treat it as Verified (
true-positive), do not close it.
Duplicate issues: the monitor sometimes files more than one issue for the
same commit. prepare.mjs detects these (writes /tmp/vsa/duplicates.json).
Keep and verify the canonical one (lowest issue number = first filed); the
rest are duplicates — close them as duplicates, or delete with gh issue delete only after the user confirms, since deletion is permanent.
Labels: add the verdict label. Never remove a label someone else applied
— if an issue carries a conflicting one, stop and surface it. You may correct
a verdict this skill applied earlier (e.g. true-positive → false-positive)
when re-analysis warrants: remove the stale label, add the right one, and post
a correction comment explaining why.
Relay a final summary (counts per repo, false positives, issues closed as
dependency bumps, duplicates found).
Prerequisites
gh must be authenticated. gh auth status reporting "not logged in" inside the
sandbox is normal for git operations, but gh api/gh issue calls still need a
real token. If gh calls fail with HTTP 401/Bad credentials, ask the user
to run ! gh auth login in the prompt (the dummy-GH_TOKEN trick does not work —
the proxy rejects it).
Ensure the dependency label exists (create once if missing):
gh label create dependency --repo <owner/repo> \
--description "Issue is only a dependency/version bump — out of scope, ignored" \
--color ededed
Procedure
1. Fetch & prepare
node .claude/skills/verify-vuln-issues/prepare.mjs
It lists issues, filters to unverified ones, parses each body for its repo + full
commit SHA (via scripts/lib/parser.mjs), downloads every commit diff and
metadata, and writes /tmp/vsa/:
todo.json — [{number, state, repository, commitSha, ...}]
ctx/<n>.txt — per-issue: the AI claim + commit message + file list + diff
(lockfiles trimmed, huge files truncated)
duplicates.json — groups of issues sharing one commit SHA (see "Duplicate
issues" above)
results.json — starts {}; record verdicts here as you go.
The --- FILES CHANGED --- list in each context file is what you use to spot a
pure dependency bump (only package.json / *.lock / go.mod / go.sum /
CHANGELOG* / doc/changelogs/* / toolchain files).
2. Analyze, in batches
Read ctx/<n>.txt files (~10–15 per turn; read large ones individually). For each
issue decide the finding using the rubric below, and record into results.json
(verified / false-positive / dependency) so progress survives compaction.
3. Comment + label (+ close)
Write each comment to /tmp/vsa/comments/<n>.md, then per issue:
gh issue comment <n> --repo <owner/repo> --body-file /tmp/vsa/comments/<n>.md
# verified:
gh issue edit <n> --repo <owner/repo> --add-label true-positive
# false positive:
gh issue edit <n> --repo <owner/repo> --add-label false-positive
# pure dependency bump:
gh issue edit <n> --repo <owner/repo> --add-label dependency
gh issue close <n> --repo <owner/repo> --reason "not planned"
Loop over a batch; report any failures.
Verdict rubric
The commit diff is ground truth — the issue body is an LLM guess and is often
wrong about the mechanism, severity, or even the vuln class.
Verified — a genuine security fix (true-positive)
- Commit message cites a CVE-ID, GHSA advisory, HackerOne report, an internal
vuln tracker (
GL-Vuln:), or a [security] tag.
- Hand-written code change that removes a real, demonstrably exploitable flaw
(memory safety, auth/authz check added, injection/CRLF/XSS sink fixed, DoS
guard), ideally with a regression test. A guard that closes a demonstrated
bypass still counts even when low-severity — but a change that only addresses a
theoretical concern does not; see "Preventive hardening" under False positive.
- A vendored-dependency update that backports/cherry-picks specific fix code
for a vulnerability (not just a version number) — even though it touches
deps/, it carries the actual patch, so keep it open.
- Still verify even if the issue mislabeled the class — say so and correct it
(e.g. "this is request smuggling, not SSRF"). Note overstated severity.
Pure dependency bump (dependency, then close)
- The whole diff is package manifests / lockfiles / version changelogs — no fix
code in the project itself. The fix, if any, lives entirely upstream.
- Applies whether the issue is otherwise "verified" (real upstream advisory) or a
false positive — either way it is dependency noise, label
dependency + close.
- Includes vendored-dependency version bumps (re-vendoring a bundled dep to a
new release). But see the Verified exception: a vendored security backport
that patches specific code stays open.
False positive — not a substantiated vulnerability (false-positive)
- Build/dev tooling: indirect or dev dependency edits under
tools/, hack/,
devDependencies, or a maintainer-only script — no runtime/attacker surface.
- Feature, not a fix: the "vulnerable" code and its validation/guard are
introduced in the same commit (no prior released version was vulnerable); or
the commit just wires up / enables an in-development feature.
- Mischaracterized: the issue's described mechanism contradicts the diff
(e.g. claims "no cert validation" but pre-patch used standard TLS; claims
prototype pollution but
__proto__ was already handled).
- Correctness bug with no attacker: internal concurrency/overflow/data-
integrity bugs (build engines, ORM dedup, migration races) with no security
boundary or attacker-controlled input.
- Preventive / defense-in-depth hardening: the change hardens against a
theoretical or downstream weakness with no demonstrated exploit in a
released version — e.g. giving an object a null prototype to address
prototype-pollution concerns, or a guard the commit frames as precautionary.
Tell-tale: the commit message hedges ("harden", "defense-in-depth",
"concerns") and cites no CVE / advisory / PoC showing the prior version was
actually exploitable. (Contrast: a guard that closes a demonstrated bypass is
Verified, even if low-severity.)
- Docs-only change — unless it reflects a real default-hardening shipped
elsewhere.
When unsure, state the caveat explicitly (dependency bump → flaw is upstream;
dev-only reach; severity overstated) rather than forcing a binary call.
Comment format
Start with a bold verdict line, reference the short commit SHA, reason from the
diff, then a one-line Verdict:. Keep it substantive but tight:
## Verification analysis — **Verified** (genuine <class> fix)
Reviewed commit `<sha>`. <what the diff actually does and why it is/ isn't a
real fix; cite advisory refs, tests, caveats>.
Verdict: verified — <one line>.
If an issue already has a CVE in its commit message but no cve: label, mention
it (it would graduate the finding from "verified" to "confirmed").
Source: spaceraccoon/vulnerability-spoiler-alert — distributed by TomeVault.
1---2name: verify-vuln-issues3description: Triage the repo's open "[Vulnerability]" GitHub issues — for every issue lacking a true-positive/false-positive label, fetch the referenced commit, judge whether it is a genuine security fix or a false positive, post an analysis comment, and apply the verdict label. Pure dependency bumps get a `dependency` label and are closed. Use when asked to "verify", "triage", or "review" the vulnerability issues / findings in the tracker. Use when this capability is needed.4---56# Verify vulnerability issues78This repo's monitoring action files a GitHub issue for every commit it thinks is a9security patch. Many are genuine; some are false positives (routine dependency10bumps, feature commits, build-tooling changes, AI-misclassified commits). This11skill verifies the unverified ones, comments, and labels each.1213## Scope & disposition1415- **Target:** **open** issues authored by `github-actions[bot]` that carry **none**16 of the verdict labels — `true-positive`, `false-positive`, or `dependency`.17 An issue carrying any of those, or one already **closed** (e.g. a dependency18 bump closed in an earlier run, or a duplicate), has already been dispositioned19 — skip it. `prepare.mjs` applies exactly this filter.20- For every targeted issue: post one analysis comment, then apply the disposition:2122 | Finding | Action |23 |---|---|24 | Genuine security fix | comment + add `true-positive` label |25 | False positive | comment + add `false-positive` label |26 | **Pure dependency bump** | comment + add `dependency` label + **close** (`not planned`) |2728- **Pure dependency bump** = the commit's entire diff is package manifests,29 lockfiles, or version changelogs — no hand-written fix code. Close it regardless30 of whether the upstream advisory is real; dependency bumps are out of scope for31 this tracker.32 - **Exception — keep it open:** if the commit *also* carries actual33 vulnerability-fix code (e.g. it backports/cherry-picks specific fix code into34 vendored sources, not merely a version number/lockfile entry), it is a real35 finding — treat it as Verified (`true-positive`), do **not** close it.36- **Duplicate issues:** the monitor sometimes files more than one issue for the37 *same commit*. `prepare.mjs` detects these (writes `/tmp/vsa/duplicates.json`).38 Keep and verify the canonical one (lowest issue number = first filed); the39 rest are duplicates — close them as duplicates, or delete with `gh issue40 delete` **only after the user confirms**, since deletion is permanent.41- Labels: **add** the verdict label. Never remove a label someone *else* applied42 — if an issue carries a conflicting one, stop and surface it. You *may* correct43 a verdict this skill applied earlier (e.g. `true-positive` → `false-positive`)44 when re-analysis warrants: remove the stale label, add the right one, and post45 a correction comment explaining why.46- Relay a final summary (counts per repo, false positives, issues closed as47 dependency bumps, duplicates found).4849## Prerequisites5051`gh` must be authenticated. `gh auth status` reporting "not logged in" inside the52sandbox is normal for git operations, **but `gh api`/`gh issue` calls still need a53real token.** If `gh` calls fail with `HTTP 401`/`Bad credentials`, ask the user54to run `! gh auth login` in the prompt (the dummy-`GH_TOKEN` trick does not work —55the proxy rejects it).5657Ensure the `dependency` label exists (create once if missing):5859```bash60gh label create dependency --repo <owner/repo> \61 --description "Issue is only a dependency/version bump — out of scope, ignored" \62 --color ededed63```6465## Procedure6667### 1. Fetch & prepare6869```bash70node .claude/skills/verify-vuln-issues/prepare.mjs71```7273It lists issues, filters to unverified ones, parses each body for its repo + full74commit SHA (via `scripts/lib/parser.mjs`), downloads every commit diff and75metadata, and writes `/tmp/vsa/`:76- `todo.json` — `[{number, state, repository, commitSha, ...}]`77- `ctx/<n>.txt` — per-issue: the AI claim + commit message + **file list** + diff78 (lockfiles trimmed, huge files truncated)79- `duplicates.json` — groups of issues sharing one commit SHA (see "Duplicate80 issues" above)81- `results.json` — starts `{}`; record verdicts here as you go.8283The `--- FILES CHANGED ---` list in each context file is what you use to spot a84pure dependency bump (only `package.json` / `*.lock` / `go.mod` / `go.sum` /85`CHANGELOG*` / `doc/changelogs/*` / toolchain files).8687### 2. Analyze, in batches8889Read `ctx/<n>.txt` files (~10–15 per turn; read large ones individually). For each90issue decide the finding using the rubric below, and record into `results.json`91(`verified` / `false-positive` / `dependency`) so progress survives compaction.9293### 3. Comment + label (+ close)9495Write each comment to `/tmp/vsa/comments/<n>.md`, then per issue:9697```bash98gh issue comment <n> --repo <owner/repo> --body-file /tmp/vsa/comments/<n>.md99# verified:100gh issue edit <n> --repo <owner/repo> --add-label true-positive101# false positive:102gh issue edit <n> --repo <owner/repo> --add-label false-positive103# pure dependency bump:104gh issue edit <n> --repo <owner/repo> --add-label dependency105gh issue close <n> --repo <owner/repo> --reason "not planned"106```107108Loop over a batch; report any failures.109110## Verdict rubric111112The commit diff is ground truth — the issue body is an LLM guess and is often113wrong about the mechanism, severity, or even the vuln class.114115### Verified — a genuine security fix (`true-positive`)116- Commit message cites a **CVE-ID**, GHSA advisory, HackerOne report, an internal117 vuln tracker (`GL-Vuln:`), or a `[security]` tag.118- Hand-written code change that removes a real, **demonstrably exploitable** flaw119 (memory safety, auth/authz check added, injection/CRLF/XSS sink fixed, DoS120 guard), ideally with a regression test. A guard that closes a *demonstrated*121 bypass still counts even when low-severity — but a change that only addresses a122 theoretical concern does not; see "Preventive hardening" under False positive.123- A vendored-dependency update that **backports/cherry-picks specific fix code**124 for a vulnerability (not just a version number) — even though it touches125 `deps/`, it carries the actual patch, so keep it open.126- Still verify even if the issue mislabeled the class — say so and correct it127 (e.g. "this is request smuggling, not SSRF"). Note overstated severity.128129### Pure dependency bump (`dependency`, then close)130- The whole diff is package manifests / lockfiles / version changelogs — no fix131 code in the project itself. The fix, if any, lives entirely upstream.132- Applies whether the issue is otherwise "verified" (real upstream advisory) or a133 false positive — either way it is dependency noise, label `dependency` + close.134- Includes vendored-dependency *version* bumps (re-vendoring a bundled dep to a135 new release). But see the Verified exception: a vendored *security backport*136 that patches specific code stays open.137138### False positive — not a substantiated vulnerability (`false-positive`)139- **Build/dev tooling**: indirect or dev dependency edits under `tools/`, `hack/`,140 `devDependencies`, or a maintainer-only script — no runtime/attacker surface.141- **Feature, not a fix**: the "vulnerable" code and its validation/guard are142 introduced *in the same commit* (no prior released version was vulnerable); or143 the commit just wires up / enables an in-development feature.144- **Mischaracterized**: the issue's described mechanism contradicts the diff145 (e.g. claims "no cert validation" but pre-patch used standard TLS; claims146 prototype pollution but `__proto__` was already handled).147- **Correctness bug with no attacker**: internal concurrency/overflow/data-148 integrity bugs (build engines, ORM dedup, migration races) with no security149 boundary or attacker-controlled input.150- **Preventive / defense-in-depth hardening**: the change hardens against a151 *theoretical* or *downstream* weakness with no demonstrated exploit in a152 released version — e.g. giving an object a null prototype to address153 prototype-pollution *concerns*, or a guard the commit frames as precautionary.154 Tell-tale: the commit message hedges ("harden", "defense-in-depth",155 "concerns") and cites no CVE / advisory / PoC showing the prior version was156 actually exploitable. (Contrast: a guard that closes a *demonstrated* bypass is157 Verified, even if low-severity.)158- **Docs-only** change — unless it reflects a real default-hardening shipped159 elsewhere.160161When unsure, state the caveat explicitly (dependency bump → flaw is upstream;162dev-only reach; severity overstated) rather than forcing a binary call.163164## Comment format165166Start with a bold verdict line, reference the short commit SHA, reason from the167diff, then a one-line `Verdict:`. Keep it substantive but tight:168169```markdown170## Verification analysis — **Verified** (genuine <class> fix)171172Reviewed commit `<sha>`. <what the diff actually does and why it is/ isn't a173real fix; cite advisory refs, tests, caveats>.174175Verdict: verified — <one line>.176```177178If an issue already has a CVE in its commit message but no `cve:` label, mention179it (it would graduate the finding from "verified" to "confirmed").180181---182> Source: [spaceraccoon/vulnerability-spoiler-alert](https://github.com/spaceraccoon/vulnerability-spoiler-alert) — distributed by [TomeVault](https://tomevault.io).183<!-- tomevault:4.0:skill_md:2026-07-04 -->