- Add multi-stage CSS build that compiles Tailwind into app/static/tw.css
- Add Tailwind config with dark tokens (bg/nav/card) and purge globs
- Add assets/input.css (@tailwind base/components/utilities + small utilities)
- Replace Tailwind CDN + REMOVE Flowbite CSS (keep Flowbite JS only)
- New base_tailwind.html (top navbar, responsive container, {%- block scripts -%})
- Port pages to Tailwind look/feel with wider content column:
- index: single-column form + recent results, fullscreen spinner overlay, copy-UUID
- result: sticky jump list, Tailwind tables/badges, Suspicious Scripts/Forms sections
- viewer: Monaco-based code viewer in Tailwind card, actions (copy/wrap/raw)
- ssl_tls macro: rewritten with Tailwind (details/summary for raw JSON)
- Dockerfile: add css-builder stage and copy built tw.css into /app/app/static
- Remove Flowbite stylesheet to avoid overrides; Flowbite JS loaded with defer
BREAKING CHANGE:
Legacy CSS classes/components (.card, .badge, etc.) are replaced by Tailwind utilities.
All templates now expect tw.css to be served from /static.
SneakyScope
A lightweight web-based sandbox for analyzing websites and domains. SneakyScope fetches a page in a sandbox, enriches with WHOIS/GeoIP, and runs a unified Rules Engine (YAML + function rules) against scripts, forms, and text. Results are saved per-run and rendered with analyst-friendly tables, severity badges, and tags. Results are saved at time of analysis per run so you have a point in time result that doesn't change.
Repo: https://git.sneakygeek.net/ptarrant/SneakyScope Status: Private (may become public later)
🚀 Features
Unified Detection (Rules Engine)
-
Regex rules from YAML + function rules in code for context-aware checks.
-
PASS/FAIL per rule with reason, severity (
low|medium|high), and tags. -
Per-script matches:
- Inline scripts → run regex rules on the code.
- External scripts → run function rules with structured facts (
src, hostnames, etc.).
-
Page-level overview: complete PASS/FAIL tables by category (
script,form,text).
Domain & IP Enrichment
- WHOIS with robust fallbacks (
N/A,Possible Privacywhen fields are missing). - GeoIP, ASN, and ISP details.
Results & UX
-
Per-run artifacts under
/data/<uuid>/:screenshot.png,source.txt,results.json(single source of truth).
-
Suspicious Scripts table shows only matched scripts with:
- Severity badges and tag chips (tooltip shows rule reason).
- Snippet preview length configurable via
settings.yaml.
🧱 Architecture at a Glance
-
Flask app (Gunicorn in Docker)
-
Playwright for headless page fetch/render
-
BeautifulSoup4 for parsing
-
Rules Engine
- YAML regex rules (
config/suspicious_rules.yaml) - Function rules (
app/rules/function_rules.py) registered on startup
- YAML regex rules (
-
Artifacts: persistent path mounted at
/data(configurable)
⚙️ Setup
1) Clone
Since this repo is private, you’ll need credentials (HTTPS with a personal access token) or SSH access.
HTTPS (with token):
git clone https://git.sneakygeek.net/ptarrant/SneakyScope.git
cd SneakyScope
SSH:
git clone git@git.sneakygeek.net:ptarrant/SneakyScope.git
cd SneakyScope
2) Configure Environment
Copy and edit env:
cp .env.example .env
Important vars:
SECRET_KEY– Flask secret (set in production).MAXMIND_LICENSE_KEY– for GeoIP (optional if you disable GeoIP).SNEAKYSCOPE_RULES_FILE– override path to YAML rules (optional).
3) Settings
settings.yaml controls UI/behavior. Example:
app:
name: "SneakyScope"
version_major: 0
version_minor: 1
ui:
snippet_preview_len: 160 # controls inline script snippet length in UI
4) Run with Docker Compose
docker-compose up --build
This builds the image and starts the web app. The /data directory in the container is where run artifacts are written—mount a host directory in Compose to persist between restarts.
🧪 Using SneakyScope
-
Open the web UI and submit a URL.
-
On completion you’ll see:
- URL Overview (with permalink to
/results/<uuid>) - Enrichment (WHOIS/GeoIP)
- Redirects
- Forms (inputs + per-form rule checks)
- Suspicious Scripts (only scripts that matched rules; badges/tags, snippet)
- Screenshot and Source
- URL Overview (with permalink to
Artifacts for each run live under /data/<uuid>/:
results.json– complete structured result consumed by the UI.source.txt,screenshot.png, and other files as added.
📝 Rules
YAML (regex) Rules
config/suspicious_rules.yaml contains regex rules (compiled IGNORECASE). Example:
- name: eval_usage
description: "Use of eval() in script"
category: script
type: regex
pattern: '\beval\s*\('
severity: high
tags: [obfuscation, unsafe-eval]
Function Rules (code)
Rules needing context (e.g., compare action host to page host) live in:
-
app/rules/function_rules.py:-
FactAdapter– converts snippets to structured facts. -
FunctionRuleAdapter– lets dict-expecting rules run from engine inputs. -
Implementations like:
form_action_missingform_http_on_https_pageform_submits_to_different_hostscript_src_uses_data_or_blobscript_src_has_dangerous_extensionscript_third_party_host
-
They’re registered at startup in app/__init__.py alongside YAML rules.
🔧 Configuration Tips
- Snippet length: tweak
ui.snippet_preview_leninsettings.yaml(default 160). - Rules file override: set
SNEAKYSCOPE_RULES_FILE=/path/to/your.yaml. - Artifacts path: by default
/datain the container (mount via Compose).
📂 Project Structure (high-level)
app/
__init__.py # Flask app factory (loads YAML + function rules)
browser.py # fetch + analysis orchestrator (writes results.json)
routes.py # web views
rules/
function_rules.py # FactAdapter, FunctionRuleAdapter, function rules
utils/
rules_engine.py # engine + Rule class + YAML loader
io_helpers.py # safe_write, etc.
settings.py # get_settings()
templates/ # Jinja2 templates
static/ # CSS/JS
config/
suspicious_rules.yaml # regex rules
docs/
roadmap.md # ongoing plan and priorities
🧭 Roadmap (short version)
Full details: docs/roadmap.md
-
Core Analysis / Stability
- Opt-in fetch external scripts (size/time limits) and evaluate fetched content.
- Remove remaining legacy form “flagged_reasons” once function rules cover them.
- Unit tests: YAML compilation, adapters, per-artifact rule cases.
-
API Layer
- Endpoints:
/screenshot,/source,/analyse - OpenAPI at
/api/openapi.yaml; docs at/docs(Swagger/Redoc)
- Endpoints:
-
UI / UX
- Auto-prepend
http(s):///www.for bare domains - Source viewer (embedded editor)
- Scripts table toggle: “Only suspicious” / “All scripts”
- Rules Lab (WYSIWYG tester) for rapid rule validation
- Auto-prepend
-
Artifact Management & Ops
- Retention/cleanup policy (age/size)
- Periodic maintenance scripts (configurable in
settings.yaml) - Results caching UX (re-run vs. load from cache)
-
Extras / Integrations
- Bulk URL analysis
- Alerting/webhooks (Slack/email)
- Analyst verdict tags + export (CSV/JSON)
🤝 Contributing
This repository is currently private on a self-hosted git server.
- Internal contributors: use feature branches and open merge requests on
https://git.sneakygeek.net/ptarrant/SneakyScope. - If/when the repo is made public, we’ll welcome issues and PRs from the community.
⚠️ Disclaimer
SneakyScope is intended for defensive security analysis and educational use. Only analyze content you are authorized to test.