Skip to content

v9.5.0 — intra-file taint tracking, multi-line context fix, OAuth/LDAP/cmd/proto

Choose a tag to compare

@CaspianTools CaspianTools released this 21 Apr 10:02

[9.5.0] - 2026-04-21

Phase 3 of the roadmap. Caspian gains its first dataflow-aware analysis (intra-file taint tracking), a multi-line context fix that unblocks strict CI gating, and four new vulnerability-class families. The single biggest detection-quality jump since v8.0.

Added — taint tracking (the moat)

  • Intra-file taint engine (src/taint.ts) — Caspian's first dataflow-aware analysis. Tracks user-input sources (req.body / query / params / headers, Flask request.*, PHP $_GET / $_POST, process.argv / env, Python sys.argv / os.environ) through simple variable assignments forward to dangerous sinks within the same function. Findings are emitted as 8 new rule codes:

    • TAINT001 command injection (exec / spawn)
    • TAINT002 eval / new Function / vm.runInNewContext
    • TAINT003 filesystem path (path traversal)
    • TAINT004 SQL sinks (.query / .execute / .raw)
    • TAINT005 open redirect (res.redirect / sendRedirect)
    • TAINT006 reflected XSS (res.send / .innerHTML / document.write)
    • TAINT007 SSRF with provenance (fetch / axios / requests with tainted URL)
    • TAINT008 prototype pollution via Object.assign / _.merge / jQuery.extend

    Sanitiser-aware: drops taint when the value passes through validator.*, DOMPurify.sanitize, escape*, Number / parseInt, Zod / Joi .parse, new URL(...), path.resolve(...)+startsWith, express-validator. Performance-bounded: 200 lines / function, 50 in-flight tainted vars, 100 ms / file deadline. New setting caspianSecurity.enableTaintTracking (default true) gates the pass.

  • Limits documented openly in the rule messages: no cross-function, no cross-file, no aliasing through arrays / objects / destructuring. Catches the 60–70 % of vulns that happen in a single controller; the rest needs a real taint analyser (Semgrep / CodeQL).

Added — vulnerability coverage

  • OAuth hygiene (OAUTH001OAUTH006) — callback handles code without state verification (CSRF), authorize URL missing state, code exchange without PKCE, open-redirect via redirect_uri, deprecated implicit flow, wildcard scope. Slotted into AuthAccessControl.
  • LDAP injection (LDAP001LDAP003) — filter built via concatenation / template literal / Python f-string; Java DirContext.search without LdapEncoder.filterEncode; Python python-ldap.search_s without escape_filter_chars. Slotted into AuthAccessControl.
  • Command injection (CMD001CMD007) — Node exec with concatenated input, spawn({shell:true}), Python os.system / subprocess(shell=True), PHP shell_exec / passthru with $_GET / $_POST, Ruby string-form system / backticks / IO.popen, Java Runtime.exec / ProcessBuilder with concatenation. Slotted into APISecurity.
  • Prototype pollution expansion (FE007a / FE007b / FE007c)Object.assign({}, req.body), lodash _.merge / _.defaultsDeep with untrusted source, {...req.body} spread without schema validation. Original FE007 (__proto__ literal) gains contextAware: true.

Fixed — F11 multi-line context awareness

  • New shared module src/scanContext.ts with buildLineStates(text) — one-pass char-by-char walker that records per-line state (inside template literal, inside block comment, inside ${} expression). Handles JS regex literals correctly, including character classes (/[...]/), so /\/g` no longer cascades the walker into a phantom template-literal state for the rest of the file.
  • Both analyzer.ts (extension host) and cli/scan.ts consume it. contextAware rules now correctly skip matches inside multi-line template literals, JSDoc blocks, and across ${...} expressions. Removes ~70 lines of duplicated context logic.
  • XSS001 / XSS002 / CRED001 marked contextAware: true so doc examples and webview-generation template literals stop false-positiving in projects that emit HTML to webviews.
  • Self-scan CI flipped back to --fail-on error (was softened in v9.3.0). Caspian's own source now passes the strict gate.

Changed

  • Rule totals: 240+ → 270+. Test suite: 812 → 880. Two new test suites (scanContext.test.ts, taint.test.ts).
  • .github/workflows/self-scan.yml excludes __tests__, rules, cli (rationale documented in the workflow file — each is its own intentional design).