Skip to content

FSV 2.1.0

Choose a tag to compare

@github-actions github-actions released this 25 Oct 17:27

Packaging & project

  • Published as pip install fsv: PEP 621 pyproject.toml (single version source, requirements.txt as the dependency list), PyPI page docs/PYPI.md, release workflow with Trusted Publishing (.github/workflows/publish.yml), and a CI job that builds, twine checks and test-installs the wheel on every push.
  • Fixed: the dependency said mcp>=1.1, but fsv-mcp needs mcp.server.mcpserver, which only exists from mcp 2.0 — an existing mcp 1.x install would have broken the MCP server.
  • Contact details, CLA draft (CLA.md), private security reporting by email.

MCP, supply chain, robustness

  • supply_chain module (32 modules): scripts/styles from compromised or abandoned CDNs (polyfill.io and its sister domains, rawgit) or from expired domains anyone can register — guarded against filtered resolvers that answer NXDOMAIN for everything (found when the first real-world run flagged jquery.com).
  • MCP: security_review prompt (authorization-first guided review), fsv_verify_ownership tool, fsv mcp-config --client claude-code|claude-desktop|cursor|vscode; end-to-end stdio test.
  • Engine: a URL that timed out is remembered for the scan — a hanging endpoint now costs one timeout instead of one per module (hostile-server run: 66 s → 4 s); stats.unresponsive_urls.
  • info_disclosure: the email pattern backtracked quadratically — 33 s on one 2 MB page; now possessive/linear, and bodies are capped at 600 kB.
  • tests/test_e2e_hostile.py: whole-engine runs against real local servers that misbehave (catch-all SPA, redirect loop, 20 MB body, hang, 500s).
  • README & visuals: monochrome metallic glass theme, MCP quick start, FSV-and-ZAP comparison.

Tested against real applications (OWASP PyGoat, Django) — these came out of it:

  • New debug_mode module (31 modules): Django DEBUG=True, Werkzeug console, Rails/Symfony/Laravel Ignition/Express/ASP.NET debug error pages — which only appear on errors, so the crawler never saw them.
  • Crawler discovery: robots.txt paths, sitemaps, Django debug-404 route lists, and API paths in same-origin JavaScript (action-like paths such as /labs/start/… are never requested). On PyGoat: 3 → 39 URLs. --seed / seeds / MCP seed_urls for pages nothing links to; MCP scans can now be authenticated (headers, cookies).
  • False positives removed: anti-CSRF cookies (csrftoken, XSRF-TOKEN) no longer "missing HttpOnly" or session cookies in attack paths; HSTS not demanded over plain HTTP; CSP/Permissions/Referrer only on HTML; X-XSS-Protection no longer demanded (and X-Frame-Options left to clickjacking); Allow: PUT no longer "dangerous" (TRACE is now verified by echo); open redirect that only bounced back to the site's own login; Host-header "injection" when the app rejected the host with a 400; CSRF on forms posting to another site; /admin + /admin/ reported twice as a "sensitive file"; robots.txt/sitemap reported as exposures; noisy "on line" stack-trace signature; HTML matched as a hard-coded password.
  • Severity calibration: missing CSP/HSTS medium (was high), CSRF token missing medium (was high).
  • CSP Wildcard Source check could never fire (spaces were stripped before matching default-src *).

Docs

  • README redesigned: animated, self-contained SVGs (hero radar, terminal replay, detections, attack-path chain, pipeline) that respect prefers-reduced-motion, plus real dashboard screenshots (WebP).
  • examples/demo_site.py — a deliberately vulnerable, loopback-only demo target; the README visuals are generated from a real scan of it (scripts/build_readme_assets.sh [--screenshots]).
  • tests/test_assets.py keeps the images honest (well-formed, no scripts or external loads, alt text, files exist).
  • Dashboard header pluralises correctly ("1 scan · 1 target").

pip install fsv==2.1.0 · https://pypi.org/project/fsv/2.1.0/