← Overnight Audit · sample report

microblog · Overnight Audit

This is a public sample report. Forgehaven Labs ran the Overnight Audit process against miguelgrinberg/microblog, the MIT-licensed companion repo to the Flask Mega-Tutorial, to show what a paying customer receives. This is teaching code and it is excellent at that job. We audit it here as if a developer had forked it toward production, which is exactly how thousands of people use it. Every finding is reproducible from Section 7.

Prepared for: Public sample (miguelgrinberg/microblog, unsolicited)

Prepared by: Forgehaven Labs LLC · forgehavenlabs.com/audit

Date: 2026-07-01 · Turnaround: sample (process normally completes in under 24 h)

Tier: Repo Audit ($149)

Scope: github.com/miguelgrinberg/microblog @ a975ef6 (default branch, 2025-04-06)

1. The verdict (read this first)

Overall grade: C+ (as production code) / A (as a tutorial) · Clean, idiomatic Flask with proper password hashing and CSRF protection. The gap between "great tutorial" and "safe to deploy" is two things: a weak default secret that, if it survives to production, makes password-reset tokens and session cookies forgeable, and a dependency set frozen in late 2023 where 17 of 54 pinned packages now carry published CVEs, including two HIGH request-smuggling issues in the WSGI server you deploy behind.

If you fix only one thing: guarantee SECRET_KEY is set from a strong random env var in every deployed environment and make the app refuse to boot without it (Section 3, P0-1). That single change closes an account-takeover path.

2. Scorecard

AreaGradeOne-line summary
SecurityCPassword hashing + CSRF are correct; the weak SECRET_KEY fallback and an unignored .env are the risks
Correctness & error handlingA-Idiomatic SQLAlchemy 2.0, sensible token expiry, clean auth flow
Dependencies & supply chainD17 of 54 pinned deps have CVEs (2 HIGH in gunicorn, RCE-class in Werkzeug debugger)
Build, test & CIBtests.py present with real unit tests; CI wiring is minimal
Code health & maintainabilityASmall, readable, blueprint-structured, well-commented
Docs & onboardingAREADME + the tutorial itself are best-in-class

Verification statement: the CVE list is authoritative OSV.dev data queried live against the exact pinned versions in requirements.txt; the secret-key and .env findings are confirmed against the source and git check-ignore. Section 7 lists every command.

3. Findings

Severity: P0 fix before you ship · P1 fix this month · P2 fix when nearby · P3 note.

P0-1 · Weak fallback SECRET_KEY makes reset tokens and sessions forgeable if it reaches production

P1-1 · .env is not git-ignored; the README tells you to put secrets in it

P1-2 · Dependencies frozen at late-2023 versions; 17 of 54 now carry published CVEs

P2-1 · No session-cookie hardening configured

P2-2 · ADMINS still points at the placeholder address

P3-1 · Things we checked that are NOT problems (so you can stop worrying about them)

5. The fix plan (next 30 days)

Session 1, 1 h (stop the bleeding): Require SECRET_KEY in production and fail fast (P0-1); add .env to .gitignore and ship .env.example (P1-1).
Session 2, half day (this month): Regenerate requirements.txt against current releases, re-run tests.py, add scheduled dependency scanning (P1-2).
Later / opportunistic: Session-cookie hardening (P2-1); real ADMINS from env (P2-2).
Explicitly fine to ignore: The Gravatar md5 and the os.system babel calls (P3-1).

6. Quick wins (under 30 minutes each)

7. What we checked (methodology & reproducibility)

Fleet + human: an automated agent fleet ran the passes below on a fresh clone of a975ef6; a human engineer reviewed and reproduced every finding.

PassKey commands (run on a fresh clone)
Secrets & config reviewread config.py; traced SECRET_KEY usage to app/models.py:181-190
Gitignore checkgit check-ignore .env (→ not ignored); read .gitignore
Dependency scanOSV.dev POST /v1/querybatch over all 54 pinned versions in requirements.txt
Advisory severitiesOSV.dev GET /v1/vulns/<GHSA> for the top issues
Auth/crypto reviewread app/models.py, app/auth/routes.py, app/api/auth.py
False-positive triageverified md5 = Gravatar, os.system = fixed babel strings

Limits (honest): we did not execute tests.py in-sandbox. This host runs an externally-managed Python with no quick virtualenv path, and the suite pulls heavy optional services (Elasticsearch, Redis/RQ). The dependency findings come from OSV.dev against the exact pins, not from a runtime exploit; the secret-key and .env findings are confirmed from source and git. On a paid engagement we stand up a throwaway venv and run your suite. No penetration test or load test was performed.

8. Appendix: raw evidence

A-1: OSV.dev advisories by pinned package (2026-07-01):

aiosmtpd==1.4.4.post2   GHSA-pr2m-px7j-xg65, GHSA-wgjv-9j3q-jhg8, PYSEC-2024-221
certifi==2023.11.17     GHSA-248v-346w-9cwc, PYSEC-2024-230
dnspython==2.4.2        GHSA-3rq5-2g8h-59hc
Flask==3.0.0            GHSA-68rp-wp8r-4726
Flask-HTTPAuth==4.8.0   GHSA-p44q-vqpr-4xmg
gunicorn==21.2.0        GHSA-hc5x-x2vx-497g (HIGH), GHSA-w3h3-4rj7-4ph4 (HIGH)
httpie==3.2.2           GHSA-8r96-8889-qg2x, PYSEC-2023-242
idna==3.4               GHSA-65pc-fj4g-8rjx, GHSA-jjg7-2v4v-x38h, +2
Jinja2==3.1.2           GHSA-cpwx-vrp4-4pq7, +4
Mako==1.3.0             GHSA-2h4p-vjrc-8xpq, +2
Pygments==2.17.1        GHSA-5239-wwwm-4pmq
PyJWT==2.8.0            GHSA-752w-5fwx-jx9f, +10
python-dotenv==1.0.0    GHSA-mf9w-mj56-hr94
requests==2.31.0        GHSA-9wx4-h78v-vm56, +2
setuptools==68.2.2      GHSA-5rjg-fvgr-3xxf, GHSA-cx63-2mw6-8hw5, PYSEC-2025-49
urllib3==2.1.0          GHSA-2xpw-w6gg-jr37, +6
Werkzeug==3.0.1         GHSA-2g68-c3qc-8985 (HIGH debugger RCE), +5

Forgehaven Labs LLC · Overnight Audit · fixed price, 24-hour turnaround.
Want this run against your repo? forgehavenlabs.com/audit