Skip to content

feat(scan): misconfiguration, weak-crypto & injection rules — coverage 71.3% → 79.8% (v0.10.0) - #103

Merged
ralyodio merged 1 commit into
masterfrom
feat/coverage-tier-2
Aug 11, 2026
Merged

feat(scan): misconfiguration, weak-crypto & injection rules — coverage 71.3% → 79.8% (v0.10.0)#103
ralyodio merged 1 commit into
masterfrom
feat/coverage-tier-2

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Release 0.10.0. Detection coverage against the testbed 71.3% → 79.8% (92 → 103 of 129), false-positive rate still 0% — and, the number that actually decides whether a dev keeps the tool installed, zero new findings on capacitor (10), the self-scan (67), ShortsStudio (0) or koajs/router (0).

13 new rules

Each targets a defect the line itself shows, so the corpus's corrected shape differs on something visible here, not three functions away:

rule CWE catches
py-framework-debug-enabled 489 DEBUG = True, run(debug=True)
js-cors-wildcard-credentials 942 origin: '*' + credentials: true
js-cookie-insecure-flag 614 cookie(…secure: false)
js-hardcoded-crypto-key 321 key literal in crypto code
py-hardcoded-secret-key 798 SECRET_KEY = "literal"
py-ldap-injection 90 unescaped LDAP filter
py-xpath-injection 643 interpolated XPath
py-fast-password-hash 759 SHA-2 on a password, no KDF
py-plaintext-password-retained 256 raw password stored
js-timing-unsafe-mac-compare 208 === on a signature
js-predictable-cipher-iv 329 static IV
js-mass-assignment 915 Object.assign(x, req.body)
js-header-injection 113 request input into a response header

Two calls in service of "safe to install"

Because the steer was desirability — and the fastest way to get a scanner uninstalled is noise:

  1. The timing-unsafe rule first flagged the corpus's own safe line — a a.length === b.length check whose timingSafeEqual sits forward of the backward guard window. A length comparison isn't the value compare, so the rule now excludes .length. FPR back to 0.
  2. A Math.random().toString(36) token rule was written and dropped. The exact shape generates security tokens and benign callback ids — Capacitor's native bridge uses it for the latter, and it produced 3 false positives there. No line-visible signal separates the two, so the bare shape is left to the credential-scoped rule that already covers token = …Math.random…. One ambiguous rule wasn't worth one testbed line.

Deliberately still absent

CSRF, IDOR, TOCTOU, missing authorization, session fixation, and the sanitize-upstream classes (CSV/log injection, whose vulnerable and safe lines are identical). They need whole-function reasoning this engine doesn't fake — forcing them would trade the 0% FPR that makes the tool worth installing. See KNOWN_GAPS.

Verification

  • Testbed: 79.8% TPR / 0% FPR, gate floor raised 68 → 76.
  • Zero new findings on capacitor, self-scan, ShortsStudio, koajs/router — checked each of the 13 rules against real code, which is where the dropped Math.random rule was caught.
  • 154 tests (up from 141) — every rule has its vulnerable case and the corrected shape beside it. tsc --noEmit clean.

Raises detection coverage against the testbed from 71.3% to 79.8% (92 to 103
of 129), false-positive rate still 0%, and — the number that matters for a
tool people choose to install — zero new findings on capacitor (10), the
self-scan (67), ShortsStudio (0) or koajs/router (0).

Each rule targets a defect the line itself shows, so the corrected shape in
the corpus differs on something visible here rather than three functions away:

  py-framework-debug-enabled   debug mode left on (CWE-489)
  js-cors-wildcard-credentials `*` origin with credentials (CWE-942)
  js-cookie-insecure-flag      cookie with secure:false (CWE-614)
  js-hardcoded-crypto-key      key literal in crypto code (CWE-321)
  py-hardcoded-secret-key      signing secret literal (CWE-798)
  py-ldap-injection            unescaped LDAP filter (CWE-90)
  py-xpath-injection           interpolated XPath (CWE-643)
  py-fast-password-hash        SHA-2 on a password, no KDF (CWE-759)
  py-plaintext-password-retained  raw password stored (CWE-256)
  js-timing-unsafe-mac-compare === on a signature (CWE-208)
  js-predictable-cipher-iv     static IV (CWE-329)
  js-mass-assignment           Object.assign(x, req.body) (CWE-915)
  js-header-injection          request input into a response header (CWE-113)

Two decisions in service of "safe to install":

  - The timing-unsafe compare first flagged the corpus's own safe line — a
    `.length ===` length check whose `timingSafeEqual` sits forward of the
    backward guard window. A length comparison is not the value compare, so
    the rule now excludes `.length`.
  - A `Math.random().toString(36)` token rule was written and then dropped: the
    exact shape generates security tokens AND benign callback ids (Capacitor's
    native bridge does the latter), with no line-visible signal between them.
    Three false positives on a real repo is precisely what gets a scanner
    uninstalled, so the bare shape is left to the credential-scoped rule that
    already covers the `token = …Math.random…` case.

Deliberately still absent: CSRF, IDOR, TOCTOU, missing authorization, session
fixation, and the sanitize-upstream classes (CSV/log injection) whose
vulnerable and safe lines are identical — they need whole-function reasoning
this engine does not fake. See KNOWN_GAPS.

Gate floor moves 68 to 76. 154 tests, up from 141.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

67 finding(s)

HIGH/CRITICAL: 11 | MEDIUM: 55 | LOW: 1

Severity Rule Location
HIGH secret-aws-access-key prd/0003-detect-hardcoded-secrets-before-they-are-committed-or-served.md:126
HIGH sh-eval-expansion .githooks/pre-commit:26
HIGH sh-remote-script-execution apps/web/public/install.sh:272
HIGH sh-remote-script-execution apps/web/public/install.sh:320
HIGH secret-generic-credential modules/spend-guard/config/example.conf.toml:13
HIGH secret-generic-credential modules/spend-guard/README.md:84
HIGH secret-generic-credential PRD.md:268
HIGH tls-verification-disabled prd/0004-find-dangerous-code-patterns-without-pretending-to-be-a-compiler.md:121
HIGH tls-verification-disabled prd/0004-find-dangerous-code-patterns-without-pretending-to-be-a-compiler.md:122
HIGH sh-remote-script-execution scripts/smoke-test.sh:46
HIGH sh-remote-script-execution scripts/smoke-test.sh:47
MEDIUM insecure-temp-file .githooks/commit-msg:16
MEDIUM insecure-temp-file .githooks/post-commit:20
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/init.ts:70
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/init.ts:79
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/service.ts:88
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/service.ts:111
MEDIUM sql-template-interpolation apps/cli/src/core/state.ts:121
MEDIUM sql-template-interpolation apps/cli/src/core/state.ts:125
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:31
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:33
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:34
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:35
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:36
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:43
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:49
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:56
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:63
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:82
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:84
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:85
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:93
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:98
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:105
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:112
MEDIUM js-shell-exec-interpolation apps/cli/src/index.ts:419
MEDIUM js-unescaped-html-sink apps/web/src/app/about/page.tsx:180
MEDIUM js-unescaped-html-sink apps/web/src/app/about/page.tsx:184
MEDIUM js-open-redirect apps/web/src/app/auth/login/page.tsx:50
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:125
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:153
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:157
MEDIUM js-unescaped-html-sink apps/web/src/app/get-whitepaper/page.tsx:346
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:211
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:215
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:219
MEDIUM js-unescaped-html-sink apps/web/src/app/page.tsx:120
MEDIUM js-unescaped-html-sink apps/web/src/app/store/[slug]/page.tsx:107
MEDIUM js-open-redirect apps/web/src/components/funding/FundingClient.tsx:97
MEDIUM manifest-install-lifecycle-script package.json:24

…and 17 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 44e23af into master Aug 11, 2026
11 checks passed
@ralyodio
ralyodio deleted the feat/coverage-tier-2 branch August 11, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant