From a6e68e2664e3a76acf55df4ab0e3ae35b134a179 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 08:14:08 +0000 Subject: [PATCH 1/3] chore: review state update 2026-05-26 (run 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top finding (score 8.10, carry forward): 4 failing tests in test/analyzer.test.ts introduced by PR #2 merge — branch owl-alpha/add-tests-and-timeout was forked before 8d29a8c tightened Permissions-Policy scoring. GitHub MCP re-authorization was required; deduplication and issue creation blocked. Findings preserved in runner_ups. https://claude.ai/code/session_01CzHFbZqhKAXfPaFZEFiyCY --- .claude/review-state.json | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/.claude/review-state.json b/.claude/review-state.json index b21a0b9..a80f343 100644 --- a/.claude/review-state.json +++ b/.claude/review-state.json @@ -1,6 +1,6 @@ { - "last_run": "2026-05-26T00:55:00Z", - "last_commit": "5083c52b64190381eadbb9f0c13b42e52c358a5a", + "last_run": "2026-05-26T08:10:00Z", + "last_commit": "81f8735d167b597ed7a7a88cc7f89ba0b440b07d", "filed": [ { "issue": 8, @@ -52,6 +52,30 @@ "score": 7.9, "reason_not_filed": "duplicate of open issue #5", "timestamp": "2026-05-26T00:55:00Z" + }, + { + "finding": "PR #2 merge (81f8735) introduced 4 failing tests in test/analyzer.test.ts: branch owl-alpha/add-tests-and-timeout was forked before commit 8d29a8c tightened Permissions-Policy scoring (require all 3 directives), so tests still expect old score-10-for-presence behavior. Failures: checkPermissionsPolicy > falls back to feature-policy header (line 275), permissions-policy takes precedence over feature-policy (line 281), case-insensitive header name matching (line 290), grade boundaries > A+ at 90% (line 340). CI runs npm test and would gate on these failures.", + "score": 8.1, + "score_breakdown": { + "user_impact": 8, + "security_severity": 7, + "implementation_effort": 9, + "evidence_quality": 10 + }, + "reason_not_filed": "GitHub MCP server required re-authorization (token expired) — deduplication searches and issue creation both blocked; carry forward to next run as top priority", + "timestamp": "2026-05-26T08:10:00Z" + }, + { + "finding": "CSP wildcard regex /(?:default-src|script-src)\\s+\\*/i misses wildcards that are not the first source token: 'default-src 'self' *' and 'script-src 'self' *' both pass without any finding, receiving full CSP score while providing essentially no XSS protection.", + "score": 7.45, + "score_breakdown": { + "user_impact": 7, + "security_severity": 8, + "implementation_effort": 7, + "evidence_quality": 10 + }, + "reason_not_filed": "GitHub MCP server required re-authorization — deduplication against issue #5 could not be verified; potential duplicate", + "timestamp": "2026-05-26T08:10:00Z" } ], "clean_areas": [ @@ -59,6 +83,9 @@ "tsconfig.json strict mode is enabled", "CI workflows (ci.yml, publish.yml, auto-tag.yml) are sound", "X-Content-Type-Options check (rules.ts:93-104) — values correctly validated", - "X-Frame-Options check (rules.ts:73-91) — accepts DENY/SAMEORIGIN and CSP frame-ancestors fallback as expected" + "X-Frame-Options check (rules.ts:73-91) — accepts DENY/SAMEORIGIN and CSP frame-ancestors fallback as expected", + "src/index.ts — exports are correct and FetchOptions type is exported", + "src/analyzer.ts — grade thresholds match README grading scale", + "src/fetch.ts — AbortController timeout is correctly implemented" ] } From 0be64e58feea66de1e059da63bfacdb5651695db Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 08:18:36 +0000 Subject: [PATCH 2/3] =?UTF-8?q?chore:=20review=20state=20update=202026-05-?= =?UTF-8?q?26=20(run=202=20=E2=80=94=20issue=20#21=20filed)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filed #21: CSP 'unsafe-inline' penalized when 'strict-dynamic' + nonce present — false positive against recommended Google Strict CSP pattern. Score 7.10. Runner-ups: #15 (4 failing tests, score 8.1), #7 (HEAD fetch, 8.1), #5 (base-uri, 7.9), #17 (HSTS max-age=0, 7.0), #19 (form-action, 6.8), #16 (CSP wildcard, 6.1), #20 (CSP-Report-Only, 5.9) — all duplicates. https://claude.ai/code/session_01CzHFbZqhKAXfPaFZEFiyCY --- .claude/review-state.json | 49 +++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/.claude/review-state.json b/.claude/review-state.json index a80f343..b2203e1 100644 --- a/.claude/review-state.json +++ b/.claude/review-state.json @@ -1,5 +1,5 @@ { - "last_run": "2026-05-26T08:10:00Z", + "last_run": "2026-05-26T08:12:00Z", "last_commit": "81f8735d167b597ed7a7a88cc7f89ba0b440b07d", "filed": [ { @@ -14,19 +14,32 @@ "evidence_quality": 10 }, "timestamp": "2026-05-26T00:55:00Z" + }, + { + "issue": 21, + "title": "[REVIEW] CSP: `'unsafe-inline'` penalized even when `'strict-dynamic'` + nonce is present — false positive flags a recommended strict CSP pattern", + "finding": "checkCSP in src/rules.ts:53-57 unconditionally deducts 5 points for 'unsafe-inline', even when 'strict-dynamic' + nonce is also present — a recommended backwards-compat pattern that is safely ignored by CSP3 browsers. Developer receives wrong advice to 'use nonces or hashes instead' when they already do.", + "score": 7.10, + "score_breakdown": { + "user_impact": 7, + "security_severity": 6, + "implementation_effort": 8, + "evidence_quality": 9 + }, + "timestamp": "2026-05-26T08:12:00Z" } ], "runner_ups": [ { "finding": "CSP wildcard regex /(?:default-src|script-src)\\s+\\*/i only matches when '*' is the first source token; 'default-src 'self' *' is not flagged.", "score": 6.1, - "reason_not_filed": "lower score; subsumed by broader CSP-evaluator-style follow-up to #5", + "reason_not_filed": "duplicate of open issue #16 (which also covers connect-src *, form-action *, and mid-policy wildcards)", "timestamp": "2026-05-26T00:55:00Z" }, { "finding": "checkCSP does not recognize Content-Security-Policy-Report-Only header; report-only deployments are treated as if no CSP exists.", "score": 5.9, - "reason_not_filed": "lower score; needs design discussion on whether report-only should count for points", + "reason_not_filed": "duplicate of open issue #20", "timestamp": "2026-05-26T00:55:00Z" }, { @@ -38,7 +51,7 @@ { "finding": "Referrer-Policy classifies 'no-referrer-when-downgrade' as a strong value (score 10), but it is the historical default and is widely considered weak for cross-origin URL leakage.", "score": 4.2, - "reason_not_filed": "lower score; borderline classification call rather than a clear bug", + "reason_not_filed": "duplicate of open issue #18", "timestamp": "2026-05-26T00:55:00Z" }, { @@ -50,11 +63,11 @@ { "finding": "checkCSP does not flag missing base-uri directive, leaving injection silently bypassing script-src 'self'.", "score": 7.9, - "reason_not_filed": "duplicate of open issue #5", + "reason_not_filed": "duplicate of closed issue #5", "timestamp": "2026-05-26T00:55:00Z" }, { - "finding": "PR #2 merge (81f8735) introduced 4 failing tests in test/analyzer.test.ts: branch owl-alpha/add-tests-and-timeout was forked before commit 8d29a8c tightened Permissions-Policy scoring (require all 3 directives), so tests still expect old score-10-for-presence behavior. Failures: checkPermissionsPolicy > falls back to feature-policy header (line 275), permissions-policy takes precedence over feature-policy (line 281), case-insensitive header name matching (line 290), grade boundaries > A+ at 90% (line 340). CI runs npm test and would gate on these failures.", + "finding": "PR #2 merge (81f8735) introduced 4 failing tests in test/analyzer.test.ts: branch owl-alpha/add-tests-and-timeout was forked before commit 8d29a8c tightened Permissions-Policy scoring (require all 3 directives), so tests still expect old score-10-for-presence behavior.", "score": 8.1, "score_breakdown": { "user_impact": 8, @@ -62,20 +75,20 @@ "implementation_effort": 9, "evidence_quality": 10 }, - "reason_not_filed": "GitHub MCP server required re-authorization (token expired) — deduplication searches and issue creation both blocked; carry forward to next run as top priority", - "timestamp": "2026-05-26T08:10:00Z" + "reason_not_filed": "duplicate of open issue #15", + "timestamp": "2026-05-26T08:12:00Z" }, { - "finding": "CSP wildcard regex /(?:default-src|script-src)\\s+\\*/i misses wildcards that are not the first source token: 'default-src 'self' *' and 'script-src 'self' *' both pass without any finding, receiving full CSP score while providing essentially no XSS protection.", - "score": 7.45, - "score_breakdown": { - "user_impact": 7, - "security_severity": 8, - "implementation_effort": 7, - "evidence_quality": 10 - }, - "reason_not_filed": "GitHub MCP server required re-authorization — deduplication against issue #5 could not be verified; potential duplicate", - "timestamp": "2026-05-26T08:10:00Z" + "finding": "HSTS: max-age=0 (HSTS revocation/deletion directive) scores 'good' when accompanied by includeSubDomains and preload, because bonus points push total to 15+ despite finding for low max-age.", + "score": 7.0, + "reason_not_filed": "duplicate of open issue #17", + "timestamp": "2026-05-26T08:12:00Z" + }, + { + "finding": "CSP: form-action directive is not checked; default-src 'self' does not restrict form submissions (form-action is a navigation directive with no default-src fallback per CSP3).", + "score": 6.8, + "reason_not_filed": "duplicate of open issue #19", + "timestamp": "2026-05-26T08:12:00Z" } ], "clean_areas": [ From fe0836c076cb9674a5a7a427c2f61f8a3828e6c2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 08:19:12 +0000 Subject: [PATCH 3/3] chore: update package-lock.json after npm install https://claude.ai/code/session_01CzHFbZqhKAXfPaFZEFiyCY --- package-lock.json | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65db0c6..72d1b93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -637,9 +637,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -654,9 +651,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -671,9 +665,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -688,9 +679,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -705,9 +693,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -722,9 +707,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -739,9 +721,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -756,9 +735,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -773,9 +749,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -790,9 +763,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -807,9 +777,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -824,9 +791,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -841,9 +805,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [