JB logo
CoffeeyOUTUBE
JB's avatarUgandan flag

JB 

Muke Johnbaptist

Go (Golang) expert · Creator of the Grit Framework

Blog
Next

How to Run a Penetration Test on Your App with Scout

A practical guide to finding your app's vulnerabilities and mapping its attack surface with Scout — the self-hosted, open-source Go vulnerability scanner. Install it, run a safe scan, read the A–F grade, mount the dashboard, gate CI with SARIF, and set up continuous monitoring — all against systems you're authorized to test.

Most penetration tests start the same way: before you touch a single exploit, you map the target and find the low-hanging fruit — missing security headers, weak TLS, exposed config, leaked secrets, open ports. That reconnaissance-and-scanning phase is exactly what Scout automates. Scout is a self-hosted, open-source vulnerability scanner and attack-surface mapper for developers: point it at a running app, a website, or a repo, and it merges every finding into one model, scores it into a letter grade, and suggests a stack-specific fix for each issue.

It's built in Go (Gin) with an embedded React dashboard, it's MIT-licensed, and it's part of the same family as Sentinel (security middleware) and Pulse (observability).

Authorized testing only. Run Scout against systems you own or have explicit written permission to test. Scanning someone else's app without authorization is illegal in most jurisdictions. Scout is deliberately safe by default — read-only unless you opt in — and it requires ownership verification before it will run an active scan. Keep it that way.

What phase of a pentest does Scout cover?

A full penetration test runs through recon → scanning → exploitation → reporting. Scout focuses on the first two and the last one:

  • Reconnaissance & attack-surface mapping — what hosts, services, routes and resources are exposed.
  • Vulnerability scanning — security misconfigurations, weak transport security, secrets, container issues.
  • Reporting — findings with evidence, a grade, and prioritized fixes.

Active input testing (SQLi, XSS, SSRF), auth/access-control checks (JWT, IDOR, CORS), Nuclei, and dependency-CVE/SAST/container scanning are on the roadmap but not yet in the current release (v0.x) — so treat Scout as the fast, automated front half of your engagement, not a replacement for manual exploitation.

1. Install

Install the CLI with Go:

go install github.com/MUKE-coder/scout/cmd/scout@latest
scout version

To embed the dashboard inside a Gin app, add it as a library instead:

go get github.com/MUKE-coder/scout

Building from source:

go build ./...
go test ./...

2. Run your first scan (safe & read-only)

Point Scout at a target. By default the scan is safe — it only reads, never sends anything that could change state:

scout scan --target https://example.com

Scout runs its collectors, merges the results, and prints findings with a score and an A–F grade. Because the default mode is read-only, this is safe to run against your own production site.

3. Read the results: findings, score, and grade

Every finding carries severity, confidence, evidence, a suggested fix, and a stable fingerprint. The fingerprint is what lets Scout track an issue across scans — so it can tell you which findings are new, which were fixed, and which regressed.

Scout rolls findings into a 0–100 score and an A–F grade, where a single serious flaw caps the whole grade (one critical hole means you don't get an A, no matter how clean the rest is). Fixes are then ranked by points regained per hour of work, so you always know what to do next for the biggest security win.

SignalWhat it tells you
SeverityHow bad the issue is if exploited
ConfidenceHow sure Scout is it's real
EvidenceThe exact request/response or snippet that proves it
FingerprintStable ID for tracking new / fixed / regressed
Score & grade0–100 and A–F, capped by your worst flaw

4. Scan modes and environment caps

Scout has four scan modes and environment caps so you can't accidentally hammer production:

  • Modes: passive, safe, active, intrusive — increasing in how much they probe.
  • Environments: dev, staging, prod — each caps what a mode is allowed to do.

Anything beyond read-only against a real target needs explicit opt-in. First, dry-run an active scan to see what would be sent without sending it:

scout scan --target https://example.com --mode active --env prod --dry-run

To actually run an active scan against a site you own, verify ownership first (via a DNS TXT record or a /.well-known/scout-verify.txt file), then pass the explicit flag:

scout ownership --target https://example.com
scout scan --target https://example.com --mode active --allow-active

This ownership gate is the guardrail that keeps Scout an authorized-testing tool.

5. Scan a repo, not just a URL

Scout can analyze source as well as a running target — useful for catching issues before they ship:

scout scan --target .

Against a repo it adds secret scanning (leaked keys and tokens) and Dockerfile linting on top of the network checks.

6. What Scout detects today

As of v0.3.0 Scout ships nine collectors / 35 checks:

CollectorLooks for
HTTP security headersMissing/weak CSP, HSTS, X-Frame-Options, etc.
TLS configurationWeak protocols, ciphers, cert issues
DNS & email recordsSPF/DKIM/DMARC and DNS hygiene
Exposed resourcesLeaked config and sensitive files
GET-only crawlerPages, forms, CSRF signals, endpoints
Port scanningServices exposed to the internet
Secret scanning (repos)Keys and tokens committed to source
Dockerfile lintingInsecure container build practices
Gin route auditRoutes missing auth middleware — flagged before any traffic is sent

The crawler is GET-only by design, so mapping your site never triggers state changes.

7. Mount the embedded dashboard

If your app is a Gin service, Scout mounts a full React 19 dashboard in one line:

scout.Mount(r, scout.Config{AppName: "My API"})

The dashboard lives at /scout/ui/ (dark and light themes) and gives you:

  • Overview — grade, 30-day trend, category subscores, and "Fix-next"
  • Findings — filters, bulk actions, an evidence panel, and "Verify fix" to re-run one check
  • Live scan — per-collector progress over WebSocket, plus a kill switch
  • History — compare any two scans
  • Attack surface — an interactive map of domains, hosts, services and routes
  • Compliance — an OWASP Top 10 heatmap and ASVS coverage
  • Settings — effective config, exports, reports, and a danger zone

Dashboard auth is JWT with login rate limiting. The default admin / scout credentials apply only in dev — everywhere else you must set SCOUT_USERNAME and SCOUT_PASSWORD.

8. Gate your CI

Fail a build when a scan finds something serious — and only on new issues, so you don't block on pre-existing debt:

scout ci --repo . --fail-on high --new-only --sarif scout.sarif

The SARIF output drops straight into GitHub's Security tab, so findings show up as code-scanning alerts on the PR.

9. Continuous monitoring & alerts

Run Scout as a long-lived server to keep scanning over time:

scout serve --addr :9090 --db scout.db

From there you get scheduled scans, a kill switch, and alerts to Slack, Discord, email, and HMAC-signed webhooks when new issues appear. Optional integrations feed data to Pulse and Sentinel, and optional AI explanations (via the Vercel AI Gateway) are redacted before anything leaves your machine.

10. Reports and diffing

Compare two scans by their IDs to see exactly what changed:

scout diff 3f2a9c 9b1c04

And generate a shareable report for the team or the client:

scout report --out report.html

Outputs include JSON, SARIF, an HTML report, JSON/CSV export, and PDF via browser print — plus accepted-risk muting with an expiry date, so a risk you've consciously accepted doesn't keep nagging you (but doesn't silently disappear forever either).

A responsible workflow

Put together, a clean Scout-driven security pass looks like this:

  1. Authorize & scope. Confirm in writing that you may test the target. Set the right --env.
  2. Map safely. Run the default read-only scan to map the attack surface and catch config/TLS/header/secret issues.
  3. Verify ownership, then go active only if your engagement calls for it and only after scout ownership.
  4. Triage by impact. Work the "Fix-next" list — points regained per hour.
  5. Verify fixes in the dashboard, then diff against the previous scan to prove regressions are gone.
  6. Gate CI so the same class of issue can't come back.
  7. Report with evidence for the team or the client.

Where Scout fits

Scout won't replace a skilled human doing manual exploitation — and it doesn't claim to. What it does is make the repetitive, automatable 80% of a security pass fast, repeatable, self-hosted and free: map the surface, grade it, tell you what to fix first, and keep watching. Pair it with Sentinel at runtime and you've got scanning and defense from the same Go stack.

Star or fork it on GitHub, and remember the one rule: only point it at what you're allowed to test.