Skip to content

Add multi-language static source code scanning (--scan-dir) - #447

Open
ethando1984 wants to merge 6 commits into
s0md3v:masterfrom
ethando1984:scanner-upstream
Open

Add multi-language static source code scanning (--scan-dir)#447
ethando1984 wants to merge 6 commits into
s0md3v:masterfrom
ethando1984:scanner-upstream

Conversation

@ethando1984

Copy link
Copy Markdown

Summary

Adds an optional static source-code scanner to XSStrike, invoked with --scan-dir <path>. Where XSStrike normally fuzzes a running target for XSS, this mode scans a source tree for a broad set of security issues without needing a URL. It reuses XSStrike's existing logging/color infrastructure and adds no new runtime dependencies for the core Python scanner.

python xsstrike.py --scan-dir ./myapp
python xsstrike.py --scan-dir ./myapp --min-severity HIGH --json-out report.json

What's included

  • core/staticScanner.py — self-contained, dependency-free regex engine. ~40 language-tagged rules covering XSS sinks, SQL/command/LDAP/template/NoSQL injection, insecure deserialization, path traversal, XXE, weak crypto, hardcoded secrets (AWS/JWT/provider tokens/private keys), SSRF, open redirect, CORS, CSRF, debug flags, etc. Skips vendored dirs, minified files, and files over 2 MB; honors a .xsstrikeignore file.
  • modes/codeScan.py — reporting layer: severity filtering, sorting, colored console output, JSON export, and CI-friendly exit codes (1 on CRITICAL/HIGH, 2 on bad input).
  • New flags in xsstrike.py: --scan-dir, --min-severity, --json-out, --scan-all-files, --scan-limit.
  • Optional headless crawling (--headless, core/headlessCrawler.py) and crawler link-discovery improvements in core/photon.py.
  • Tooling (all optional, not required to run the scanner): a scripts/codescan.sh wrapper around semgrep/trivy/gitleaks, a pre-commit hook, and a .github/workflows/codescan.yml CI job.

Notes for reviewers

  • The core --scan-dir scanner is pure-Python (re/os/fnmatch only). The optional --headless mode uses Playwright and the scripts/ tooling uses external scanners; none are needed for the default XSS-fuzzing workflow or for --scan-dir itself.
  • Being regex-based and line-oriented, the engine favors recall over precision — some rules (e.g. any os.system() are intentionally broad. --min-severity and --scan-limit help manage output volume.
  • This is scoped to only the scanner feature; it does not include the unrelated sys.executable pip-install fix proposed separately in Use sys.executable for the fuzzywuzzy auto-install fallback #445.

🤖 Generated with Claude Code

ethando1984 and others added 6 commits August 6, 2026 22:11
Introduce a --scan-dir mode that statically scans a source directory for
common security vulnerabilities across ~25 languages. Self-contained,
pattern-based engine (no network, no extra dependencies) covering XSS,
injection, insecure deserialization, path traversal, XXE, weak crypto,
hardcoded secrets, SSRF, open redirect, CORS, and CSRF, each tagged with
a CWE id. Supports --min-severity, --json-out, --scan-all-files, and a
.xsstrikeignore file; exits non-zero on CRITICAL/HIGH findings.

Also add a GitHub Actions codescan workflow (Semgrep + Gitleaks + Trivy)
and document the new mode in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Block commits that introduce CRITICAL/HIGH findings. The hook scans the
exact staged blobs (copied from the index into a temp dir), so it checks
what is being committed rather than the working tree, and it invokes the
scanner module directly so it needs only the standard library. A failed
scanner run exits non-zero rather than silently passing the gate.

Includes an installer (core.hooksPath), a pre-commit framework config,
and a .xsstrikeignore excluding XSStrike's by-design files. Also tighten
the os.system rule to ignore constant string literals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the anchor-only link scraper with extractLinks(), which also
pulls href/src/action attributes and absolute or parameterised URLs
embedded in inline scripts and JSON, so API endpoints on JS-heavy sites
are discovered. Parameterised URLs are registered as GET forms so they
become XSS-testable directly.

Add an optional --headless mode (core/headlessCrawler.py) that renders
pages with Playwright before scraping, recovering links injected at
runtime. It degrades gracefully to plain HTTP when Playwright is absent
or a render fails, and forces single-threaded crawling while active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Expose the existing codeScan limit parameter via a --scan-limit CLI flag
so users can cap how many findings are printed (0 = no limit). Findings
are sorted by severity first, so the highest-impact issues are the ones
shown; a note reports how many were suppressed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An unrecognized --min-severity silently fell back to the widest cutoff
and reported every finding, so a typo (e.g. --min-severity HGIH) looked
like a filtered run. Emit a warning naming the accepted levels
(CRITICAL/HIGH/MEDIUM/LOW) when the value isn't one of them.

(--scan-limit was implemented separately on the feature branch, so it is
no longer included here.)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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