@tamsensedev/runner 0.13.0 → 0.19.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.
Files changed (82) hide show
  1. package/LICENSE +5 -5
  2. package/README.md +76 -57
  3. package/dist/cli.js +757 -379
  4. package/dist/cli.js.map +1 -1
  5. package/dist/recorder.cjs.map +1 -1
  6. package/library/.claude-plugin/plugin.json +5 -5
  7. package/library/THIRD_PARTY_NOTICES.md +123 -123
  8. package/library/agents/code-architect.md +67 -67
  9. package/library/agents/code-explorer.md +61 -61
  10. package/library/agents/code-reviewer.md +73 -73
  11. package/library/agents/code-simplifier.md +62 -62
  12. package/library/agents/design-critic.md +52 -52
  13. package/library/agents/second-opinion.md +64 -64
  14. package/library/agents/security-auditor.md +86 -86
  15. package/library/agents/silent-failure-hunter.md +70 -70
  16. package/library/agents/test-coverage-analyzer.md +78 -78
  17. package/library/agents/test-runner.md +48 -48
  18. package/library/agents/ui-tester.md +50 -50
  19. package/library/licenses/Apache-2.0.txt +202 -202
  20. package/library/skills/accessibility/SKILL.md +144 -144
  21. package/library/skills/accessibility/references/wcag-checks.md +168 -168
  22. package/library/skills/addressing-review-feedback/SKILL.md +109 -109
  23. package/library/skills/app-screens/SKILL.md +96 -96
  24. package/library/skills/app-screens/references/shell-kpis-charts.md +108 -108
  25. package/library/skills/app-screens/references/states-density-phone.md +54 -54
  26. package/library/skills/app-screens/references/tables-forms-settings.md +104 -104
  27. package/library/skills/avoiding-generic-ai-design/SKILL.md +92 -92
  28. package/library/skills/avoiding-generic-ai-design/references/tells.md +112 -112
  29. package/library/skills/clean-commits/SKILL.md +85 -85
  30. package/library/skills/design-review/SKILL.md +107 -107
  31. package/library/skills/design-review/references/critique-passes.md +101 -101
  32. package/library/skills/design-review/references/screenshot-procedure.md +121 -121
  33. package/library/skills/differential-security-review/LICENSE +427 -427
  34. package/library/skills/differential-security-review/SKILL.md +105 -105
  35. package/library/skills/differential-security-review/references/adversarial.md +115 -115
  36. package/library/skills/differential-security-review/references/methodology.md +145 -145
  37. package/library/skills/differential-security-review/references/patterns.md +108 -108
  38. package/library/skills/false-positive-check/LICENSE +427 -427
  39. package/library/skills/false-positive-check/SKILL.md +95 -95
  40. package/library/skills/false-positive-check/references/bug-class-verification.md +128 -128
  41. package/library/skills/false-positive-check/references/deep-verification.md +113 -113
  42. package/library/skills/false-positive-check/references/evidence-templates.md +93 -93
  43. package/library/skills/false-positive-check/references/false-positive-patterns.md +122 -122
  44. package/library/skills/false-positive-check/references/gate-reviews.md +36 -36
  45. package/library/skills/false-positive-check/references/standard-verification.md +80 -80
  46. package/library/skills/focused-implementation/SKILL.md +104 -104
  47. package/library/skills/implementation-plan/SKILL.md +66 -66
  48. package/library/skills/interface-design/SKILL.md +144 -144
  49. package/library/skills/interface-design/references/craft-defaults.md +130 -130
  50. package/library/skills/interface-design/references/new-direction.md +62 -62
  51. package/library/skills/interface-design/references/writing.md +52 -52
  52. package/library/skills/interface-polish/SKILL.md +103 -103
  53. package/library/skills/interface-polish/references/detail-rules.md +154 -154
  54. package/library/skills/interface-polish/references/worst-case-data.md +158 -158
  55. package/library/skills/motion-design/SKILL.md +106 -106
  56. package/library/skills/motion-design/references/recipes.md +243 -243
  57. package/library/skills/postgres-performance/SKILL.md +97 -97
  58. package/library/skills/postgres-performance/references/rules.md +265 -265
  59. package/library/skills/project-orientation/SKILL.md +77 -77
  60. package/library/skills/reviewing-changes/SKILL.md +183 -183
  61. package/library/skills/safe-database-changes/SKILL.md +111 -111
  62. package/library/skills/safe-database-changes/references/backfills.md +75 -75
  63. package/library/skills/safe-database-changes/references/migration-tools.md +69 -69
  64. package/library/skills/safe-database-changes/references/postgres-ddl.md +199 -199
  65. package/library/skills/security-review/SKILL.md +132 -132
  66. package/library/skills/security-review/references/checks-by-area.md +107 -107
  67. package/library/skills/security-review/references/do-not-report.md +86 -86
  68. package/library/skills/spec-writing/SKILL.md +144 -144
  69. package/library/skills/systematic-debugging/SKILL.md +130 -130
  70. package/library/skills/systematic-debugging/references/flaky-tests.md +51 -51
  71. package/library/skills/systematic-debugging/references/root-cause-tracing.md +55 -55
  72. package/library/skills/task-interview/SKILL.md +84 -84
  73. package/library/skills/test-driven-development/SKILL.md +116 -116
  74. package/library/skills/test-driven-development/references/writing-good-tests.md +85 -85
  75. package/library/skills/ui-testing/SKILL.md +102 -102
  76. package/library/skills/ui-testing/references/headless-check.md +295 -295
  77. package/library/skills/ui-testing/references/local-stand.md +51 -51
  78. package/library/skills/ui-testing/references/playwright-patterns.md +134 -134
  79. package/library/skills/ui-testing/references/recording.md +61 -61
  80. package/library/skills/verification-before-completion/SKILL.md +113 -113
  81. package/library/skills/web-interface-guidelines/SKILL.md +202 -202
  82. package/package.json +46 -46
@@ -1,105 +1,105 @@
1
- ---
2
- name: differential-security-review
3
- description: Use when a risky diff needs a deep security review against its base branch, such as auth or permission changes, removed validation, new external calls, money or data handling. Classifies risk per file, checks git history for regressions, counts callers for blast radius, checks tests on changed code, and builds concrete attack scenarios.
4
- ---
5
-
6
- # Differential security review
7
-
8
- Security review of a change, measured against what the code was before. Where `security-review` asks "is this code exploitable?", this skill adds "what did this change remove, whom does it affect, and has this bug been fixed here before?"
9
-
10
- Use it for pull requests and branches that touch authentication, authorization, cryptography, external calls, money or value transfer, or that remove validation. For a small change with no trust boundary, `security-review` alone is enough.
11
-
12
- ## Core principles
13
-
14
- 1. **Risk first.** Focus on auth, crypto, value transfer, external calls, validation.
15
- 2. **Evidence based.** Every finding is backed by line numbers, git history and a concrete attack scenario.
16
- 3. **Adaptive.** Scale depth to the codebase size and the risk.
17
- 4. **Honest.** State what you covered, what you did not, and your confidence.
18
- 5. **Read-only.** Never check out other commits, edit, commit, push or switch branches in the repository under review. Read old versions with `git show <ref>:<path>`. If you need a full old tree, add a detached worktree in a temp directory outside the repository (`git worktree add --detach <tmp> origin/<base>`) and remove it when done.
19
-
20
- ## Rationalizations to reject
21
-
22
- | Rationalization | Why it is wrong | Required action |
23
- |---|---|---|
24
- | "Small PR, quick review" | Heartbleed was 2 lines | Classify by risk, not size |
25
- | "I know this codebase" | Familiarity breeds blind spots | Build explicit baseline context |
26
- | "Git history takes too long" | History reveals regressions | Never skip phase 1 |
27
- | "Blast radius is obvious" | You will miss transitive callers | Count them |
28
- | "No tests = not my problem" | Missing tests mean higher risk | Flag it, raise the risk rating |
29
- | "Just a refactor, no security impact" | Refactors break invariants | Treat as HIGH until proven LOW |
30
- | "I will just summarise" | Findings without evidence get lost | Write the full report into the verdict |
31
-
32
- ## Quick reference
33
-
34
- **Codebase size strategy**
35
-
36
- | Codebase size | Strategy | Approach |
37
- |---|---|---|
38
- | Small (under 20 files) | Deep | Read all dependencies, full git blame |
39
- | Medium (20 to 200) | Focused | One hop of dependencies, priority files |
40
- | Large (over 200) | Surgical | Critical paths only |
41
-
42
- **Risk level per changed file**
43
-
44
- | Risk | Triggers |
45
- |---|---|
46
- | HIGH | Auth, crypto, external calls, value transfer, validation removal, permission changes |
47
- | MEDIUM | Business logic, state changes, new public APIs |
48
- | LOW | Comments, tests, UI text, logging |
49
-
50
- ## Workflow
51
-
52
- ```
53
- Phase 0: triage -> Phase 1: changed code -> Phase 2: test coverage -> Phase 3: blast radius
54
- -> Phase 4: deep context (HIGH risk) -> Phase 5: adversarial analysis (HIGH risk) -> Phase 6: report
55
- ```
56
-
57
- - Phases 0 to 4, with commands: [references/methodology.md](references/methodology.md). Read it at the start of every review.
58
- - Phase 5, attacker modelling and exploit scenarios: [references/adversarial.md](references/adversarial.md). Read it for every HIGH risk change.
59
- - Vulnerability patterns to check for in a diff: [references/patterns.md](references/patterns.md). Read it during phase 1.
60
-
61
- Before reporting any finding, verify it: apply the do-not-report rules of `security-review`, and run `false-positive-check` on each finding you would make blocking.
62
-
63
- ## Red flags (stop and investigate)
64
-
65
- These need adversarial analysis even in a quick triage:
66
-
67
- - Code removed that came from commits mentioning "security", "CVE", "fix" or "vulnerability".
68
- - Access control removed or loosened: a guard, decorator, middleware, policy or role check deleted; a private function made public.
69
- - Validation removed without replacement.
70
- - External calls added without checks on the response.
71
- - High blast radius (more than 50 callers) combined with a HIGH risk change.
72
-
73
- ## Phase 6: report
74
-
75
- The report goes into the verdict, not into a file in the repository. If a `submit_verdict` tool is available, that is how the result is returned: call it once, `passed: true` only if nothing blocks. Otherwise, or when you are a helper inside another step, put the report at the end of your reply. Sections:
76
-
77
- 1. **Summary.** Count by severity, overall risk, recommendation: approve (passed) or reject (failed).
78
- 2. **What changed.** Commit range, number of commits, a table of changed files with risk and blast radius.
79
- 3. **Findings**, highest first. For each: severity, file and line, commit, blast radius (number of callers), test coverage (yes, no, partial), what is wrong, historical context (when and why the removed code was added), the attack scenario, and the fix.
80
- 4. **Test coverage gaps** in changed code, with risk.
81
- 5. **Blast radius** of HIGH risk functions.
82
- 6. **Historical context:** security-related removals and regressions found.
83
- 7. **Method and limits:** strategy used, files analysed versus total, techniques applied, what was not analysed, confidence.
84
-
85
- What blocks (passed is false): any confirmed vulnerability with a concrete attack path (Critical or High, or Medium with confidence 8 or more), a regression of an earlier security fix, removed validation or access control without an equivalent replacement. Missing tests, high blast radius without a vulnerability, and hardening suggestions are notes that raise the risk rating but do not fail the check on their own.
86
-
87
- Never put secret values in the report: mask them. Never post the report to GitHub.
88
-
89
- ## Quality checklist
90
-
91
- - [ ] Every changed file was classified by risk and analysed at the depth its risk needs.
92
- - [ ] Git history was checked for every removal of security-relevant code.
93
- - [ ] Blast radius was counted for every HIGH risk change.
94
- - [ ] Attack scenarios are concrete: who, through which entry point, with which input, gaining what.
95
- - [ ] Findings cite file, line and commit.
96
- - [ ] Coverage limits and confidence are stated.
97
- - [ ] The repository is exactly as you found it (no checkouts, no temp files, worktree removed).
98
- - [ ] The verdict was returned once.
99
-
100
- ## When not to use
101
-
102
- - Greenfield code with no baseline to compare against: use `security-review`.
103
- - Documentation-only or formatting-only changes.
104
-
105
- Adapted from https://github.com/trailofbits/skills/tree/main/plugins/differential-review (commit 5c99c03fb8a9ea568432ecbcba5d86e9f4ac2bf0), by Trail of Bits (Omar Inuwa), CC BY-SA 4.0. Changed: rewritten for unattended read-only runs (no checkout of other commits, report returned through the verdict instead of a file, no user notification, no external skills or agents), added verdict mapping, removed time estimates and emoji, generalised examples beyond smart contracts. This skill folder, including its references, is licensed under CC BY-SA 4.0; see LICENSE.
1
+ ---
2
+ name: differential-security-review
3
+ description: Use when a risky diff needs a deep security review against its base branch, such as auth or permission changes, removed validation, new external calls, money or data handling. Classifies risk per file, checks git history for regressions, counts callers for blast radius, checks tests on changed code, and builds concrete attack scenarios.
4
+ ---
5
+
6
+ # Differential security review
7
+
8
+ Security review of a change, measured against what the code was before. Where `security-review` asks "is this code exploitable?", this skill adds "what did this change remove, whom does it affect, and has this bug been fixed here before?"
9
+
10
+ Use it for pull requests and branches that touch authentication, authorization, cryptography, external calls, money or value transfer, or that remove validation. For a small change with no trust boundary, `security-review` alone is enough.
11
+
12
+ ## Core principles
13
+
14
+ 1. **Risk first.** Focus on auth, crypto, value transfer, external calls, validation.
15
+ 2. **Evidence based.** Every finding is backed by line numbers, git history and a concrete attack scenario.
16
+ 3. **Adaptive.** Scale depth to the codebase size and the risk.
17
+ 4. **Honest.** State what you covered, what you did not, and your confidence.
18
+ 5. **Read-only.** Never check out other commits, edit, commit, push or switch branches in the repository under review. Read old versions with `git show <ref>:<path>`. If you need a full old tree, add a detached worktree in a temp directory outside the repository (`git worktree add --detach <tmp> origin/<base>`) and remove it when done.
19
+
20
+ ## Rationalizations to reject
21
+
22
+ | Rationalization | Why it is wrong | Required action |
23
+ |---|---|---|
24
+ | "Small PR, quick review" | Heartbleed was 2 lines | Classify by risk, not size |
25
+ | "I know this codebase" | Familiarity breeds blind spots | Build explicit baseline context |
26
+ | "Git history takes too long" | History reveals regressions | Never skip phase 1 |
27
+ | "Blast radius is obvious" | You will miss transitive callers | Count them |
28
+ | "No tests = not my problem" | Missing tests mean higher risk | Flag it, raise the risk rating |
29
+ | "Just a refactor, no security impact" | Refactors break invariants | Treat as HIGH until proven LOW |
30
+ | "I will just summarise" | Findings without evidence get lost | Write the full report into the verdict |
31
+
32
+ ## Quick reference
33
+
34
+ **Codebase size strategy**
35
+
36
+ | Codebase size | Strategy | Approach |
37
+ |---|---|---|
38
+ | Small (under 20 files) | Deep | Read all dependencies, full git blame |
39
+ | Medium (20 to 200) | Focused | One hop of dependencies, priority files |
40
+ | Large (over 200) | Surgical | Critical paths only |
41
+
42
+ **Risk level per changed file**
43
+
44
+ | Risk | Triggers |
45
+ |---|---|
46
+ | HIGH | Auth, crypto, external calls, value transfer, validation removal, permission changes |
47
+ | MEDIUM | Business logic, state changes, new public APIs |
48
+ | LOW | Comments, tests, UI text, logging |
49
+
50
+ ## Workflow
51
+
52
+ ```
53
+ Phase 0: triage -> Phase 1: changed code -> Phase 2: test coverage -> Phase 3: blast radius
54
+ -> Phase 4: deep context (HIGH risk) -> Phase 5: adversarial analysis (HIGH risk) -> Phase 6: report
55
+ ```
56
+
57
+ - Phases 0 to 4, with commands: [references/methodology.md](references/methodology.md). Read it at the start of every review.
58
+ - Phase 5, attacker modelling and exploit scenarios: [references/adversarial.md](references/adversarial.md). Read it for every HIGH risk change.
59
+ - Vulnerability patterns to check for in a diff: [references/patterns.md](references/patterns.md). Read it during phase 1.
60
+
61
+ Before reporting any finding, verify it: apply the do-not-report rules of `security-review`, and run `false-positive-check` on each finding you would make blocking.
62
+
63
+ ## Red flags (stop and investigate)
64
+
65
+ These need adversarial analysis even in a quick triage:
66
+
67
+ - Code removed that came from commits mentioning "security", "CVE", "fix" or "vulnerability".
68
+ - Access control removed or loosened: a guard, decorator, middleware, policy or role check deleted; a private function made public.
69
+ - Validation removed without replacement.
70
+ - External calls added without checks on the response.
71
+ - High blast radius (more than 50 callers) combined with a HIGH risk change.
72
+
73
+ ## Phase 6: report
74
+
75
+ The report goes into the verdict, not into a file in the repository. If a `submit_verdict` tool is available, that is how the result is returned: call it once, `passed: true` only if nothing blocks. Otherwise, or when you are a helper inside another step, put the report at the end of your reply. Sections:
76
+
77
+ 1. **Summary.** Count by severity, overall risk, recommendation: approve (passed) or reject (failed).
78
+ 2. **What changed.** Commit range, number of commits, a table of changed files with risk and blast radius.
79
+ 3. **Findings**, highest first. For each: severity, file and line, commit, blast radius (number of callers), test coverage (yes, no, partial), what is wrong, historical context (when and why the removed code was added), the attack scenario, and the fix.
80
+ 4. **Test coverage gaps** in changed code, with risk.
81
+ 5. **Blast radius** of HIGH risk functions.
82
+ 6. **Historical context:** security-related removals and regressions found.
83
+ 7. **Method and limits:** strategy used, files analysed versus total, techniques applied, what was not analysed, confidence.
84
+
85
+ What blocks (passed is false): any confirmed vulnerability with a concrete attack path (Critical or High, or Medium with confidence 8 or more), a regression of an earlier security fix, removed validation or access control without an equivalent replacement. Missing tests, high blast radius without a vulnerability, and hardening suggestions are notes that raise the risk rating but do not fail the check on their own.
86
+
87
+ Never put secret values in the report: mask them. Never post the report to GitHub.
88
+
89
+ ## Quality checklist
90
+
91
+ - [ ] Every changed file was classified by risk and analysed at the depth its risk needs.
92
+ - [ ] Git history was checked for every removal of security-relevant code.
93
+ - [ ] Blast radius was counted for every HIGH risk change.
94
+ - [ ] Attack scenarios are concrete: who, through which entry point, with which input, gaining what.
95
+ - [ ] Findings cite file, line and commit.
96
+ - [ ] Coverage limits and confidence are stated.
97
+ - [ ] The repository is exactly as you found it (no checkouts, no temp files, worktree removed).
98
+ - [ ] The verdict was returned once.
99
+
100
+ ## When not to use
101
+
102
+ - Greenfield code with no baseline to compare against: use `security-review`.
103
+ - Documentation-only or formatting-only changes.
104
+
105
+ Adapted from https://github.com/trailofbits/skills/tree/main/plugins/differential-review (commit 5c99c03fb8a9ea568432ecbcba5d86e9f4ac2bf0), by Trail of Bits (Omar Inuwa), CC BY-SA 4.0. Changed: rewritten for unattended read-only runs (no checkout of other commits, report returned through the verdict instead of a file, no user notification, no external skills or agents), added verdict mapping, removed time estimates and emoji, generalised examples beyond smart contracts. This skill folder, including its references, is licensed under CC BY-SA 4.0; see LICENSE.
@@ -1,115 +1,115 @@
1
- # Adversarial analysis (phase 5)
2
-
3
- Read after phase 4 for every HIGH risk change. The rule: concrete impact only, never "could cause issues". Every finding names the data exposed, the privilege gained, the money at risk or the invariant broken.
4
-
5
- Everything here is analysis on paper and reading code. Do not send requests to live services, and do not write files into the repository under review.
6
-
7
- ## 1. Define a specific attacker model
8
-
9
- **Who is the attacker?**
10
- - Unauthenticated visitor
11
- - Authenticated regular user
12
- - User of another tenant or organisation
13
- - Malicious or compromised administrator
14
- - Compromised upstream service, webhook sender or dependency
15
-
16
- **What access do they have?**
17
- - Public API only
18
- - An authenticated role
19
- - Specific permissions or tokens
20
- - Ability to send webhooks, queue messages or files
21
-
22
- **Where do they interact with the system?**
23
- - Specific HTTP endpoints, pages or forms
24
- - RPC, GraphQL or WebSocket interfaces
25
- - Jobs triggered by their input
26
- - External APIs the system calls on their behalf
27
-
28
- ## 2. Identify concrete attack vectors
29
-
30
- ```
31
- ENTRY POINT: <exact endpoint or function the attacker can reach>
32
-
33
- ATTACK SEQUENCE:
34
- 1. <specific request with parameters>
35
- 2. <how it reaches the vulnerable code, file:line>
36
- 3. <what happens in the vulnerable code>
37
- 4. <impact achieved>
38
-
39
- PROOF OF ACCESSIBILITY:
40
- - The entry point is exposed (route registered, no guard in front)
41
- - The attacker has the required permissions
42
- - The path exists through real interfaces, not only internal calls
43
- ```
44
-
45
- ## 3. Rate realistic exploitability
46
-
47
- **EASY:** through public or ordinary user APIs, no special privileges, a single request, no special conditions.
48
-
49
- **MEDIUM:** needs specific conditions or elevated but obtainable privileges: several steps, timing, a particular system state.
50
-
51
- **HARD:** needs admin privileges, rare conditions or significant resources.
52
-
53
- ## 4. Build the complete exploit scenario
54
-
55
- ```
56
- ATTACKER STARTING POSITION:
57
- <what the attacker has at the beginning>
58
-
59
- STEP-BY-STEP EXPLOITATION:
60
- Step 1: <concrete action through an accessible interface>
61
- - Request: <exact call>
62
- - Parameters: <specific values>
63
- - Result: <what happens>
64
- Step 2: <next action>
65
- - Why this works: <reference to the code change>
66
- - State change: <what changed>
67
- Step 3: <final impact>
68
- - Result: <concrete harm>
69
- - Evidence: <how to verify it from the code or a test>
70
-
71
- CONCRETE IMPACT:
72
- <specific and measurable: which records exposed, which privilege gained, how much money>
73
- ```
74
-
75
- ## 5. Cross-reference with the baseline
76
-
77
- From the baseline context in [methodology.md](methodology.md):
78
-
79
- - Does this violate a system-wide invariant?
80
- - Does it break a trust boundary?
81
- - Does it bypass a validation pattern used elsewhere?
82
- - Is it a regression of an earlier fix?
83
-
84
- ## Finding template
85
-
86
- ```
87
- [SEVERITY] <title>
88
-
89
- Attacker model:
90
- - WHO: <attacker type>
91
- - ACCESS: <privileges>
92
- - INTERFACE: <entry point>
93
-
94
- Attack vector: <step-by-step through accessible interfaces>
95
- Exploitability: EASY | MEDIUM | HARD, because <reason>
96
- Concrete impact: <specific harm>
97
- Proof of concept: <pseudocode or request sequence>
98
- Root cause: <file:line, commit>
99
- Blast radius: <N callers>
100
- Baseline violation: <invariant or pattern broken>
101
- ```
102
-
103
- ## Example
104
-
105
- **Change:** a refactor of the invoice routes moved handlers into a new router file. The old router applied `requireAccountMember` to the whole `/accounts/:accountId/*` group; the new file registers `GET /invoices/:id` without it and loads the invoice by id alone.
106
-
107
- 1. **Attacker model.** WHO: any authenticated user. ACCESS: an ordinary account. INTERFACE: `GET /invoices/:id`.
108
- 2. **Attack vector.** ENTRY POINT: `GET /invoices/:id`. SEQUENCE: log in with any account; request `/invoices/1001`, `/invoices/1002`, and so on; the handler calls `invoiceRepo.findById(id)` (src/invoices/routes.ts:24) with no account filter; the full invoice is returned. PROOF: the route is registered in src/app.ts:40 behind `requireLogin` only.
109
- 3. **Exploitability.** EASY: one request per invoice, ordinary user, ids are sequential integers.
110
- 4. **Impact.** Every invoice of every customer can be read: names, addresses, amounts, tax ids.
111
- 5. **Baseline violation.** Breaks the invariant "a user only sees data of accounts they belong to". `requireAccountMember` guards every other account resource (12 routes). Git history: the guard was added in commit 4f2a9c1, "Fix: invoices readable across accounts". This is a regression.
112
-
113
- Recommendation: register the route inside the account-scoped router, or add the guard and filter the query by account id; add a test that a member of account A gets 404 for an invoice of account B.
114
-
115
- Part of the `differential-security-review` skill, adapted from https://github.com/trailofbits/skills/tree/main/plugins/differential-review (commit 5c99c03fb8a9ea568432ecbcba5d86e9f4ac2bf0), CC BY-SA 4.0. Changed: attacker types and example rewritten for web applications, no live testing, no separate agent.
1
+ # Adversarial analysis (phase 5)
2
+
3
+ Read after phase 4 for every HIGH risk change. The rule: concrete impact only, never "could cause issues". Every finding names the data exposed, the privilege gained, the money at risk or the invariant broken.
4
+
5
+ Everything here is analysis on paper and reading code. Do not send requests to live services, and do not write files into the repository under review.
6
+
7
+ ## 1. Define a specific attacker model
8
+
9
+ **Who is the attacker?**
10
+ - Unauthenticated visitor
11
+ - Authenticated regular user
12
+ - User of another tenant or organisation
13
+ - Malicious or compromised administrator
14
+ - Compromised upstream service, webhook sender or dependency
15
+
16
+ **What access do they have?**
17
+ - Public API only
18
+ - An authenticated role
19
+ - Specific permissions or tokens
20
+ - Ability to send webhooks, queue messages or files
21
+
22
+ **Where do they interact with the system?**
23
+ - Specific HTTP endpoints, pages or forms
24
+ - RPC, GraphQL or WebSocket interfaces
25
+ - Jobs triggered by their input
26
+ - External APIs the system calls on their behalf
27
+
28
+ ## 2. Identify concrete attack vectors
29
+
30
+ ```
31
+ ENTRY POINT: <exact endpoint or function the attacker can reach>
32
+
33
+ ATTACK SEQUENCE:
34
+ 1. <specific request with parameters>
35
+ 2. <how it reaches the vulnerable code, file:line>
36
+ 3. <what happens in the vulnerable code>
37
+ 4. <impact achieved>
38
+
39
+ PROOF OF ACCESSIBILITY:
40
+ - The entry point is exposed (route registered, no guard in front)
41
+ - The attacker has the required permissions
42
+ - The path exists through real interfaces, not only internal calls
43
+ ```
44
+
45
+ ## 3. Rate realistic exploitability
46
+
47
+ **EASY:** through public or ordinary user APIs, no special privileges, a single request, no special conditions.
48
+
49
+ **MEDIUM:** needs specific conditions or elevated but obtainable privileges: several steps, timing, a particular system state.
50
+
51
+ **HARD:** needs admin privileges, rare conditions or significant resources.
52
+
53
+ ## 4. Build the complete exploit scenario
54
+
55
+ ```
56
+ ATTACKER STARTING POSITION:
57
+ <what the attacker has at the beginning>
58
+
59
+ STEP-BY-STEP EXPLOITATION:
60
+ Step 1: <concrete action through an accessible interface>
61
+ - Request: <exact call>
62
+ - Parameters: <specific values>
63
+ - Result: <what happens>
64
+ Step 2: <next action>
65
+ - Why this works: <reference to the code change>
66
+ - State change: <what changed>
67
+ Step 3: <final impact>
68
+ - Result: <concrete harm>
69
+ - Evidence: <how to verify it from the code or a test>
70
+
71
+ CONCRETE IMPACT:
72
+ <specific and measurable: which records exposed, which privilege gained, how much money>
73
+ ```
74
+
75
+ ## 5. Cross-reference with the baseline
76
+
77
+ From the baseline context in [methodology.md](methodology.md):
78
+
79
+ - Does this violate a system-wide invariant?
80
+ - Does it break a trust boundary?
81
+ - Does it bypass a validation pattern used elsewhere?
82
+ - Is it a regression of an earlier fix?
83
+
84
+ ## Finding template
85
+
86
+ ```
87
+ [SEVERITY] <title>
88
+
89
+ Attacker model:
90
+ - WHO: <attacker type>
91
+ - ACCESS: <privileges>
92
+ - INTERFACE: <entry point>
93
+
94
+ Attack vector: <step-by-step through accessible interfaces>
95
+ Exploitability: EASY | MEDIUM | HARD, because <reason>
96
+ Concrete impact: <specific harm>
97
+ Proof of concept: <pseudocode or request sequence>
98
+ Root cause: <file:line, commit>
99
+ Blast radius: <N callers>
100
+ Baseline violation: <invariant or pattern broken>
101
+ ```
102
+
103
+ ## Example
104
+
105
+ **Change:** a refactor of the invoice routes moved handlers into a new router file. The old router applied `requireAccountMember` to the whole `/accounts/:accountId/*` group; the new file registers `GET /invoices/:id` without it and loads the invoice by id alone.
106
+
107
+ 1. **Attacker model.** WHO: any authenticated user. ACCESS: an ordinary account. INTERFACE: `GET /invoices/:id`.
108
+ 2. **Attack vector.** ENTRY POINT: `GET /invoices/:id`. SEQUENCE: log in with any account; request `/invoices/1001`, `/invoices/1002`, and so on; the handler calls `invoiceRepo.findById(id)` (src/invoices/routes.ts:24) with no account filter; the full invoice is returned. PROOF: the route is registered in src/app.ts:40 behind `requireLogin` only.
109
+ 3. **Exploitability.** EASY: one request per invoice, ordinary user, ids are sequential integers.
110
+ 4. **Impact.** Every invoice of every customer can be read: names, addresses, amounts, tax ids.
111
+ 5. **Baseline violation.** Breaks the invariant "a user only sees data of accounts they belong to". `requireAccountMember` guards every other account resource (12 routes). Git history: the guard was added in commit 4f2a9c1, "Fix: invoices readable across accounts". This is a regression.
112
+
113
+ Recommendation: register the route inside the account-scoped router, or add the guard and filter the query by account id; add a test that a member of account A gets 404 for an invoice of account B.
114
+
115
+ Part of the `differential-security-review` skill, adapted from https://github.com/trailofbits/skills/tree/main/plugins/differential-review (commit 5c99c03fb8a9ea568432ecbcba5d86e9f4ac2bf0), CC BY-SA 4.0. Changed: attacker types and example rewritten for web applications, no live testing, no separate agent.