@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4

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 (112) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/README.md +8 -0
  3. package/commands/pentest.md +5 -0
  4. package/package.json +8 -3
  5. package/skills/analyzing-tls-config/SKILL.md +221 -0
  6. package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
  7. package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
  8. package/skills/analyzing-tls-config/references/THEORY.md +128 -0
  9. package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
  10. package/skills/auditing-cors-policy/SKILL.md +186 -0
  11. package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
  12. package/skills/auditing-cors-policy/references/THEORY.md +142 -0
  13. package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
  14. package/skills/auditing-npm-dependencies/SKILL.md +254 -0
  15. package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
  16. package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
  17. package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
  18. package/skills/auditing-python-dependencies/SKILL.md +251 -0
  19. package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
  20. package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
  21. package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
  22. package/skills/checking-http-security-headers/SKILL.md +176 -0
  23. package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
  24. package/skills/checking-http-security-headers/references/THEORY.md +137 -0
  25. package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
  26. package/skills/checking-license-compliance/SKILL.md +225 -0
  27. package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
  28. package/skills/checking-license-compliance/references/THEORY.md +152 -0
  29. package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
  30. package/skills/composing-vulnerability-report/SKILL.md +212 -0
  31. package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
  32. package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
  33. package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
  34. package/skills/confirming-pentest-authorization/SKILL.md +247 -0
  35. package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
  36. package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
  37. package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
  38. package/skills/defining-pentest-scope/SKILL.md +227 -0
  39. package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
  40. package/skills/defining-pentest-scope/references/THEORY.md +170 -0
  41. package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
  42. package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
  43. package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
  44. package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
  45. package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
  46. package/skills/detecting-debug-endpoints/SKILL.md +207 -0
  47. package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
  48. package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
  49. package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
  50. package/skills/detecting-directory-listing/SKILL.md +206 -0
  51. package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
  52. package/skills/detecting-directory-listing/references/THEORY.md +203 -0
  53. package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
  54. package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
  55. package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
  56. package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
  57. package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
  58. package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
  59. package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
  60. package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
  61. package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
  62. package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
  63. package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
  64. package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
  65. package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
  66. package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
  67. package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
  68. package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
  69. package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
  70. package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
  71. package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
  72. package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
  73. package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
  74. package/skills/detecting-weak-cryptography/SKILL.md +147 -0
  75. package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
  76. package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
  77. package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
  78. package/skills/fingerprinting-server-software/SKILL.md +191 -0
  79. package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
  80. package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
  81. package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
  82. package/skills/generating-executive-summary/SKILL.md +261 -0
  83. package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
  84. package/skills/generating-executive-summary/references/THEORY.md +195 -0
  85. package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
  86. package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
  87. package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
  88. package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
  89. package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
  90. package/skills/performing-penetration-testing/SKILL.md +282 -190
  91. package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
  92. package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
  93. package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
  94. package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
  95. package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
  96. package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
  97. package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
  98. package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
  99. package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
  100. package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
  101. package/skills/recording-pentest-engagement/SKILL.md +253 -0
  102. package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
  103. package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
  104. package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
  105. package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
  106. package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
  107. package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
  108. package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
  109. package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
  110. package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
  111. package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
  112. package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: mapping-findings-to-owasp-top10
3
+ description: |
4
+ Annotate every pentest finding with its OWASP Top 10 (2021)
5
+ category by applying a deterministic rule table keyed on source
6
+ skill, finding category, detail keywords, and CWE identifier when
7
+ present. Produces an enriched findings JSONL plus a per-category
8
+ rollup report showing how findings distribute across A01 through
9
+ A10. Required for customer-facing OWASP coverage sections and
10
+ compliance contexts (PCI DSS 6.5, SOC2 CC7, ISO 27001 A.14.2).
11
+ Use when: enriching findings after cluster 1-4 scans, regenerating
12
+ the report with OWASP tags, producing the OWASP coverage section
13
+ for an exec summary, or auditing engagement OWASP coverage.
14
+ Threshold: unclassifiable findings emitted as INFO with UNMAPPED
15
+ category for operator review.
16
+ Trigger with: "map to OWASP", "owasp top 10 mapping",
17
+ "annotate owasp categories", "owasp coverage check".
18
+ allowed-tools:
19
+ - Read
20
+ - Write
21
+ - Bash(python3:*)
22
+ - Glob
23
+ disallowed-tools:
24
+ - Bash(rm:*)
25
+ - Bash(curl:*)
26
+ - Bash(wget:*)
27
+ - Write(.env)
28
+ - Edit(.env)
29
+ version: 3.0.0-dev
30
+ author: Jeremy Longshore <jeremy@intentsolutions.io>
31
+ license: MIT
32
+ compatibility: Designed for Claude Code
33
+ tags:
34
+ - security
35
+ - reporting
36
+ - owasp
37
+ - top10
38
+ - pentest
39
+ ---
40
+
41
+ # Mapping Findings to OWASP Top 10
42
+
43
+ ## Overview
44
+
45
+ OWASP Top 10 is the canonical taxonomy of web-application risk
46
+ categories. Every customer-facing pentest report has an "OWASP
47
+ coverage" section because customers, auditors, and insurers
48
+ expect to see findings mapped against the Top 10. Without the
49
+ mapping, a long list of CVEs and misconfigurations reads as
50
+ noise; with the mapping, it reads as a structured assessment.
51
+
52
+ This skill applies a deterministic rule table to annotate each
53
+ finding with its OWASP category. Rules are keyed on:
54
+
55
+ 1. **Source skill ID** (a finding from `auditing-npm-dependencies`
56
+ is almost always A06 — Vulnerable and Outdated Components).
57
+ 2. **Finding category** (the per-skill category tag, e.g.
58
+ `dependency-vulnerability`, `engagement-scope`).
59
+ 3. **CWE identifier** if present (CWE → OWASP is a well-trodden
60
+ mapping; OWASP themselves publish the cross-walk).
61
+ 4. **Detail keywords** as a fallback when the above don't
62
+ determine a category.
63
+
64
+ Output is an enriched JSONL (each finding gets an `owasp_category`
65
+ field) plus a coverage report showing how the engagement's
66
+ findings distribute across A01-A10. UNMAPPED findings are
67
+ surfaced for human review — extend the rule table or accept the
68
+ finding as cross-cutting (some findings genuinely don't fit a
69
+ single A0X bucket).
70
+
71
+ ## When the skill produces findings
72
+
73
+ | Finding | Severity | Threshold | Affected control |
74
+ |---|---|---|---|
75
+ | Finding unmapped after rule application | **INFO** | No rule matched the finding | (operational) |
76
+ | Source JSONL unparseable | **HIGH** | Standard JSONL parse error | (operational) |
77
+ | Annotation written back successfully | **INFO** | Confirmation per source file | (informational) |
78
+ | Coverage report generated | **INFO** | Coverage report path emitted | (informational) |
79
+ | Engagement covers all 10 categories | **INFO** | At least one finding in each A01-A10 bucket | (positive observation) |
80
+ | Engagement covers <5 of 10 categories | **MEDIUM** | Suggests scope may have been narrow | (informational) |
81
+
82
+ ## OWASP Top 10 (2021) reference
83
+
84
+ | Category | Description |
85
+ |---|---|
86
+ | A01:2021 | Broken Access Control |
87
+ | A02:2021 | Cryptographic Failures |
88
+ | A03:2021 | Injection |
89
+ | A04:2021 | Insecure Design |
90
+ | A05:2021 | Security Misconfiguration |
91
+ | A06:2021 | Vulnerable and Outdated Components |
92
+ | A07:2021 | Identification and Authentication Failures |
93
+ | A08:2021 | Software and Data Integrity Failures |
94
+ | A09:2021 | Security Logging and Monitoring Failures |
95
+ | A10:2021 | Server-Side Request Forgery |
96
+
97
+ ## Prerequisites
98
+
99
+ - Python 3.9+
100
+ - One or more cluster 1-4 findings files
101
+ - Optional `.owasp-overrides.yaml` for engagement-specific
102
+ classification rules
103
+
104
+ ## Instructions
105
+
106
+ ### Step 1 — Identify findings sources
107
+
108
+ Default: every file under `engagement/findings/*.json[l]`.
109
+ Override with `--source FILE` (repeatable).
110
+
111
+ ### Step 2 — Run the mapper
112
+
113
+ ```bash
114
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/
115
+ ```
116
+
117
+ Options:
118
+
119
+ ```
120
+ Usage: map_owasp.py PATH [OPTIONS]
121
+
122
+ Options:
123
+ --source FILE Specific findings file (repeatable)
124
+ --enrich-output FILE Write annotated findings JSONL here
125
+ (default: PATH/findings/all-with-owasp.jsonl)
126
+ --coverage-output FILE Coverage report path
127
+ (default: PATH/reports/owasp-coverage.md)
128
+ --overrides FILE Optional rule-overrides YAML
129
+ --output FILE Operational findings output
130
+ --format FMT json | jsonl | markdown (default: markdown)
131
+ --min-severity SEV default info
132
+ ```
133
+
134
+ ### Step 3 — Review unmapped findings
135
+
136
+ UNMAPPED findings are surfaced as INFO. For each:
137
+
138
+ 1. Check whether a CWE was present; if so, the canonical CWE →
139
+ OWASP cross-walk should have caught it. Extend the rule table.
140
+ 2. Check whether the finding's source skill ID is in the rule
141
+ table; if not, add a skill-level default.
142
+ 3. If the finding genuinely doesn't fit a single A0X bucket,
143
+ accept UNMAPPED and document in the engagement notes.
144
+
145
+ ### Step 4 — Read the coverage report
146
+
147
+ The coverage report lists each A0X category with:
148
+
149
+ - Count of findings mapped to that category
150
+ - Severity breakdown within the category
151
+ - Pointer to specific findings
152
+
153
+ For an engagement intended as broad-coverage testing, all ten
154
+ categories should have at least one entry. Categories with zero
155
+ findings either reflect scope ("we didn't test for this") or
156
+ clean results ("we tested and found nothing").
157
+
158
+ ## Examples
159
+
160
+ ### Example 1 — End-of-engagement enrichment
161
+
162
+ ```bash
163
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/
164
+ ```
165
+
166
+ Produces `engagements/acme-2026-q2/findings/all-with-owasp.jsonl`
167
+ (enriched findings) and `engagements/acme-2026-q2/reports/owasp-coverage.md`
168
+ (coverage report).
169
+
170
+ ### Example 2 — Apply engagement-specific overrides
171
+
172
+ ```yaml
173
+ # .owasp-overrides.yaml — engagement-specific classifications
174
+ - skill_id: auditing-cors-policy
175
+ owasp_category: A05:2021 — Security Misconfiguration
176
+ reason: customer treats CORS as misconfig, not access-control
177
+ - skill_id: scanning-for-hardcoded-secrets
178
+ detail_contains: ".env"
179
+ owasp_category: A02:2021 — Cryptographic Failures
180
+ reason: env-file leaks treated as crypto failure for this engagement
181
+ ```
182
+
183
+ ```bash
184
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/ \
185
+ --overrides engagements/acme-2026-q2/.owasp-overrides.yaml
186
+ ```
187
+
188
+ ### Example 3 — Coverage audit (no enrichment write-back)
189
+
190
+ ```bash
191
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/ \
192
+ --enrich-output /dev/null \
193
+ --coverage-output /tmp/coverage.md
194
+ ```
195
+
196
+ Produces the coverage report without modifying findings files.
197
+
198
+ ## Output
199
+
200
+ JSON / JSONL / Markdown per `lib/report.py` for operational
201
+ findings. PRIMARY outputs:
202
+
203
+ 1. **Enriched findings JSONL** at `--enrich-output` — every
204
+ finding from the sources has an `owasp_category` field added.
205
+ 2. **Coverage report markdown** at `--coverage-output` — per-
206
+ category rollup.
207
+
208
+ Each operational Finding includes:
209
+
210
+ - `id` — `owasp::<issue>::<finding-fingerprint>`
211
+ - `severity` — INFO mostly; HIGH for parse errors
212
+ - `category` — `owasp-mapping`
213
+ - `summary` — what happened to the finding
214
+ - `evidence` — original finding fingerprint, derived OWASP
215
+ category, rule that matched
216
+
217
+ ## Error Handling
218
+
219
+ - **PATH missing** → CRITICAL operational finding, exits 1.
220
+ - **Source file unparseable** → HIGH op finding, skip file.
221
+ - **No sources found** → HIGH op finding, exits 1.
222
+ - **Override YAML unparseable** → HIGH op finding, falls back to
223
+ default rules.
224
+ - **Enriched output path not writable** → HIGH op finding, exits 1.
225
+
226
+ ## Resources
227
+
228
+ - `references/THEORY.md` — OWASP Top 10 history and 2021 changes,
229
+ CWE → OWASP cross-walk, rule-table design rationale, when a
230
+ finding genuinely doesn't fit, OWASP A0X precision tradeoffs
231
+ (broad categories vs specific findings)
232
+ - `references/PLAYBOOK.md` — Default rule table per cluster 1-4
233
+ skill, override YAML format, coverage-audit interpretation,
234
+ customer-specific category preferences, integration with
235
+ PCI DSS 6.5 / NIST 800-53 control mapping
@@ -0,0 +1,193 @@
1
+ # PLAYBOOK — Mapping Rules and Workflow
2
+
3
+ ## Default skill → OWASP mappings (reference table)
4
+
5
+ | Cluster | Skill | OWASP | Reason |
6
+ |---|---|---|---|
7
+ | 1 | analyzing-tls-config | A02 | Cryptographic Failures |
8
+ | 1 | detecting-ssl-cert-issues | A02 | Cryptographic Failures |
9
+ | 1 | auditing-cors-policy | A01 | Broken Access Control |
10
+ | 1 | checking-http-security-headers | A05 | Security Misconfiguration |
11
+ | 1 | probing-dangerous-http-methods | A05 | Security Misconfiguration |
12
+ | 2 | detecting-exposed-secrets-files | A02 | Cryptographic Failures (.env, .git exposures) |
13
+ | 2 | detecting-debug-endpoints | A05 | Misconfiguration |
14
+ | 2 | fingerprinting-server-software | A06 | Outdated components signal |
15
+ | 2 | detecting-directory-listing | A05 | Misconfiguration |
16
+ | 3 | scanning-for-hardcoded-secrets | A02 | Hardcoded credentials |
17
+ | 3 | detecting-sql-injection-patterns | A03 | Injection |
18
+ | 3 | detecting-command-injection-patterns | A03 | Injection |
19
+ | 3 | detecting-eval-exec-usage | A03 | Injection (code execution) |
20
+ | 3 | detecting-insecure-deserialization | A08 | Integrity Failures |
21
+ | 3 | detecting-weak-cryptography | A02 | Crypto failures |
22
+ | 4 | auditing-npm-dependencies | A06 | Vulnerable Components |
23
+ | 4 | auditing-python-dependencies | A06 | Vulnerable Components |
24
+ | 4 | checking-license-compliance | A06 | Components hygiene |
25
+ | 4 | tracing-transitive-vulnerabilities | A06 | Vulnerable Components |
26
+ | 5 | confirming-pentest-authorization | A04 | Insecure Design |
27
+ | 5 | defining-pentest-scope | A04 | Insecure Design |
28
+ | 5 | recording-pentest-engagement | A09 | Logging / Monitoring |
29
+
30
+ Cluster 5 (governance) findings aren't technical application
31
+ vulnerabilities; the A04 / A09 mapping is for COVERAGE-REPORTING
32
+ purposes (so engagement-governance findings show up somewhere
33
+ in the OWASP narrative rather than being invisible).
34
+
35
+ ## Overrides YAML format
36
+
37
+ ```yaml
38
+ # .owasp-overrides.yaml
39
+ - skill_id: auditing-cors-policy
40
+ owasp_category: A05:2021 — Security Misconfiguration
41
+ reason: customer treats CORS as misconfig, not access-control
42
+
43
+ - skill_id: scanning-for-hardcoded-secrets
44
+ detail_contains: ".env"
45
+ owasp_category: A02:2021 — Cryptographic Failures
46
+ reason: .env leaks treated as crypto failure for this customer
47
+
48
+ - skill_id: tracing-transitive-vulnerabilities
49
+ detail_contains: "deep"
50
+ owasp_category: A08:2021 — Software and Data Integrity Failures
51
+ reason: deep-transitive vulns treated as integrity concern for this customer
52
+ ```
53
+
54
+ An override applies when:
55
+
56
+ - `skill_id` matches AND
57
+ - `detail_contains` matches (if specified — substring match)
58
+
59
+ The `owasp_category` must be one of the canonical strings (e.g.
60
+ "A05:2021 — Security Misconfiguration"). The skill parses the
61
+ leading code (`A05`) for table lookup.
62
+
63
+ Add a `reason` field on every override. Reasons become part of
64
+ the engagement archive's audit trail.
65
+
66
+ ## Coverage-report interpretation
67
+
68
+ ### "All 10 categories covered"
69
+
70
+ Customer report's OWASP section can claim "the engagement evaluated
71
+ all 10 OWASP Top 10 categories." This is the strongest possible
72
+ coverage claim and what most customers want.
73
+
74
+ ### "8 of 10 categories covered"
75
+
76
+ Customer report should explicitly note which categories had no
77
+ findings AND whether each "no findings" reflects clean results
78
+ or out-of-scope testing. Phrasing template:
79
+
80
+ > The engagement covered 8 of the 10 OWASP Top 10 (2021)
81
+ > categories. A04 (Insecure Design) and A10 (Server-Side Request
82
+ > Forgery) had no findings within this engagement's scope.
83
+
84
+ ### "3 of 10 categories covered"
85
+
86
+ Either a deliberately narrow scope or a rule-table coverage gap.
87
+ Investigate before shipping the report:
88
+
89
+ 1. Check the unmapped findings list. Are findings falling into the
90
+ "no rule matched" bucket?
91
+ 2. Check the scope. Did the engagement explicitly include only
92
+ network testing (which would naturally cover A02 + A05 + A06)?
93
+ 3. If the narrow coverage is intentional, document it in the
94
+ engagement summary's scope section.
95
+
96
+ ## Per-customer category-emphasis patterns
97
+
98
+ ### PCI DSS customers
99
+
100
+ PCI DSS Req 6.5 lists specific vulnerability classes that must be
101
+ addressed. The skill's standard A0X mapping covers most of these.
102
+ Recommend including a "PCI DSS Req 6.5 coverage" section in the
103
+ report that cross-references A0X findings to specific Req 6.5
104
+ items. Out of scope for this skill (separate mapping).
105
+
106
+ ### HIPAA customers
107
+
108
+ A02 (Crypto) and A09 (Logging) get the most scrutiny. Recommend
109
+ running A02 + A09 specifically (auditing-tls-config + checking
110
+ for security logging + monitoring failures) regardless of
111
+ broader scope.
112
+
113
+ ### SOC2 customers
114
+
115
+ CC7 (System Operations) maps loosely to A06 + A09. CC8 (Change
116
+ Management) maps to A04 + A08. The full coverage report supports
117
+ the SOC2 audit narrative.
118
+
119
+ ### ISO 27001 customers
120
+
121
+ Annex A.14.2 (Security in Development) maps to A04 + A08. Annex
122
+ A.12.6 (Vulnerability Management) maps to A06. The full coverage
123
+ report supports the ISO 27001 audit narrative.
124
+
125
+ ## Workflow patterns
126
+
127
+ ### Standalone enrichment
128
+
129
+ ```bash
130
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/
131
+ ```
132
+
133
+ Enriched JSONL at `findings/all-with-owasp.jsonl`.
134
+ Coverage report at `reports/owasp-coverage.md`.
135
+
136
+ ### Enrichment with overrides
137
+
138
+ ```bash
139
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/ \
140
+ --overrides engagements/acme-2026-q2/.owasp-overrides.yaml
141
+ ```
142
+
143
+ ### Coverage audit only (no enrichment)
144
+
145
+ ```bash
146
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/ \
147
+ --enrich-output /dev/null \
148
+ --coverage-output /tmp/coverage.md
149
+ ```
150
+
151
+ ### Re-compose vulnerability report after enrichment
152
+
153
+ ```bash
154
+ # Step 1: enrich
155
+ python3 ./scripts/map_owasp.py engagements/acme-2026-q2/
156
+
157
+ # Step 2: re-compose report from enriched findings
158
+ python3 plugins/security/penetration-tester/skills/composing-vulnerability-report/scripts/compose_report.py \
159
+ engagements/acme-2026-q2/ \
160
+ --source engagements/acme-2026-q2/findings/all-with-owasp.jsonl \
161
+ --report-output engagements/acme-2026-q2/reports/vulnerability-report-v2.md
162
+ ```
163
+
164
+ ## When to extend the rule table
165
+
166
+ Add a new entry to `SKILL_TO_OWASP` when:
167
+
168
+ - A new cluster 1-4 skill is added to the pack.
169
+ - A skill's default classification proves consistently wrong in
170
+ practice.
171
+ - A new CWE → OWASP mapping is needed (extend `CWE_TO_OWASP`).
172
+
173
+ Add a new entry to `DETAIL_KEYWORDS` when:
174
+
175
+ - An UNMAPPED-finding pattern is recognizable by detail keywords
176
+ that no current rule catches.
177
+ - A detail-keyword rule is sometimes a useful fallback for
178
+ third-party tools whose output passes through this skill.
179
+
180
+ Don't add overrides as rule-table extensions — overrides are
181
+ engagement-specific by design. Rule-table changes are global.
182
+
183
+ ## Integration with executive-summary
184
+
185
+ The exec-summary skill consumes the enriched findings JSONL plus
186
+ the coverage report. The exec summary's "OWASP coverage" section
187
+ quotes per-category counts from the coverage report and risk
188
+ score from the unified findings.
189
+
190
+ Order of operations: cluster 1-4 → this skill → exec summary.
191
+ Optionally re-run compose-vulnerability-report between this skill
192
+ and exec-summary so the OWASP tags appear in the main report's
193
+ per-finding sections.
@@ -0,0 +1,160 @@
1
+ # THEORY — OWASP Top 10 Mapping
2
+
3
+ ## What the OWASP Top 10 actually is
4
+
5
+ The OWASP Top 10 is a community-curated list of the most critical
6
+ web application security risks, updated every 3-4 years. The
7
+ current version is the 2021 edition. The Top 10 is NOT a complete
8
+ taxonomy of all possible vulnerabilities — it's a prioritization
9
+ framework. Findings outside the Top 10 still matter; they just
10
+ don't get their own A0X slot.
11
+
12
+ The 2021 edition's categories (with their derivation from 2017
13
+ predecessors):
14
+
15
+ | 2021 | Notes |
16
+ |---|---|
17
+ | A01 Broken Access Control | Promoted from A05 (2017); broadest category, includes path traversal + IDOR |
18
+ | A02 Cryptographic Failures | Renamed from A03 "Sensitive Data Exposure"; emphasizes the failure modes not the data |
19
+ | A03 Injection | Demoted from A01 (2017); XSS folded in here |
20
+ | A04 Insecure Design | NEW; threat-modeling-failure findings |
21
+ | A05 Security Misconfiguration | Includes XML External Entities (was A04 in 2017) |
22
+ | A06 Vulnerable and Outdated Components | Promoted from A09 (2017) |
23
+ | A07 Identification and Authentication Failures | Renamed from A02 "Broken Authentication" |
24
+ | A08 Software and Data Integrity Failures | NEW; supply-chain-attack-shaped |
25
+ | A09 Security Logging and Monitoring Failures | Renamed from A10 (2017) |
26
+ | A10 Server-Side Request Forgery | NEW as a Top 10 entry |
27
+
28
+ The 2025 edition is in draft as of this skill's authorship. When
29
+ it ships, this skill's mapping table should be reviewed against
30
+ the new category set.
31
+
32
+ ## CWE → OWASP cross-walk
33
+
34
+ OWASP publishes an authoritative mapping from CWE identifiers to
35
+ OWASP categories at https://owasp.org/Top10/A0X_2021-<name>/. The
36
+ mapping is one-to-many in both directions: a single CWE can map
37
+ to multiple OWASP categories depending on context, and a single
38
+ OWASP category encompasses many CWEs.
39
+
40
+ This skill's `CWE_TO_OWASP` table captures the most common
41
+ mappings deterministically. Edge cases:
42
+
43
+ - CWE-200 (Information Exposure) — typically A01 but can map to
44
+ A05 or A09 depending on context.
45
+ - CWE-352 (CSRF) — included in A01 in 2021 (was A08 in 2017).
46
+ - CWE-89 (SQL Injection) — A03, no ambiguity.
47
+
48
+ When a CWE has multiple plausible mappings, the skill picks the
49
+ most common one in practice. Override via the engagement-specific
50
+ overrides YAML for cases where the customer expects a different
51
+ classification.
52
+
53
+ ## Why deterministic rules, not LLM classification
54
+
55
+ It's tempting to feed each finding to an LLM and ask "which OWASP
56
+ category fits best?" Two problems:
57
+
58
+ 1. **Reproducibility.** A pentest report claims to be the result
59
+ of a defined methodology. An LLM-classified report changes
60
+ slightly on every regeneration (model temperature, prompt
61
+ variation, training-data drift). Auditors hate this.
62
+
63
+ 2. **Explainability.** A finding's mapping needs a defensible
64
+ reason ("this is A06 because the source skill is
65
+ `auditing-npm-dependencies` which detects vulnerable
66
+ third-party components" is defensible; "the LLM said so" is
67
+ not).
68
+
69
+ The skill uses a deterministic rule table. Rules are auditable.
70
+ The classifier can be wrong, but it's wrong consistently — and
71
+ the operator can extend the table to fix patterns.
72
+
73
+ ## Rule precedence
74
+
75
+ The skill applies rules in this order:
76
+
77
+ 1. **Engagement-specific overrides** (from `--overrides FILE`).
78
+ Highest precedence; lets customers express their own
79
+ classification preferences.
80
+ 2. **CWE-based mapping** when the finding has a `cwe_id`.
81
+ 3. **Skill-ID default** when no CWE is present or matches.
82
+ 4. **Detail-keyword fallback** as a last-resort heuristic.
83
+
84
+ Each successful classification records WHICH rule matched in the
85
+ operational Finding. Operators can see the reasoning chain when
86
+ debugging unexpected classifications.
87
+
88
+ ## Coverage interpretation
89
+
90
+ The coverage report shows count per A0X category. Interpretation:
91
+
92
+ | Pattern | What it usually means |
93
+ |---|---|
94
+ | All 10 categories have findings | Broad-coverage engagement, comprehensive scope |
95
+ | 6-9 categories | Typical engagement; some categories not in scope |
96
+ | 1-5 categories | Narrow scope OR rule table missed mappings |
97
+ | 0 categories with HIGH/CRITICAL | Either remarkably clean target OR scans didn't run |
98
+
99
+ The skill flags fewer-than-5 categories as MEDIUM. The operator
100
+ should determine whether the narrow coverage is intentional (and
101
+ document so) or a sign of incomplete testing.
102
+
103
+ ## When a finding genuinely doesn't fit a single category
104
+
105
+ Some findings are cross-cutting:
106
+
107
+ - A misconfigured database cluster (A05 Misconfiguration + A09
108
+ Logging + A02 Crypto-at-rest) — could legitimately appear in
109
+ three categories.
110
+ - A supply-chain compromise (A06 Components + A08 Software Integrity)
111
+ — both apply.
112
+ - An authentication bypass via path traversal (A07 + A01).
113
+
114
+ The Top 10 doesn't tolerate multi-category findings. The convention
115
+ is to pick the PRIMARY category (the failure mode that most
116
+ directly causes exploitation) and accept that the finding will be
117
+ reported under one A0X bucket. Cross-references in the report body
118
+ can point to the secondary category.
119
+
120
+ ## Customer-specific category preferences
121
+
122
+ Some customers care about specific A0X categories for compliance
123
+ reasons:
124
+
125
+ - **PCI DSS** customers care about A02 (Crypto) and A07 (Auth).
126
+ - **Healthcare (HIPAA)** customers care about A02 + A09 (Logging).
127
+ - **SOC2 CC7** customers want broad coverage across all categories.
128
+
129
+ The skill's overrides YAML is the mechanism for capturing these
130
+ preferences. An override re-classifies a finding's category for
131
+ the specific engagement without changing the default rule table.
132
+
133
+ ## OWASP Top 10 vs ASVS
134
+
135
+ The OWASP Application Security Verification Standard (ASVS) is a
136
+ much more granular framework — 286 verification requirements across
137
+ 14 chapters. Some engagements demand ASVS coverage instead of (or
138
+ in addition to) Top 10 coverage. This skill maps Top 10 only;
139
+ ASVS mapping would be a separate skill (or extension to this one)
140
+ because the rule table is differently shaped.
141
+
142
+ ## Mapping precision tradeoffs
143
+
144
+ The skill optimizes for:
145
+
146
+ - **Coverage** — every finding gets a mapping if at all possible.
147
+ - **Reproducibility** — same input → same output, always.
148
+ - **Auditability** — the rule that matched is recorded.
149
+ - **Extensibility** — operators can add overrides without code changes.
150
+
151
+ It does NOT optimize for:
152
+
153
+ - **Per-finding precision** — a finding might fit two categories;
154
+ the skill picks one deterministically.
155
+ - **2025-edition forward compatibility** — when OWASP 2025
156
+ finalizes, the table needs review.
157
+ - **ASVS coverage** — out of scope.
158
+
159
+ These tradeoffs are deliberate. The skill is a triage tool, not a
160
+ substitute for human judgment on contested classifications.