OWASP Top 10 for Indie Hackers: A No-Nonsense Guide
The OWASP Top 10 without the enterprise jargon. Each category explained for a solo dev shipping a SaaS — what it is, how it bites you, and the one fix that matters.
The Top 10, for a team of one
The OWASP Top 10 is the industry's consensus list of the most critical web app security risks. It's written for enterprises; you're one person shipping a SaaS. Here's each category translated into what actually matters for you — what it is, how it bites, and the highest-leverage fix.
A01: Broken Access Control
The #1 risk, and the one you'll most likely have. A logged-in user accesses data or actions they shouldn't — usually by changing an ID (IDOR).
// Always scope to the owner
const doc = await getDoc(id);
if (doc.ownerId !== session.user.id) return forbidden();
Fix: ownership check on every record access; enforce it server-side (and in RLS if you use Supabase/Firebase). Never trust a client-supplied ID alone.
A02: Cryptographic Failures
Sensitive data exposed because it wasn't protected — secrets in the client bundle, passwords hashed with MD5, traffic over HTTP, PII in plaintext.
Fix: HTTPS everywhere; hash passwords with bcrypt/argon2; keep secrets in env vars; don't log tokens. Use a real auth provider rather than rolling crypto yourself.
A03: Injection
Untrusted input interpreted as code or query — SQL injection, command injection, XSS.
// Parameterize, never interpolate
await db.query("SELECT * FROM users WHERE id = $1", [id]);
Fix: parameterized queries, ORM query builders, output encoding, and a strict CSP for XSS. Validate input on top.
A04: Insecure Design
The flaw is in the plan, not the code — e.g., a password reset with no rate limit, or trusting the client to send the price. You can't patch your way out of a bad design.
Fix: think about abuse cases up front. "What if they call this 10,000 times? What if they change this field?" Design the limit in, not on.
A05: Security Misconfiguration
Default credentials, verbose errors, open cloud buckets, missing headers, test-mode database rules. Extremely common in fast-shipped apps.
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
Fix: set security headers, disable debug/verbose errors in production, lock down BaaS rules, and change every default.
A06: Vulnerable and Outdated Components
A dependency with a known CVE is how a lot of "advanced" breaches actually start.
npm audit --omit=dev
Fix: run audits in CI, patch high/critical promptly, and remove dependencies you don't use.
A07: Identification and Authentication Failures
Weak passwords allowed, no brute-force protection, predictable sessions, broken password reset, user-enumeration oracles.
Fix: use a vetted auth library; rate-limit auth endpoints; return generic "invalid email or password"; expire and rotate sessions; offer MFA.
A08: Software and Data Integrity Failures
Trusting code or data you didn't verify — an unsigned auto-update, an unverified webhook, a compromised CI dependency.
// Verify webhook signatures — never trust the payload alone
const event = stripe.webhooks.constructEvent(rawBody, sig, secret);
Fix: verify signatures on webhooks and updates; pin/lock dependencies; protect your CI/CD secrets.
A09: Security Logging and Monitoring Failures
You can't respond to an attack you can't see. Most indie apps log nothing security-relevant, so a breach is discovered weeks later — by someone else.
Fix: log auth events, admin actions, and access-control failures. Send alerts on anomalies. You don't need a SIEM; you need visibility.
A10: Server-Side Request Forgery (SSRF)
Your server fetches a URL the user controls, and the attacker points it at internal services or cloud metadata endpoints.
// Allowlist outbound destinations; block internal ranges
if (!isAllowedHost(new URL(userUrl).hostname)) throw new Error("Blocked");
Fix: allowlist hosts for any user-supplied URL fetch, and block requests to private/link-local IP ranges and 169.254.169.254.
Your realistic priority order
As a solo dev, you'll most likely have, in order:
- A01 Broken Access Control (IDOR) — check this first.
- A05 Misconfiguration — headers, BaaS rules, debug mode.
- A02 Crypto failures — exposed secrets.
- A03 Injection — string-built SQL, XSS.
- A07 Auth failures — rate limits, enumeration.
Fix those five and you've eliminated the overwhelming majority of real-world risk for an app your size.
Scan it with Troja
Troja maps its findings to the OWASP Top 10 so you can see exactly where you stand on each category — and ships a fix prompt with every issue. Run a scan and turn this list into a clean checklist.
Run the scan this post is about.
Free, no signup. See what's hiding inside your walls in ~30 seconds.
Keep reading
All postsTroja vs. checkvibe: the closest scanner comparison (2026)
checkvibe pioneered security + SEO + AEO scanning with AI fix prompts and a 7-engine matrix. Troja matches it and adds connected deep-stack scans. The honest comparison.
ReadTroja vs. Fixnx: which AI website scanner should you use?
Fixnx runs 100+ AI-powered security, SEO and speed checks with credit-pack pricing. Troja adds AEO, connected deep-stack scans and per-finding AI fixes. Compared.
ReadTroja vs. CyScan.io: recon tool vs. fix-it scanner
CyScan.io is a free attack-surface recon scanner — endpoints, subdomains, fuzzing, screenshots. Troja is a fix-and-ship scanner with AI fixes, AEO and deep-stack scans.
Read