free-pi-cli 0.4.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-xkn61g24.js → index-2s8fh2p0.js} +338 -403
- package/dist/index-n5qs9pq1.js +49 -0
- package/dist/index.js +4 -1
- package/dist/main-a786gwpy.js +24256 -0
- package/package.json +3 -2
- package/skills/security-audit/AI-AND-LLM.md +83 -0
- package/skills/security-audit/ATTACK-CLASSES.md +130 -0
- package/skills/security-audit/CLIENT-SIDE.md +83 -0
- package/skills/security-audit/CLOUD-AND-DEPLOYMENT.md +86 -0
- package/skills/security-audit/DATA-ISOLATION-AND-LIFECYCLE.md +84 -0
- package/skills/security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md +89 -0
- package/skills/security-audit/HUNTING.md +172 -0
- package/skills/security-audit/LICENSE +21 -0
- package/skills/security-audit/MEMORY-SAFETY-AND-BINARY.md +101 -0
- package/skills/security-audit/PROTOCOLS-RPC-AND-MESSAGING.md +81 -0
- package/skills/security-audit/RECONNAISSANCE.md +140 -0
- package/skills/security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md +78 -0
- package/skills/security-audit/SKILL.md +152 -0
- package/skills/security-audit/SUPPLY-CHAIN-AND-RELEASE.md +73 -0
- package/skills/security-audit/UPSTREAM.md +1 -0
- package/skills/security-audit/VALIDATION-AND-REPORTING.md +141 -0
- package/skills/security-audit/WEB-PROTOCOL-AND-AUTH.md +105 -0
- package/skills/security-audit/report-schema.json +461 -0
- package/skills/security-audit/validate-coverage-ledger.cjs +872 -0
- package/skills/security-audit/validate-findings.cjs +773 -0
- package/dist/main-jaz36mav.js +0 -10818
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-audit
|
|
3
|
+
description: Security guidance and vulnerability review for codebases, APIs, services, CLI tools, libraries, and daemons. Use for security questions, focused reviews, vulnerability research, security audits, or pen tests. Run the complete workflow only for explicit codebase audit or pen-test requests, full/comprehensive/end-to-end reviews, or requested report artifacts. Runs entirely in one agent, in the main thread; it never uses sub-agents.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Security Audit
|
|
7
|
+
|
|
8
|
+
Find vulnerabilities that violate a real trust boundary, then give owners the source evidence, safe reproduction, priority, and smallest effective fix. This is a defensive, source-first workflow. A candidate without a concrete affected principal, resource, or security outcome is not a confirmed finding.
|
|
9
|
+
|
|
10
|
+
## Operating modes
|
|
11
|
+
|
|
12
|
+
This skill is guidance by default. Loading it does not authorize the complete audit workflow or file creation.
|
|
13
|
+
|
|
14
|
+
- **Guidance mode**: For security questions, focused reviews, methodology, triage, or investigation of specific findings, use only the relevant parts of this skill. Do not automatically run all six phases, create an output directory, or write audit artifacts.
|
|
15
|
+
- **Full audit mode**: Use the complete workflow when the user explicitly asks to audit or pen-test a codebase, asks for a full, comprehensive, or end-to-end security review, or requests report artifacts. Run all six phases and write the files defined below.
|
|
16
|
+
|
|
17
|
+
If the request could mean either mode, ask one focused question before creating files or starting the complete workflow.
|
|
18
|
+
|
|
19
|
+
## Execution model: one agent, main thread
|
|
20
|
+
|
|
21
|
+
This skill runs entirely in the main thread. There are no sub-agents, no Task tool, and no parallel workers. One agent (you) performs every phase in order, owns every file, and never waits on anyone else. Your tools are read, bash, edit, write, grep, find, and ls.
|
|
22
|
+
|
|
23
|
+
Because no second reviewer exists, independence comes from a separate **disprove pass** (Phase 3): after all hunting is finished, you set aside your hunting notes and try to refute each candidate from scratch. A candidate is not confirmed until it survives that pass.
|
|
24
|
+
|
|
25
|
+
Pass labels. The ledger validator requires a different assignment owner for each reassignment, so label each pass instead of each agent: use `main-w1` as the owner `agent_id` for wave 1 hunting, `main-w2` for wave 2, and so on, and use `main-disprove` for checks recorded in the disprove pass and `main-final` for checks recorded in the final record re-check. These are labels for passes in your one thread, not separate agents.
|
|
26
|
+
|
|
27
|
+
## Universal execution safety
|
|
28
|
+
|
|
29
|
+
These rules apply in both operating modes. free-pi has no OS sandbox, so safety comes from what you choose to run.
|
|
30
|
+
|
|
31
|
+
- Validate by reading code. Run only the repository's own existing tests, or small offline checks on dummy data (a minimal function harness, a small malformed fixture, a locally rendered policy).
|
|
32
|
+
- Never run target code with network access, and never run it against live, deployed, shared, or production systems. Do not install dependencies or let builds fetch them. Use only tools already installed locally.
|
|
33
|
+
- Ask the user before running anything that executes code from the audited target, and say exactly what command you intend to run. Source inspection (read, grep, find, ls) needs no approval.
|
|
34
|
+
- Run checks with a minimal environment: do not pass credentials or tokens; use dummy principals, fixtures, and secrets. Do not read or copy the ambient environment, authentication state, or unrelated host paths into evidence.
|
|
35
|
+
- If a check would need network access, real credentials, a live service, or code execution you were not approved to run, do not run it. Keep the finding `needs_validation`, name the exact missing fact, and give a safe plan an owner could run.
|
|
36
|
+
- Stop at the minimum local effect that establishes a defect: a wrong return value, an unauthorized dummy record, a policy difference. Do not test availability against a live or shared process, publish artifacts, alter releases, or spend paid API quota.
|
|
37
|
+
|
|
38
|
+
Findings that need runtime proof you cannot safely or permissibly obtain stay `needs_validation`.
|
|
39
|
+
|
|
40
|
+
## Full audit setup
|
|
41
|
+
|
|
42
|
+
In full audit mode, resolve these values before reconnaissance:
|
|
43
|
+
|
|
44
|
+
- **Skill directory**: the absolute directory containing this `SKILL.md`.
|
|
45
|
+
- **Target**: the absolute repository root under review.
|
|
46
|
+
- **Repo name**: a stable repository identifier from the directory or local Git remote.
|
|
47
|
+
- **Output directory**: a new writable directory outside the target, defaulting to `~/security-audit-skill/<repo-name>/run-<N>`, where `<N>` is the next unused integer. Use a directory inside the target only when the user explicitly selects it and you verify that version control ignores the whole directory. Otherwise stop and request an external path.
|
|
48
|
+
- **Source ref**: the reviewed commit and whether the worktree is dirty. Do not treat unreviewed generated or modified files as another revision.
|
|
49
|
+
|
|
50
|
+
### Files and retained evidence
|
|
51
|
+
|
|
52
|
+
You write all run files: `run-metadata.json`, `architecture.md`, `coverage-ledger.json`, `findings.json`, `REPORT.md`, `FINDINGS-DETAIL.md`, and `NEEDS-VALIDATION.md`. Never edit target source.
|
|
53
|
+
|
|
54
|
+
Most checks are source reads and need no retained file (`method: "source"`, `artifact: null`). When an approved local check produces decisive evidence, save the small result (command output or fixture result, at most 1 MiB, a plain regular file with no symlinks, no archives, no secrets) at `<output-dir>/agents/<pass-label>/artifacts/<name>` and reference it from the check as `agents/<pass-label>/artifacts/<name>`, where `<pass-label>` is the check's own `agent_id`. If you cannot save it safely, do not cite it; keep `needs_validation` with the exact blocker.
|
|
55
|
+
|
|
56
|
+
For a reproduced check, record the command, exact test input, and only the environment variable names plus safe non-secret values needed to reproduce it.
|
|
57
|
+
|
|
58
|
+
Before hunting, write `run-metadata.json` with at least `run_id`, `repo`, `target`, `source_ref`, `profile`, `scope_paths`, `execution_policy: "single-agent-source-and-local-only"`, selected companion files, prior-run paths, and `run_status: "in_progress"`. Update it only when those facts change; candidate state belongs in the coverage ledger and `findings.json`.
|
|
59
|
+
|
|
60
|
+
## Full audit planning
|
|
61
|
+
|
|
62
|
+
The coverage, prior-run, and profile requirements in this section apply only in full audit mode.
|
|
63
|
+
|
|
64
|
+
### Coverage and prior runs
|
|
65
|
+
|
|
66
|
+
No one pass is complete. Build a deterministic coverage plan before hunting and update it after every unit you review. [RECONNAISSANCE.md](RECONNAISSANCE.md) defines the stable coverage units and [HUNTING.md](HUNTING.md) defines the coverage review that follows each hunting wave.
|
|
67
|
+
|
|
68
|
+
If prior runs exist, read every compatible `coverage-ledger.json` and `findings.json` before planning the current run:
|
|
69
|
+
|
|
70
|
+
1. Compare the relevant current source with each prior record and unit. A prior source ref alone is not evidence that a path is unchanged.
|
|
71
|
+
2. Carry a prior `confirmed` record into the current candidate set only when its relevant source and conditions are unchanged and its evidence still meets the current contract. Link it to a current ledger unit seeded `planned`, preserve its fingerprint, exclude only that carried root cause from hunting, and send the carried record through the current disprove pass; that pass becomes the unit's assignment owner and moves it to `candidate`.
|
|
72
|
+
3. When relevant source for a prior `confirmed` record changed, create a current planned revalidation unit. Do not put that record on the hunting exclusion list. It remains confirmed only if the current disprove pass establishes the current path and result.
|
|
73
|
+
4. Make prior `needs_validation`, `deferred`, `blocked`, `out_of_scope`, and any changed-source unit current work. A still-external `needs_validation` record may be carried only after the current source trace is checked and linked by fingerprint to a current `planned` unit whose disprove-pass re-check supplies its owner and evidence; the record keeps the unresolved blocker. These prior states never suppress a current unit.
|
|
74
|
+
5. A prior same-source covered unit may inform priority, but it remains visible in the current ledger. A prior `rejected` record suppresses only the unchanged failed claim, not coverage of its unit; changed evidence creates current work.
|
|
75
|
+
6. Read the prior profile and scope. A prior `quick` or scoped ledger contributes only its recorded evidence and gaps, never an implied "rest is fine."
|
|
76
|
+
|
|
77
|
+
If no prior ledger exists, say so in the final coverage statement. Never imply that one run exhausts the target.
|
|
78
|
+
|
|
79
|
+
### Run profiles and scope
|
|
80
|
+
|
|
81
|
+
During full audit setup, pick a profile from the user's request or propose one from the target's size and stakes. Record it in `run-metadata.json` (`profile`, `scope_paths`) and state it in the report. The default is `standard`.
|
|
82
|
+
|
|
83
|
+
- **`quick`** — a bounded pass for small targets, re-runs, or a fast first look. Coarsen ledger units to surface x boundary x attack class (subsystem uses the fixed canonical `profile/quick/all-in-scope-subsystems` identifier), run exactly one hunting wave followed by exactly one coverage review. Do not start a second hunting wave: record the review's accepted discoveries and reassignments as `deferred`.
|
|
84
|
+
- **`standard`** — the workflow as written.
|
|
85
|
+
- **`deep`** — for high-stakes or large targets. Split ledger units per subsystem and lifecycle mode, repeat hunting waves and coverage reviews until a review finds nothing new, and give `prior_covered_same_source` units a second pass.
|
|
86
|
+
|
|
87
|
+
A **scoped run** audits a subset: named paths, one subsystem, one companion domain, or the diff between two source refs. Seed ledger units only for in-scope surfaces and record everything else as `out_of_scope` — never as `covered`. A scoped or `quick` run must present itself as partial coverage.
|
|
88
|
+
|
|
89
|
+
Profiles change breadth and repetition, never the evidence bar. Do not scale away the candidate gate, the execution safety rules, `needs_validation` discipline, schema validation, or the disprove pass for `confirmed` records.
|
|
90
|
+
|
|
91
|
+
#### Context and time limits
|
|
92
|
+
|
|
93
|
+
One agent has finite context and time. Work units in priority order (HUNTING.md). If you cannot finish every unit, stop starting new ones, mark each untouched unit `deferred` with reason `context_or_time_exhausted`, finish the disprove pass for every candidate you already have, and set `run_status: "incomplete"` with the exact `incomplete_reason`. Tell the user what was not covered. If you cannot disprove-check every candidate, keep the unchecked ones as `candidate` ledger units with an unresolved reason; they never enter `findings.json` and are never presented as findings. Never claim complete coverage after an early stop.
|
|
94
|
+
|
|
95
|
+
## Core principles
|
|
96
|
+
|
|
97
|
+
### Require a boundary and result
|
|
98
|
+
|
|
99
|
+
For every candidate, name the lower-trust principal, accepted input or action, intended control, crossed boundary, affected principal or resource, and concrete observed or owner-observable result. Do not elevate a missing best practice, guessed deployment behavior, generic parser crash, or self-impact into a security finding.
|
|
100
|
+
|
|
101
|
+
### Use bounded local evidence
|
|
102
|
+
|
|
103
|
+
Static analysis establishes the source path. Approved local tests resolve behavior when the execution safety rules allow them: a minimal function harness, existing unit test, small parser fixture, dummy-tenant integration test, or locally rendered configuration. Stop at a wrong return value, unauthorized dummy record, sanitizer finding, policy difference, or other minimum effect. Do not extend the local check beyond the minimum boundary result or produce persistence, post-fault, or concealment material.
|
|
104
|
+
|
|
105
|
+
### Respect source visibility
|
|
106
|
+
|
|
107
|
+
Deployment controls, proxy behavior, provider settings, browser headers, identity policy, broker ACLs, packaging, and topology are real controls. If they are required and absent from the repository, do not assume either presence or absence. Use `needs_validation` with the exact missing fact and a safe owner-observed or local plan.
|
|
108
|
+
|
|
109
|
+
### Separate priority from certainty
|
|
110
|
+
|
|
111
|
+
Only `confirmed` records receive severity. Likelihood and impact must reflect the demonstrated conditions and result; overall severity cannot exceed demonstrated impact. `needs_validation` means a specific source-grounded boundary hypothesis is blocked, not a low-confidence confirmed vulnerability, and it has no severity.
|
|
112
|
+
|
|
113
|
+
Calibrate overall severity with these anchors:
|
|
114
|
+
|
|
115
|
+
- **critical** — an unauthenticated actor gains code execution, full data-store access, or takeover of arbitrary accounts.
|
|
116
|
+
- **high** — an actor fully defeats an explicit security control with real consequences: authentication bypass, cross-tenant read or write, stored script execution affecting other users, authenticated code execution, or an unauthenticated remote stop of a shared service.
|
|
117
|
+
- **medium** — a real boundary violation with limited blast radius, uncommon preconditions, or consequences confined to a narrow resource set.
|
|
118
|
+
- **low** — disclosure of non-secret internals, or an effect requiring sustained effort for minimal gain.
|
|
119
|
+
- **informational** — a confirmed but minimal-impact observation, useful mainly as a prerequisite inside a larger finding.
|
|
120
|
+
|
|
121
|
+
The high/medium discriminator: does the demonstrated result fully defeat an explicit control for an action with real consequences, or only weaken it? If you cannot state the concrete damage, the severity is lower than it feels.
|
|
122
|
+
|
|
123
|
+
### Recommend the smallest effective source fix
|
|
124
|
+
|
|
125
|
+
For each confirmed finding, identify the invariant the code must enforce and the narrowest source change that enforces it at the last trusted decision point. Prefer specific repository-relative changes and regression tests over generic hardening advice. The audit describes fixes; it does not modify target source.
|
|
126
|
+
|
|
127
|
+
## Full audit workflow
|
|
128
|
+
|
|
129
|
+
In full audit mode, you perform all six phases yourself, in order, in the main thread:
|
|
130
|
+
|
|
131
|
+
1. **Reconnaissance** — work through the four reconnaissance passes in [RECONNAISSANCE.md](RECONNAISSANCE.md) in order, then write the architecture summary and the initial deterministic coverage ledger.
|
|
132
|
+
2. **Coverage-led hunting waves** — take `planned` ledger units one at a time in priority order and hunt each with [HUNTING.md](HUNTING.md), [ATTACK-CLASSES.md](ATTACK-CLASSES.md), and the selected domain companions. After each wave, run the coverage review described there and repeat until it finds nothing new (or the profile or limits stop you).
|
|
133
|
+
3. **Disprove pass** — set aside your hunting notes. For each candidate, re-read the cited source from scratch, argue the strongest defense, and try to refute it, as defined in [VALIDATION-AND-REPORTING.md](VALIDATION-AND-REPORTING.md). Only candidates that survive are decided as `confirmed` or `needs_validation`.
|
|
134
|
+
4. **Structured output** — write all final `confirmed`, `needs_validation`, and `rejected` records to `findings.json`; validate it with `report-schema.json` and `validate-findings.cjs`, and validate the coverage claim with `validate-coverage-ledger.cjs`.
|
|
135
|
+
5. **Final record re-check** — re-verify each retained record against the source once more, reading only the record, and reconcile corrections or state changes.
|
|
136
|
+
6. **Target-neutral report** — derive `REPORT.md`, `FINDINGS-DETAIL.md`, and `NEEDS-VALIDATION.md` from the final records, with no live-probe instructions.
|
|
137
|
+
|
|
138
|
+
Do not end the run before one of exactly two terminal states: (a) all Phase 6 artifacts are written and both validators pass, or (b) `run_status: "incomplete"` is recorded with its exact reason and the gap is disclosed in the report. Never stop mid-phase.
|
|
139
|
+
|
|
140
|
+
## Anti-patterns
|
|
141
|
+
|
|
142
|
+
1. Checklist deviations presented as vulnerabilities.
|
|
143
|
+
2. Defense-in-depth advice with no reachable boundary violation.
|
|
144
|
+
3. Live or shared-environment testing where bounded local evidence is insufficient.
|
|
145
|
+
4. Guessing provider, proxy, browser, identity, or deployment behavior not present in source.
|
|
146
|
+
5. Treating intended same-principal authority or self-impact as a cross-boundary result.
|
|
147
|
+
6. Reporting a parser or runtime effect stronger than the observed effect.
|
|
148
|
+
7. Recording prose-only hunting results that cannot be deduplicated or verified.
|
|
149
|
+
8. Re-reporting carried same-source prior confirmed records or using them as exemplars that anchor the hunt.
|
|
150
|
+
9. Assigning severity to `needs_validation` records.
|
|
151
|
+
10. Writing the report before the disprove pass and final re-check, or letting prose and JSON disagree.
|
|
152
|
+
11. Confirming a candidate in the same breath you found it, without a separate attempt to refute it.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Supply Chain and Release Hunting
|
|
2
|
+
|
|
3
|
+
#### When to use this file
|
|
4
|
+
|
|
5
|
+
Reach for this file when the target resolves dependencies, builds from untrusted contributions, runs CI, creates release artifacts, signs or promotes builds, loads plugins, or updates deployed software. This domain covers trust handoffs from source and dependency to the artifact a user runs. Use `MEMORY-SAFETY-AND-BINARY.md` for flaws inside a local binary loader and `CLOUD-AND-DEPLOYMENT.md` for runtime workload authority.
|
|
6
|
+
|
|
7
|
+
Split large targets into dependency resolution, CI isolation, artifact provenance, release authorization, and updater/plugin trust.
|
|
8
|
+
|
|
9
|
+
## Core discipline (apply throughout this domain)
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
- A mutable or known-vulnerable dependency is not a finding by itself. Show who can influence resolution, which build consumes it, and what execution or release boundary follows.
|
|
13
|
+
- Follow integrity across every handoff: source identity, resolved inputs, build worker, artifact identity, test result, signature/attestation, promotion, and update consumer.
|
|
14
|
+
- CI configuration is authorization code. Establish which event triggered a workflow, whose code runs, which secrets and tokens exist, and what it may publish or mutate.
|
|
15
|
+
- A checksum fetched from the same untrusted location as the artifact does not establish independent integrity. Identify the trusted root and failure behavior.
|
|
16
|
+
- Use `confirmed` for in-repo control-flow failures with bounded local validation. Use `needs_validation` for branch protection, hosted-runner, registry, signing-service, or production promotion facts that are not observable.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Dependency and build-input attack classes
|
|
20
|
+
|
|
21
|
+
**Dependency source and namespace confusion**
|
|
22
|
+
Resolver configuration can select an unintended public/private namespace, fallback registry, mirror, repository, or source URL. Review package names, source priority, lockfile and checksum use, alternate build files, platform-specific resolution, and first-install versus update behavior.
|
|
23
|
+
|
|
24
|
+
**Mutable and unbound build inputs**
|
|
25
|
+
Builds consume branches, tags, unverified submodules, downloaded tools, generated assets, remote includes, floating CI actions, or container tags whose content can change without source review. Require a lower-trust writer and a path into trusted build output; reproducibility by itself does not prove authenticity.
|
|
26
|
+
|
|
27
|
+
**Generated-source and codegen provenance gaps**
|
|
28
|
+
Schemas, vendored archives, generated clients, localization, documentation examples, or binary blobs produce executable or shipped content without the same review and integrity gate as source. Compare local regeneration with committed output and verify who controls input and generator.
|
|
29
|
+
|
|
30
|
+
**Build-context inclusion**
|
|
31
|
+
Secrets, local configuration, repository metadata, test fixtures, or developer artifacts enter a package or image because the build context and ignore rules exceed intended release inputs. Confirm that the resulting artifact exposes a real credential, private data, or privileged configuration.
|
|
32
|
+
|
|
33
|
+
## CI and automation attack classes
|
|
34
|
+
|
|
35
|
+
**Untrusted code in a privileged workflow**
|
|
36
|
+
A pull request, issue comment, fork, dependency update, or external event runs contributor-controlled code with protected secrets, write tokens, deployment authority, or a trusted runner. Compare trigger type, checkout ref, approval gate, environment protection, and permission narrowing. Do not assume repository-host defaults that are not in source.
|
|
37
|
+
|
|
38
|
+
**Workflow command and expression confusion**
|
|
39
|
+
Attacker-controlled branch names, commit messages, issue fields, artifact names, matrix values, or generated output enter shell commands, template expressions, paths, or privileged workflow inputs without canonical validation.
|
|
40
|
+
|
|
41
|
+
**Cache, artifact, and workspace trust mixing**
|
|
42
|
+
A lower-trust job can populate a cache, artifact, shared workspace, or output that a higher-trust job later restores and executes or releases. Review cache keys and namespaces, artifact producer identity, digest binding, retention, and whether promotion re-resolves by mutable name.
|
|
43
|
+
|
|
44
|
+
**Automation identity overreach**
|
|
45
|
+
CI jobs receive permissions beyond the operation, repository, environment, or duration needed, and untrusted job inputs can select the affected resource. Missing least privilege alone is hardening; require a reachable privileged action.
|
|
46
|
+
|
|
47
|
+
## Release and update attack classes
|
|
48
|
+
|
|
49
|
+
**Build-to-promotion substitution**
|
|
50
|
+
Tests, review, signature, and publication refer to mutable tags, filenames, channels, or artifact IDs rather than the same immutable digest. Check every copy, repack, architecture merge, and provenance step between build and release.
|
|
51
|
+
|
|
52
|
+
**Release authorization and signing-policy gaps**
|
|
53
|
+
A release or signature is accepted from the wrong workflow, repository, branch, environment, key role, or threshold. Review identity claims inside attestations and verify the consumer validates them, not just a valid signature. Rotation, expiry, and revocation must fail closed where policy requires.
|
|
54
|
+
|
|
55
|
+
**Update metadata and rollback confusion**
|
|
56
|
+
An updater authenticates payload bytes but not version, product, platform, channel, target path, expiry, or rollback state, or it accepts metadata and payload from different authorized transactions. Verify atomic installation and recovery behavior. A signature API call without policy binding is incomplete.
|
|
57
|
+
|
|
58
|
+
**Plugin and extension trust expansion**
|
|
59
|
+
An extension package gains host authority beyond its declared scope, a lower-trust publisher can replace another publisher's identity, or install/update hooks run before authenticity and capability checks. Intended installation of arbitrary same-user plugins is not a privilege boundary.
|
|
60
|
+
|
|
61
|
+
## Universal moves (apply across the above)
|
|
62
|
+
|
|
63
|
+
- Walk backward from a released digest or installed update to every source, generated input, credential, worker, cache, test result, and authorization decision.
|
|
64
|
+
- Compare untrusted and protected workflow events side by side. Mark each persisted channel crossing between them and require an immutable identity plus producer trust.
|
|
65
|
+
- Review revoked key, failed download, missing attestation, partial platform release, rollback, and registry outage paths. The failure policy is part of release integrity.
|
|
66
|
+
|
|
67
|
+
## Validation rules (apply before reporting ANY finding here)
|
|
68
|
+
|
|
69
|
+
1. Name the lower-trust actor, controllable source/cache/artifact/metadata, consuming trusted job or updater, and resulting unauthorized publication, code inclusion, secret disclosure, or privileged execution.
|
|
70
|
+
2. Prove artifact identity across the broken handoff. A different mutable name or unbound digest must reach a real consumer.
|
|
71
|
+
3. Verify built-in package-manager, repository-host, registry, and signing defaults for the pinned version. Unknown hosted controls require `needs_validation`.
|
|
72
|
+
4. Keep local validation bounded: use a harmless fixture repository, dummy credential marker, local registry/config, and non-production artifact namespace. Do not publish or alter a real release.
|
|
73
|
+
5. Return `confirmed` only with a complete source-visible handoff and meaningful result. Return `needs_validation` with the precise branch, runner, registry, signing, or deployment fact an owner must observe.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Vendored from https://github.com/cloudflare/security-audit-skill at c1c8a8c1471069fb0e188eeaff69b8e8db6564a8 (MIT, see LICENSE). Modified for free-pi (single agent, no sub-agents): SKILL.md, RECONNAISSANCE.md, HUNTING.md and VALIDATION-AND-REPORTING.md now run every phase in the main thread with a separate disprove pass instead of parallel agents and an OS sandbox; `(subagent_type: ...)` labels were removed from section headings. The validators, report schema and the two `*.test.cjs` files were not changed or vendored.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Validation, Structured Output, Verification, and Reporting
|
|
2
|
+
|
|
3
|
+
### Phase 3: Disprove pass on every candidate
|
|
4
|
+
|
|
5
|
+
After the clean coverage review or an explicitly recorded early stop, consolidate Phase 2 candidates and carried same-source prior confirmations by stable fingerprint and root cause. Then run the disprove pass on every unique proposed `confirmed` and `needs_validation` candidate. A carried prior confirmation follows the same current path even though hunting excluded that unchanged root cause.
|
|
6
|
+
|
|
7
|
+
You are the only agent, so independence has to come from method. Before starting, stop working from your hunting notes: close them, and for each candidate work only from its written record (fingerprint, trace, evidence, claimed result). Treat the record as a claim made by someone else that you are trying to knock down. Re-read every cited current source location yourself, and decide from what the code says now, not from what you remember. Do the whole pass for one candidate before moving to the next, and decide each candidate separately.
|
|
8
|
+
|
|
9
|
+
#### Disprove checklist
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
Try to refute this candidate from repository source and, where approved and safe,
|
|
13
|
+
bounded local evidence. Do not contact deployed endpoints or external/shared services.
|
|
14
|
+
Follow the execution safety rules in SKILL.md: ask the user before running anything
|
|
15
|
+
that executes code from the target, run offline on dummy data only, and if a check
|
|
16
|
+
cannot be run safely keep the exact missing capability as a needs_validation blocker.
|
|
17
|
+
|
|
18
|
+
1. Verify every trace and evidence file, positive line number, scope, and description.
|
|
19
|
+
Confirm the first entry is a real lower-trust entrypoint and the last is the
|
|
20
|
+
claimed sink or boundary effect.
|
|
21
|
+
2. Reconstruct the strongest source-visible validation, identity, authorization,
|
|
22
|
+
normalization, lifecycle, framework, and containment controls on the path. Search
|
|
23
|
+
for a layer you missed (middleware, a framework default, a wrapper, a later check).
|
|
24
|
+
Where the architecture summary names a comparable baseline, note whether it shares
|
|
25
|
+
the pattern, as calibration and never as grounds to dismiss.
|
|
26
|
+
3. For a proposed confirmed candidate, re-establish the minimum observed result
|
|
27
|
+
independently: by re-tracing the exact input through the code, and by an approved
|
|
28
|
+
local check when one is safe and offline. Verify inputs, interface shape, conditions,
|
|
29
|
+
and the affected dummy principal/resource. Do not infer a stronger result.
|
|
30
|
+
4. Check that likelihood, impact, confidence, and the proposed source fix match only
|
|
31
|
+
what the evidence establishes.
|
|
32
|
+
5. For a proposed needs_validation candidate, decide whether the blocker is genuinely
|
|
33
|
+
outside source/local observation. If source refutes the trace, reject it. If the
|
|
34
|
+
missing fact remains decisive, keep needs_validation and make the local and
|
|
35
|
+
owner-observed plans exact and non-destructive.
|
|
36
|
+
6. Preserve the fingerprint for the same source-derived root cause across every state.
|
|
37
|
+
|
|
38
|
+
Decide one of: confirmed, needs_validation, rejected. Write the corrected record in the
|
|
39
|
+
schema branch matching your decision; a corrected record replaces your hunting wording.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A candidate can move from `needs_validation` to `confirmed` only after you independently establish the complete path and bounded observed result in this pass. Demote a proposed confirmation to `needs_validation` when a specific deployment or runtime fact remains unknown. Use `rejected` when source, local behavior, a visible control, missing meaningful impact, or an impossible prerequisite refutes the claim. `needs_validation` is never a parking place for a speculative idea.
|
|
43
|
+
|
|
44
|
+
Merge corrections, record the decision in every linked coverage unit, and ensure there is one final record per fingerprint. Keep a candidate's fingerprint the same unless you identified a genuinely different root cause (give that one a new fingerprint and run it through this pass too).
|
|
45
|
+
|
|
46
|
+
When the disprove pass updates a ledger check, add a check with `agent_id: "main-disprove"` and its nonempty repository-relative `reviewed_paths`. Keep the unit-level `reviewed_paths` equal to the union across checks. Use `method: "source"` with `artifact: null` for source-only review. Use `method: "local"` only with a plain regular file you saved below `agents/main-disprove/artifacts/`. The unit retains its original hunting-pass owner, so hunting and disprove checks coexist. For a carried prior record's seeded `planned` unit there is no prior owner: set `agent_id: "main-disprove"` as the unit's owner, and its re-check is the unit's first check, moving the unit to `candidate` with the carried fingerprint.
|
|
47
|
+
|
|
48
|
+
If you cannot disprove-check every candidate, follow the incomplete-run rule in `SKILL.md`. An unchecked candidate remains only in the ledger. It does not enter `findings.json` under any verdict.
|
|
49
|
+
|
|
50
|
+
### Phase 4: Write and validate `findings.json`
|
|
51
|
+
|
|
52
|
+
Write all decided records to `<output-dir>/findings.json`, sorted by fingerprint. Include:
|
|
53
|
+
|
|
54
|
+
- `confirmed`: source-grounded vulnerabilities with complete local execution evidence, conditions, specific remediation, likelihood/impact/overall severity, and confidence.
|
|
55
|
+
- `needs_validation`: source-grounded candidates with an exact unresolved blocker and at least one applicable local or owner-observed deployment plan.
|
|
56
|
+
- `rejected`: source-grounded candidates disproved during validation, retained so future runs do not repeat the unsupported claim without changed evidence.
|
|
57
|
+
|
|
58
|
+
Read `report-schema.json` immediately before writing. It uses `additionalProperties: false`; do not carry working-record fields such as `proposed_verdict` into a record. Keep these verdict contracts distinct:
|
|
59
|
+
|
|
60
|
+
- A `confirmed` record uses `root_cause`, `intended_behavior`, `conditions`, `execution`, `remediation`, `severity`, and `confidence`. It must not use `claimed_root_cause`, `blockers`, `validation_plan`, or `reason`. `execution` is target-neutral and uses the target's native interface: API/HTTP input, CLI call, library call, message, file fixture, browser action, rendered policy, or local harness as applicable. `observed_result` is nonempty and factual.
|
|
61
|
+
- A `needs_validation` record uses `claimed_root_cause`, `trace`, `evidence`, `blockers`, and at least one nonempty `validation_plan.local` or `validation_plan.deployment` field. Include both only when both contexts can resolve distinct facts. It must not use severity, execution, remediation, reason, or confirmed root cause.
|
|
62
|
+
- A `rejected` record uses `claimed_root_cause`, `trace`, `evidence`, and `reason`. It must not use severity, execution, remediation, blockers, validation plan, or confirmed root cause.
|
|
63
|
+
|
|
64
|
+
Every record has a stable fingerprint, title, description, and repository-relative source paths. A multi-step trace begins with `entrypoint`, ends with `sink`, and uses `propagation` only between them. One-entry traces use `entrypoint` or `sink`. Overall severity cannot exceed demonstrated impact.
|
|
65
|
+
|
|
66
|
+
Run:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
node <skill-dir>/validate-findings.cjs <output-dir>/findings.json
|
|
70
|
+
node <skill-dir>/validate-coverage-ledger.cjs <output-dir>/coverage-ledger.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Fix every structural and semantic error before continuing. The findings validator rejects input beyond 5 MiB, 1,000 top-level findings, or 64 nesting levels, and caps reported error output at 100 messages. Validator success proves format and ledger consistency only.
|
|
74
|
+
|
|
75
|
+
### Phase 5: Re-check the final records
|
|
76
|
+
|
|
77
|
+
Re-check every final `confirmed` and `needs_validation` record once more, as a separate step after `findings.json` validates. Read only the structured record, not your hunting or disprove notes, and re-read the cited source. Stay inside source and approved local boundaries.
|
|
78
|
+
|
|
79
|
+
In a `quick` run, Phase 3 and Phase 5 merge: the disprove pass also performs these record checks, so each candidate gets one dedicated refutation attempt. Every other profile keeps the two steps separate. Never skip the disprove pass for a `confirmed` record in any profile.
|
|
80
|
+
|
|
81
|
+
For `confirmed`, check:
|
|
82
|
+
|
|
83
|
+
1. Every repository-relative trace/evidence path, line, scope, and described operation.
|
|
84
|
+
2. Real entry interface and exact local input shape.
|
|
85
|
+
3. Every condition, parser/policy step, source-visible preventing layer, and observed result.
|
|
86
|
+
4. Affected principal/resource and demonstrated impact.
|
|
87
|
+
5. Severity separation: realistic likelihood, demonstrated impact, overall no greater than impact.
|
|
88
|
+
6. Remediation strategy and any `code_changes`, including whether the fix enforces the invariant without merely moving trust.
|
|
89
|
+
|
|
90
|
+
For `needs_validation`, check:
|
|
91
|
+
|
|
92
|
+
1. The source path is real and supports only the `claimed_root_cause` stated.
|
|
93
|
+
2. Every listed blocker is decisive and not already answerable locally.
|
|
94
|
+
3. The candidate names a boundary and a possible concrete result rather than a generic concern.
|
|
95
|
+
4. At least one validation-plan field is present and exact. `local` uses a bounded fixture; `deployment` asks an owner to observe a configuration, identity, route, policy, or runtime fact. Do not invent a plan for an inapplicable context, and never send audit traffic to a deployment.
|
|
96
|
+
5. The fingerprint matches prior/current records for the same root cause.
|
|
97
|
+
|
|
98
|
+
The outcome for each record is either "verified" or "replace" with a corrected record matching its `confirmed`, `needs_validation`, or `rejected` schema branch. Apply non-material wording or repository-line corrections directly. For a replacement that promotes a record to a stronger verdict (including any promotion to `confirmed`) or materially changes the root cause, trace, execution input or observed result, demonstrated impact, or severity, do not apply it from this step alone: go back to Phase 3 and run the full disprove checklist on the replacement as a new candidate. Apply it only if it survives. If it does not survive, or you cannot finish that, remove the disputed record from `findings.json`, keep its ledger unit as an unresolved candidate, and set `run_status: "incomplete"` with an exact `incomplete_reason`.
|
|
99
|
+
|
|
100
|
+
When a re-check adds ledger evidence, record it as a check with `agent_id: "main-final"`.
|
|
101
|
+
|
|
102
|
+
After every applied replacement, rerun both validators and update linked ledger decisions. If the re-check finds a separate root cause, assign a new fingerprint and send it through the disprove pass before inclusion. Set `run_status: "complete"` only when every ledger candidate has a final disposition and every retained record passes this step.
|
|
103
|
+
|
|
104
|
+
Do not re-check only `confirmed` records. A misleading `needs_validation` handoff wastes owner time and can preserve a false premise.
|
|
105
|
+
|
|
106
|
+
### Phase 6: Produce target-neutral reports from final records
|
|
107
|
+
|
|
108
|
+
Only after the Phase 5 re-check passes for every record retained in `findings.json`, derive prose from the final records, the ledger, and the `hardening` notes retained in ledger bookkeeping. An incomplete run may report independently verified records, but it must identify each unresolved ledger candidate and must not present it as a finding. The prose files never change a verdict, severity, blocker, or demonstrated impact.
|
|
109
|
+
|
|
110
|
+
#### `REPORT.md`
|
|
111
|
+
|
|
112
|
+
Write:
|
|
113
|
+
|
|
114
|
+
1. Run profile, scope, source ref, a single-agent source-and-local-only execution statement (what was and was not run), prior-run use, and explicit deferred and out-of-scope coverage. Name carried same-source confirmations and changed-source revalidations. A `quick`, scoped, limit-stopped, or incomplete run states plainly that it is a partial pass. If you ran out of context or time before the disprove pass finished, state that the run is incomplete and list every unchecked fingerprint and linked unit; do not describe those candidates as findings. If a coverage review did not run, say which and make no clean-coverage claim.
|
|
115
|
+
2. One short security posture summary.
|
|
116
|
+
3. A confirmed-findings table: severity, title, affected boundary, and one-line observed result.
|
|
117
|
+
4. Each confirmed finding: repository source location, lower-trust principal, target-native bounded reproduction, conditions, actual result, impact, priority rationale, and smallest source fix.
|
|
118
|
+
5. A separate `NEEDS VALIDATION` table. Give each lead's title, repository trace, exact blocker, bounded local next step, and safe owner-observed deployment check. Do not assign severity or call it a confirmed vulnerability.
|
|
119
|
+
6. Separate hardening notes and positive source patterns.
|
|
120
|
+
7. Coverage summary from the ledger: covered, candidate, blocked, and deferred counts, plus important exclusions and the final coverage review result.
|
|
121
|
+
|
|
122
|
+
Do not describe rejected records as findings. Mention their fingerprints only when they explain a prior disagreement or coverage decision.
|
|
123
|
+
|
|
124
|
+
#### `FINDINGS-DETAIL.md`
|
|
125
|
+
|
|
126
|
+
For each confirmed `medium`, `high`, or `critical` record, copy the complete source path and target-neutral local reproduction:
|
|
127
|
+
|
|
128
|
+
- ordered repository-relative trace and evidence;
|
|
129
|
+
- dummy attacker/principal and affected dummy resource;
|
|
130
|
+
- native input, invocation, or fixture and exact bounded instructions;
|
|
131
|
+
- observed output and the security invariant it proves;
|
|
132
|
+
- conditions and containment;
|
|
133
|
+
- source-level remediation and regression case.
|
|
134
|
+
|
|
135
|
+
#### `NEEDS-VALIDATION.md`
|
|
136
|
+
|
|
137
|
+
For every unresolved record, copy the source trace, verified evidence, exact blocker, affected boundary, and each applicable bounded local or owner-observed resolution plan. Keep these as prioritized leads without severity. Do not turn them into live test guidance or assume the missing deployment fact.
|
|
138
|
+
|
|
139
|
+
HTTP is one possible native interface, not the default. A library finding may use a function call, a parser a fixture, a CLI a command, a desktop app an IPC or file action, and infrastructure a locally rendered policy. Do not require an endpoint, external account, or live environment that the target does not have.
|
|
140
|
+
|
|
141
|
+
Keep the report proportional to the evidence. A clean run may have zero confirmed records. State that result and the remaining coverage/validation limits without inventing LOW findings.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# HTTP-Protocol and Authentication Hunting
|
|
2
|
+
|
|
3
|
+
#### When to use this file
|
|
4
|
+
|
|
5
|
+
Reach for this file when the target speaks HTTP at a parsing, caching, browser-authentication, or identity boundary: web applications, APIs, reverse proxies, CDNs, gateways, custom HTTP servers, and services implementing sessions, JWT, OAuth/OIDC, SAML, password recovery, MFA, passkeys, API keys, or mTLS. Use this with `ATTACK-CLASSES.md`: access-control review asks whether a principal may perform an operation; this file asks whether the HTTP or identity layer can confuse which principal, request, assurance level, or token the operation belongs to.
|
|
6
|
+
|
|
7
|
+
Pick classes from Phase 1. Split a large target into request framing and cache policy, browser authentication, federated identity, strong authentication and recovery, service credentials, and session lifecycle. A single server behind an unobserved managed proxy has little source-confirmable smuggling surface; a proxy or custom parser has much more.
|
|
8
|
+
|
|
9
|
+
## Core discipline (apply throughout this domain)
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
- Framing and cache findings require two interpretations of the same request, response, or key. Name both components and the exact normalized value on each side.
|
|
13
|
+
- For every credential, find the signature or secret verification and every binding required for its role: issuer, audience, origin, RP, client, session, principal, resource, assurance, expiry, and one-time state.
|
|
14
|
+
- Host, Forwarded, X-Forwarded-*, Origin, Referer, redirect targets, callback state, and request-derived URLs are trust decisions. Trace each to the affected identity or response.
|
|
15
|
+
- A missing header, cookie attribute, MFA prompt, or rate limit is not a finding alone. Require an accepted invalid request, cross-principal impact, assurance downgrade, or credential disclosure.
|
|
16
|
+
- Classify `confirmed` only from complete source evidence and bounded local request/token tests. Use `needs_validation` when proxy, IdP, browser, certificate, secret, or deployed configuration is required but not visible.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## HTTP framing and cache attack classes
|
|
20
|
+
|
|
21
|
+
**Request framing and desynchronization**
|
|
22
|
+
Front end and back end disagree on request length or header normalization. Review multiple `Content-Length` values, `Transfer-Encoding`, HTTP/2 or HTTP/3 downgrade, header-name normalization, forbidden connection headers, and CR/LF conversion. Confirm which bytes one component assigns to a request and which bytes its peer assigns to the next request.
|
|
23
|
+
|
|
24
|
+
**Web cache poisoning through unkeyed input**
|
|
25
|
+
A request value changes cached content or security-relevant headers but is absent from the cache key. Compare cache key construction with every response variant, including forwarded host/scheme, selected cookies, query normalization, language/device headers, and authorization state.
|
|
26
|
+
|
|
27
|
+
**Cache deception and private-response caching**
|
|
28
|
+
Cache routing treats a private dynamic path as a public static asset, or caches a response whose identity and authorization inputs are missing from policy. Compare edge cacheability with application route parsing, suffix/path-parameter normalization, and response cache directives.
|
|
29
|
+
|
|
30
|
+
**Host and forwarded-header trust**
|
|
31
|
+
Untrusted host/proxy metadata determines absolute URLs, tenant routing, callbacks, reset links, cache keys, or the client address used by authorization. Confirm who can supply the header and whether trusted ingress removes client-provided copies.
|
|
32
|
+
|
|
33
|
+
**Response-header injection**
|
|
34
|
+
Untrusted data reaches `Location`, `Set-Cookie`, CSP, or another response header with unsafe control characters or normalization. Verify framework rejection before reporting and require a security-relevant response change.
|
|
35
|
+
|
|
36
|
+
## Browser-session attack classes
|
|
37
|
+
|
|
38
|
+
**Ordinary CSRF**
|
|
39
|
+
A browser sends ambient credentials to a state-changing endpoint that accepts a cross-site request without an effective anti-CSRF token, same-site request binding, or strict Origin/Referer validation. Inventory every cookie-authenticated mutation, including form, JSON-like, multipart, method-override, and legacy routes. SameSite is effective only for the cookie and browser contexts actually used; login CSRF and cross-site subresource requests can have different requirements.
|
|
40
|
+
|
|
41
|
+
**Session fixation and invalidation**
|
|
42
|
+
Session identifiers are not rotated on login, account switch, MFA completion, impersonation, or other privilege changes, or remain valid after logout, password change, revocation, and account disable. Check server sessions, refresh tokens, signed cookies, websocket state, cache copies, and fallback endpoints.
|
|
43
|
+
|
|
44
|
+
**Cookie scope and transport**
|
|
45
|
+
A sensitive cookie has an over-broad `Domain` or `Path`, can cross an insecure transport, or conflicts with a sibling cookie that another component selects differently. Bare missing flags remain hardening notes unless a realistic less-trusted origin, network position, or browser path can gain or replace the credential.
|
|
46
|
+
|
|
47
|
+
## Federated-identity attack classes
|
|
48
|
+
|
|
49
|
+
First establish role. Authorization-server controls such as redirect allowlisting and code issuance do not belong to a relying-party client. Verification and binding defects belong to the component consuming the artifact.
|
|
50
|
+
|
|
51
|
+
**JWT verification and claim binding**
|
|
52
|
+
Check signature verification, server-pinned algorithm and key source, then `exp`, `nbf`, `aud`, and `iss`. Review `kid`, `jku`, and `x5u` as untrusted key selectors, duplicate/header normalization, and decode-without-verify paths. A valid token for another service is invalid here even when signed by a trusted issuer.
|
|
53
|
+
|
|
54
|
+
**OAuth/OIDC request and callback binding**
|
|
55
|
+
Validate exact `redirect_uri` ownership where the target is the authorization server; session-bound `state`; PKCE and authorization-code binding where applicable; ID-token issuer/audience/signature/nonce; and selected-IdP binding in multi-provider flows. Compare initial callback, retry, mobile/deep-link, and account-link routes.
|
|
56
|
+
|
|
57
|
+
**SAML signed-object and assertion binding**
|
|
58
|
+
Ensure the element whose signature is validated is the element used as identity. Review unsigned/fallback paths, safe XML parser configuration, canonicalization differences, and freshness/binding fields such as validity windows, audience/recipient, request correlation, and replay state.
|
|
59
|
+
|
|
60
|
+
## MFA, passkey, and account-transition attack classes
|
|
61
|
+
|
|
62
|
+
**MFA enrollment and assurance downgrade**
|
|
63
|
+
Enrollment, replacement, disablement, recovery-code generation, trusted-device creation, and fallback login require the intended prior assurance. Check that a valid first factor cannot enroll or replace the second factor without policy-required fresh authentication, and that disabled or stale factors stop authorizing sessions.
|
|
64
|
+
|
|
65
|
+
**Step-up binding and bypass**
|
|
66
|
+
A successful challenge upgrades the wrong session, account, tenant, action, or API request, or an alternate route omits the assurance check. Bind the challenge to principal, current session, assurance target, operation or resource when required, expiry, and one-time completion. Compare UI, API, batch, recovery, and resumed-flow paths.
|
|
67
|
+
|
|
68
|
+
**WebAuthn and passkey verification**
|
|
69
|
+
At registration, bind challenge, RP ID, expected origin, credential, user/userHandle, algorithm, and policy-required user verification to the initiating session. At authentication, verify challenge, RP/origin, credential membership, signature, and intended user presence/verification. Check account-discovery and linking flows for userHandle or credential-to-account confusion. Signature-counter handling is meaningful only when the product treats regressions as a clone signal.
|
|
70
|
+
|
|
71
|
+
**Account linking and identity collision**
|
|
72
|
+
Adding an IdP, passkey, email, phone, device, or external account to an existing account must require a current authenticated session, verified ownership of the new identity, policy-required step-up, and callback state bound to the account that initiated linking. Review unlink/relink and invite-acceptance paths for verified-identifier or tenant collisions.
|
|
73
|
+
|
|
74
|
+
**Password reset and broader recovery**
|
|
75
|
+
Recovery tokens, support/admin recovery, backup codes, device migration, and email or phone change often become the weakest authentication path. Verify token randomness, user/action binding, expiry, one-time state, rate/accounting controls, delivery URL trust, and invalidation of prior tokens and sessions. Different responses that only reveal public account existence are not automatically security findings.
|
|
76
|
+
|
|
77
|
+
## API-key and mTLS attack classes
|
|
78
|
+
|
|
79
|
+
**API-key scope and resource binding**
|
|
80
|
+
A key authenticates to broader tenants, resources, actions, or environments than its server-side record grants, or request parameters override those bindings. Review key lookup, prefix/full-secret verification, type confusion between publishable and secret keys, scope checks, rotation, revocation caches, and bulk endpoints.
|
|
81
|
+
|
|
82
|
+
**API-key exposure and unsafe transport**
|
|
83
|
+
Keys appear in client bundles, URLs, redirects, logs, error paths, build artifacts, or responses accessible to a lower-trust principal. A public identifier called a key is not a secret. Confirm key type and the authority gained by disclosure.
|
|
84
|
+
|
|
85
|
+
**mTLS peer and application-identity confusion**
|
|
86
|
+
A process trusts client-certificate identity headers from any network peer, verifies a chain but maps attacker-influenceable subject text to an account incorrectly, or accepts a certificate for the wrong trust domain, extended usage, audience, or validity policy. Where a trusted proxy terminates mTLS, verify only that proxy can connect, it removes incoming identity headers, and the backend binds the sanitized identity to the request.
|
|
87
|
+
|
|
88
|
+
**Certificate lifecycle fallback**
|
|
89
|
+
Expired, revoked, missing, or renewal-failed certificates cause silent fallback to bearer-only or anonymous operation, or long-lived pooled connections retain authorization after revocation. Missing deployment revocation data makes the result `needs_validation`; an in-repo fail-open branch is source-confirmable.
|
|
90
|
+
|
|
91
|
+
## Universal moves (apply across the above)
|
|
92
|
+
|
|
93
|
+
- Walk issue → store → transmit → consume → refresh → revoke for every credential and challenge. Compare normal, error, retry, migration, legacy, and account-switch paths.
|
|
94
|
+
- Enumerate every door to the same identity and every route to the same sensitive operation. The effective policy is the weakest parallel path, not the most polished UI.
|
|
95
|
+
- Diff parser, proxy, router, cache, and application normalization side by side. For local validation, feed identical bounded request fixtures into each component rather than sending traffic to a live deployment.
|
|
96
|
+
- For recovery and linking, draw the account before/after graph. Each edge must name the current principal, proof of the new identity, required assurance, callback/session binding, and revocation effect.
|
|
97
|
+
|
|
98
|
+
## Validation rules (apply before reporting ANY finding here)
|
|
99
|
+
|
|
100
|
+
1. Apply a source-visibility gate. Proxy chains, edge cache keys, IdP policy, certificate trust, browser cookie behavior, secrets, and deployed auth modes may be outside the repository. Record a precise `needs_validation` candidate instead of asserting missing infrastructure behavior.
|
|
101
|
+
2. For framing and cache findings, name both components and the divergent parse/key. Confirm cross-request, cross-user, or private-response impact with bounded local fixtures.
|
|
102
|
+
3. For token, MFA, passkey, account-link, recovery, API-key, and mTLS findings, cite the verification line and missing principal/session/resource/origin/audience/action/assurance binding. Prove the server accepts the invalid transition or credential.
|
|
103
|
+
4. For CSRF, name the ambient credential, state-changing route, accepted cross-site request shape, browser cookie policy, and missing effective check. Read-only actions and routes requiring a non-ambient bearer token do not qualify.
|
|
104
|
+
5. Verify framework and library defaults. If version or configuration is unknown, use `needs_validation`; do not turn an unverified critical claim into a lower-severity confirmed finding.
|
|
105
|
+
6. Return `confirmed` only with a complete source trace and observable unauthorized identity, state, or disclosure. For `needs_validation`, name the missing fact and safe local or owner-observed check that resolves it.
|