Skip to main content

SiteVigil

     .      o                 .               o                       .
  ______  _____  _______  ______ __      __ _____   ______   _____  _
 / ____/ |_   _||__   __||  ____|\ \    / /|_   _| / ____/  |_   _|| |
| (___     | |     | |   | |__    \ \  / /   | |  | |  ___    | |  | |
 \___ \    | |     | |   |  __|    \ \/ /    | |  | | |_  |   | |  | |
 ____) |  _| |_    | |   | |____    \  /    _| |_ | |___| |  _| |_ | |____
|_____/  |_____|   |_|   |______|    \/    |_____| \_____/  |_____||______|
   |                                                |               |
   .                                                .              \___/

One command. A security audit of any website — scored, explained, and with the fix written out for you.

PyPI Python CI License: MIT

pip install sitevigil
sitevigil aqles.github.io
https://aqles.github.io
Score: 75/100  Grade: C  HTTP 200

[MEDIUM  ] Missing Content-Security-Policy header
           No CSP header; the page has no second line of defence against XSS.
           Fix: Add a CSP that fits your site, starting strict, e.g. Content-Security-Policy: default-src 'self'
[LOW     ] Missing X-Content-Type-Options: nosniff
           Header absent or not set to 'nosniff'.
           Fix: Add: X-Content-Type-Options: nosniff
[MEDIUM  ] No clickjacking protection
           Neither X-Frame-Options (DENY/SAMEORIGIN) nor CSP frame-ancestors is set.
           Fix: Add: X-Frame-Options: DENY (or SAMEORIGIN), or frame-ancestors 'none' in your CSP.

SiteVigil is a small Python tool with zero dependencies — standard library only. It runs the checks that turn up again and again when real websites get audited, it works as a plain CLI for humans, and it speaks MCP so AI coding agents (Claude Code, Cursor, …) can run the same audit and fix what it finds.

Why not just use a free web checker?

Fair question — sites like SecurityHeaders or Mozilla Observatory grade a page for free, and for a one-off look they're fine. SiteVigil exists for everything around that moment:

  • It hands you the patch, not just the grade. --fix generates a ready-to-commit config for your actual platform (Vercel, Netlify, Cloudflare Pages, nginx, Apache). On GitHub Pages it tells you plainly that headers are a platform limit and gives you the portable _headers file instead of a lecture.
  • It lives where you work. Terminal, CI (--fail-under, --baseline), and inside your AI agent via MCP — a web page can't fail your deploy or re-check a fix.
  • It checks more than headers. Exposed .env/.git (verified by content, not status codes), CORS reflection, cookie flags, mixed content, missing SRI, TRACE, TLS expiry, security.txt.
  • It remembers. Save a report, come back next week, and --baseline shows exactly what regressed and what got fixed — web checkers have no memory of your last scan.

What it checks

Area Checks
Transport HTTPS in place, HTTP → HTTPS redirect, TLS protocol, certificate expiry, redirect chains (downgrade hops, chains over 3 hops), main-page response time (flagged over 3 s)
Security headers HSTS, Content-Security-Policy (incl. unsafe-inline / unsafe-eval / wildcard sources), X-Content-Type-Options, clickjacking, Referrer-Policy, Permissions-Policy
Cookies Secure, HttpOnly (on session-like cookies), SameSite
CORS Arbitrary-origin reflection, * combined with credentials
Exposed files /.env, /.git/HEAD, /.git/config
Exposed services Database ports open to the internet — MySQL/MariaDB (3306), PostgreSQL (5432), Redis (6379), MongoDB (27017), plain TCP connect
Page content Mixed content (HTTP subresources on an HTTPS page), cross-origin scripts without Subresource Integrity
Methods & discovery HTTP TRACE enabled, missing /.well-known/security.txt
Isolation Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy, CSP hardening directives (object-src / base-uri)
Domain (via DNS) SPF and DMARC (only when the domain receives mail), CAA
Known vulnerabilities Software/version fingerprints (nginx, Apache, PHP, OpenSSL, IIS, WordPress, Drupal, Joomla) matched against NVD CVEs, verified against each CVE's vulnerable version ranges — plus jQuery and WordPress plugins (Elementor, WooCommerce, Contact Form 7, Akismet) fingerprinted from the page source
Info disclosure Server, X-Powered-By

The full catalog — 30+ checks, each with its reference — is one command away: sitevigil --checks. Checks are versioned as a ruleset (currently 2026.11); every report names the ruleset that produced it, and changes land in CHANGELOG.md, never silently. To keep a site up to date automatically, drop in the weekly GitHub Action from examples/github-action: it re-audits on a schedule and fails on score drops or regressions.

Every finding includes what was actually observed and a concrete fix — not just a warning label.

Two details that took real-world pain to learn:

  • No soft-404 false positives. Many sites (SPAs, some hosts) answer 200 with their homepage for every path. SiteVigil only reports an exposed file when the response content actually matches a real .env / git file — a bare 200 is never enough.
  • CVE matches are verified, not googled. NVD search happily returns CVEs that only mention your software. SiteVigil re-checks every candidate against the CVE's own vulnerable configurations and version ranges before reporting it, scores it with NVD's primary CVSS, and prints the backport caveat next to every match — a version string alone never proves a server is unpatched.
  • Proxy-aware TLS. If you sit behind a corporate proxy (https_proxy), the TLS check tunnels through it with CONNECT instead of dying with WRONG_VERSION_NUMBER.

Install

pip install sitevigil
# or straight from the repo:
pip install git+https://github.com/aqles/sitevigil
# or just run it from a clone, no install needed:
python -m sitevigil example.com

Requires Python 3.10+. That's it — nothing else gets installed.

Use it

sitevigil example.com                  # human-readable report
sitevigil example.com --json           # structured output, for scripts and agents
sitevigil example.com --markdown       # a report you can paste into an issue
sitevigil example.com --html > report.html   # one self-contained HTML report
sitevigil a.com b.com c.com            # audit several sites, with a summary table
sitevigil example.com --fail-under 80  # CI mode: exit 1 if the score is below 80
sitevigil example.com --fix            # + a ready-to-commit header config for your platform
sitevigil example.com --json > monday.json          # save a baseline
sitevigil example.com --baseline monday.json        # next week: what regressed? (exit 1 on new findings)
sitevigil example.com --crawl 10                    # audit up to 10 pages (sitemap.xml, else homepage links)
sitevigil example.com --badge > badge.svg           # an SVG score badge for your README
sitevigil example.com --no-cve                      # skip the CVE lookup (faster, fully offline)
sitevigil example.com --no-ports                    # skip the exposed-database-port check
sitevigil example.com --html --output report.html   # write any format straight to a file

Scoring starts at 100 and loses points per finding (critical 25, high 15, medium 8, low 3), ending in a grade from A to F.

Let your AI agent use it

SiteVigil ships an MCP server (still stdlib-only). Local agents use stdio; hosted agents can use the HTTP transport:

sitevigil --mcp                      # stdio, for desktop/CLI agents
sitevigil --mcp-http 8900            # HTTP on localhost, for hosted agents

MCP is a shared protocol, so one server works with every MCP-compatible agent — Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Gemini CLI — no per-agent builds. Only the config file's location changes; ready-to-paste snippets for each agent live in examples/mcp. Interoperability is not just claimed: the server is tested against the official MCP Python SDK client (initialize → tool list → a real audit_site call).

Your agent gets two tools: audit_site (the full scored report) and suggest_fix (the audit plus a ready-to-commit, platform-specific header config). It can check a site before telling you it's "secure" — or audit the fix it just deployed.

Honest limits

  • It audits the response of the URL you give it (plus /.env / /.git probes). It is not a vulnerability scanner and it does not fuzz, brute-force, or log in anywhere.
  • The database-port check is a plain TCP connect to four well-known ports: no banner grabbing, no login attempts. A firewalled port counts as closed — the check claims reachability, nothing more.
  • Only audit sites you own or have permission to test. The probes are read-only GETs, but scanning other people's property without permission is still a bad idea.
  • A high score means these basics are in place. It is not a guarantee that a site is secure.

Development

git clone https://github.com/aqles/sitevigil
cd sitevigil
PYTHONPATH=src python -m unittest discover -s tests -v

The test fixture is a local HTTP server that deliberately serves a soft-404 for unknown paths and a real-looking .env file — the audit has to catch one and ignore the other.

License

MIT — see LICENSE. Use it, fork it, ship it; just keep the copyright notice. If SiteVigil saves you from shipping a site with an exposed .env, a star is the going rate.

Metadata

Release files for sitevigil 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sitevigil 0.9.0
File Size Uploaded Provenance Actions
sitevigil-0.9.0.tar.gz 38.6 kB Without provenance Details for sitevigil-0.9.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sitevigil 0.9.0
File Interpreter ABI Platform Actions
sitevigil-0.9.0-py3-none-any.whl Python 3 none any Details for sitevigil-0.9.0-py3-none-any.whl

Total release size: 70.0 kB

Release files / sitevigil-0.9.0.tar.gz

Download URL sitevigil-0.9.0.tar.gz
Size 38.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6e098c1150eb2df90b89f13596736b3da3cf64049e5a59b29a2d32def227613e
BLAKE2b-256 checksum
How to use checksums
1ef907bf3573b04ad828fc5bde87534e9e6aa4919949dad0bdea312e41a40541
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / sitevigil-0.9.0-py3-none-any.whl

Download URL sitevigil-0.9.0-py3-none-any.whl
Size 31.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad5306b5e1c437153dbd08f857fcc9afb27c322ade7533ad4ac3f217233b1373
BLAKE2b-256 checksum
How to use checksums
62fdd58005b1565b2acd85ec92f31c91604db89ad5abbb92e33a55f4606b4fc4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for sitevigil 0.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page