Skip to content
uaip-devPublic

About

A simple, self-hosted **passive** website security scanner.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

🛡️ Scan Me

A simple, self-hosted passive website security scanner. Enter a URL and get:

  • Security header grade (A–F) — HSTS, CSP, X-Frame-Options, and more, each with an explanation and a recommended value.
  • Information disclosure — flags Server, X-Powered-By, and other headers that leak software versions.
  • Tech fingerprint — detects server, framework, CMS, CDN/WAF, JS libraries, e-commerce and analytics from headers, cookies, and page body, with versions where available. Built-in rules are augmented by a bundled Wappalyzer-style dataset (7,000+ technologies, from the open webappanalyzer project), so a Laravel app surfaces PHP/Livewire/Alpine.js, a WordPress site its editor and database, and so on. Passive patterns only (headers, cookies, meta, HTML, script URLs) — runtime dom/js rules are skipped.
  • Component & plugin enumeration — passively parses the page markup to list client-side JS/CSS libraries (jQuery, Bootstrap, Vue, Swiper, …) with versions, and — on WordPress — the core version plus every installed plugin and theme with versions (Elementor, WooCommerce, Contact Form 7, Jetpack, …). Versioned components are fed into CVE correlation, so you can see, e.g., an outdated jQuery on a Laravel site or a vulnerable WordPress plugin.
  • Host / location — resolves the target to its IP(s), reverse DNS, geolocation (country/region/city), ASN, ISP, and hosting provider (via ipwho.is), and flags when the IP is a CDN edge (so you know the location reflects the CDN, not origin).
  • TLS check — protocol, certificate validity, issuer, and expiry.
  • CVE correlation — for client-side JS libraries it uses the bundled retire.js database for precise, version-range–matched vulnerabilities (high confidence, not just a version banner). For the server stack, WordPress core/plugins, and any library retire.js doesn't track, it falls back to the NVD API keyword search (with a CIRCL fallback).
  • Deep render (optional) — tick Deep render to load the page in a real browser via the sibling @uaip/locator and report the rendered interactive surface: page title, form/button/link counts, and security-relevant inputs (password, file-upload, search, hidden/CSRF fields), plus a login-form flag. Because it runs JavaScript, it sees single-page-app content a passive fetch can't. Off by default and degrades gracefully if not installed — see below.
  • Companion tests (@uaip/locator) — after a scan, a "next step" card pulls the current @uaip/locator version live from npm and offers a ready-to-run command to generate a Playwright end-to-end test suite for the scanned site.
  • Scan history — every scan is saved; browse past scans in the sidebar and re-open them.
  • Export — download the full history as JSON or CSV.
  • 1-hour cache limit — scanning the same domain within an hour returns the stored result instead of re-scanning. Tick Force rescan to override.

Passive only: it just fetches the page and inspects the certificate. No port scanning, fuzzing, or intrusive probing.

Run it

Requires Node.js 18+.

npm install
npm start

Then open http://localhost:3000 and enter a domain.

Optional: NVD API key

The NVD API rate-limits unauthenticated requests (~5 per 30s). Grab a free key at https://nvd.nist.gov/developers/request-an-api-key and run:

NVD_API_KEY=your-key npm start

Optional: deep render (real browser)

The Deep render checkbox uses the sibling project @uaip/locator to load the page in a real (headless) browser and read the rendered interactive surface — useful for single-page apps and JS-injected forms. It's not bundled (it pulls in Playwright and a browser binary). Enable it once with:

npm i @uaip/locator
npx playwright install chromium

Without it, deep-render requests still succeed — the panel just shows an install hint. Scan Me uses uaip only to read the page (title, forms, inputs, page type), not to generate tests.

Keeping the retire.js database current

The JS-library vulnerability database (data/retire-jsrepository.json) and the Wappalyzer-style technology dataset (data/wappalyzer/) are bundled and work offline. Refresh them to the latest any time with:

npm run update:retiredb     # retire.js vulnerability database
npm run update:wappalyzer   # webappanalyzer technology dataset

Optional: allow localhost / private IPs (local testing)

By default localhost and private/reserved IPs are blocked (SSRF protection). To scan your own local services during development, opt in with an env var or CLI flag:

ALLOW_PRIVATE=1 npm start
# or
node server.js --allow-private

The server prints a warning while this is on. Leave it off for any deployment reachable by others — it disables the SSRF guard.

Notes & limits

  • Only scan sites you own or have permission to test.
  • Requests to localhost and private/reserved IPs are blocked (SSRF protection), unless ALLOW_PRIVATE / --allow-private is set (see above).
  • CVE matches are based on version banners, which can be spoofed or already patched — they are shown as potential, not confirmed.

Project layout

server.js            Express server + API routes
lib/validate.js      URL normalization + SSRF guard
lib/scan.js          Orchestrates a scan
lib/headers.js       Security-header analysis + grading
lib/fingerprint.js   Version / tech detection (headers, cookies, body)
lib/wappalyzer.js    Wappalyzer-style detection over the bundled dataset
data/wappalyzer/     Bundled webappanalyzer technology + category dataset
lib/components.js    JS-library + WordPress plugin/theme enumeration (passive)
lib/geo.js           Host IP / reverse-DNS / geolocation / ASN enrichment
lib/tls.js           TLS certificate inspection
lib/cve.js           NVD + CIRCL CVE lookup (cached)
lib/retire.js        retire.js version-range vuln matching for JS libraries
data/retire-jsrepository.json  Bundled retire.js vulnerability database
lib/store.js         Scan history persistence + JSON/CSV export
lib/deep.js          Optional deep render via @uaip/locator (rendered surface)
lib/uaip.js          Live @uaip/locator metadata for the companion card
data/history.json    Saved scan history (created at runtime)
public/              Frontend (HTML/CSS/JS)

API

  • POST /api/scan — body { "url": "...", "force": false, "deep": false }. Respects the 1-hour cache unless force is true. deep: true adds a real-browser render (via @uaip/locator, if installed) and always runs fresh.
  • GET /api/history — list past scans.
  • GET /api/history/:id — full result for one scan.
  • DELETE /api/history — clear history.
  • GET /api/export?format=json|csv — download history.
  • GET /api/uaip — live metadata for the companion tool @uaip/locator (from the npm registry, cached).

Possible next steps

  • Scan history (SQLite) and PDF export.
  • More fingerprint rules (Wappalyzer-style).
  • CPE-based CVE matching for higher precision.

About

A simple, self-hosted **passive** website security scanner.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages