Security checklist for a side project before launch
A pre-launch security checklist for side projects, mapped to the OWASP Top 10:2025: secrets, auth, access control, dependencies, headers, backups and accounts.
A side project does not need an enterprise security program, but it does need the basics, because automated scanners do not care how small your app is. This checklist covers what a solo developer can realistically do before launch, grouped by area and mapped to the OWASP Top 10:2025 categories so you can read further where needed.
It is based on OWASP publications and official platform documentation. Treat it as a minimum, not a guarantee.
The OWASP Top 10:2025 at a glance
| ID | Category | What it means for a small app |
|---|---|---|
| A01 | Broken Access Control | Users can see or change data that is not theirs |
| A02 | Security Misconfiguration | Debug mode, default credentials, open storage buckets |
| A03 | Software Supply Chain Failures | Compromised or vulnerable dependencies and build tools |
| A04 | Cryptographic Failures | Plain-text passwords, no TLS, weak or home-made crypto |
| A05 | Injection | SQL, command or template injection from user input |
| A06 | Insecure Design | Missing limits and abuse cases in the design itself |
| A07 | Authentication Failures | Weak login, session handling, credential stuffing |
| A08 | Software or Data Integrity Failures | Unsigned updates, unsafe deserialization, untrusted CI |
| A09 | Security Logging and Alerting Failures | Attacks happen and nobody notices |
| A10 | Mishandling of Exceptional Conditions | Errors that leak data or fail open |
1. Secrets (A02, A04)
- No secrets in the repository, including history. Use the host’s environment variables or a secrets manager
-
.envfiles are in.gitignore, and an.env.examplewith empty values documents what is needed - GitHub secret scanning and push protection enabled on the repository
- Separate API keys for development and production; production keys only on the server
- Rotate any key that was ever committed, pasted in a chat or shared in a screenshot
2. Authentication (A07)
- Prefer a proven auth provider or framework library over writing your own
- If you store passwords, hash them with a slow, salted algorithm recommended by OWASP’s Password Storage Cheat Sheet (Argon2id, scrypt or bcrypt), never a plain hash like SHA-256
- Rate-limit login, sign-up and password reset endpoints
- Password reset tokens are single-use and expire
- Session cookies use
Secure,HttpOnlyandSameSite=Lax(orStrict) - Offer or require two-factor authentication for admin accounts
3. Access control (A01)
This is the top category for a reason, and it is the one automated tools catch least.
- Every API endpoint checks that the current user owns the resource, not just that someone is logged in
- IDs in URLs are not trusted:
/api/invoices/123checks that invoice 123 belongs to the user - Admin routes are protected server-side, not only hidden in the UI
- Deny by default: new endpoints require auth unless explicitly public
- Write one test per sensitive endpoint that tries to access another user’s data
Worked example. A common bug looks like this:
// Vulnerable: any logged-in user can read any invoice
app.get('/api/invoices/:id', requireLogin, async (req, res) => {
res.json(await db.invoice.findUnique({ where: { id: req.params.id } }));
});
// Fixed: scope the query to the current user
app.get('/api/invoices/:id', requireLogin, async (req, res) => {
const invoice = await db.invoice.findFirst({
where: { id: req.params.id, userId: req.user.id },
});
if (!invoice) return res.sendStatus(404);
res.json(invoice);
});
4. Input handling (A05)
- Use parameterized queries or an ORM; never build SQL with string concatenation
- Validate request bodies against a schema (type, length, allowed values)
- Escape output by default (most modern templating and UI frameworks do this; avoid raw-HTML escape hatches)
- Never pass user input to a shell command
- Limit upload size and type, and store uploads outside the web root or in object storage
5. Dependencies and build (A03, A08)
- Commit the lockfile and install with
npm ci(or your ecosystem’s equivalent) in CI and production - Turn on automated dependency alerts and updates (for example, Dependabot)
- Run
npm audit(or equivalent) before launch and fix high-severity issues - Remove unused dependencies; each one is attack surface
- Pin third-party GitHub Actions to a version or commit, and give CI tokens the least privilege needed
6. Configuration and transport (A02, A04)
- HTTPS everywhere, with HTTP redirecting to HTTPS
- Debug mode and verbose error pages are off in production
- Security headers set:
Content-Security-Policy(start simple),X-Content-Type-Options: nosniff,Referrer-Policy, andStrict-Transport-Securityonce HTTPS is stable - CORS allows only your own origins, not
*for authenticated APIs - Storage buckets are private unless they intentionally serve public files
- Default credentials changed on every database, dashboard and admin panel
- Database not exposed to the public internet (or restricted to your app’s IPs)
7. Errors, logging and alerts (A09, A10)
- Errors return a generic message to users and the detail only to your logs
- Failures fail closed: if a permission check throws, access is denied
- Log logins, failed logins, password resets and permission errors, without logging passwords or tokens
- Error tracking and uptime alerts go to an address you actually read
8. Abuse and design (A06)
- Rate limits on anything that costs you money (email sending, AI calls, SMS, file processing)
- Hard caps or billing alerts on every paid API and cloud account
- Sign-up abuse considered: email verification, CAPTCHA only if needed
- A way to disable a user or feature quickly without a deploy
9. Accounts around the app
Attackers often skip the app and target the accounts that control it.
- Two-factor authentication on your registrar, DNS, hosting, Git host, email, payment provider and app store accounts
- Registrar lock enabled on the domain
- Recovery codes stored offline
- The business email account is separate from personal accounts
10. Backups and recovery
- Automated daily database backups stored outside the primary provider or region
- One test restore done and timed
- A short written runbook: how to redeploy, rotate keys and restore data
Pre-launch quick pass (one evening)
If you only have a few hours, do these in order:
- Search the repo and its history for secrets; rotate anything found
- Check every endpoint for ownership checks (A01)
- Enable 2FA on registrar, hosting, Git and payment accounts
- Turn on dependency alerts and run an audit
- Confirm backups exist and restore one
- Set billing alerts
Static site extras
If part of your project is a static site, a few settings close the remaining gaps:
- Set security headers at the host or CDN (most static hosts support a headers file or dashboard rules)
- Load third-party scripts only from sources you trust, and as few as possible
- Keep the build pipeline secure: dependency alerts and protected main branch
- Protect the Git host and hosting accounts with 2FA, since anyone with push access can change the live site
What to do if something goes wrong
Even with the checklist done, plan for an incident. A short, written plan saves panic:
- Contain. Rotate the affected keys, revoke sessions, and disable the vulnerable feature or endpoint.
- Assess. Use your logs to work out what was accessed and when. This is where A09 (logging and alerting) pays off.
- Fix and deploy. Patch the root cause, not just the symptom, and add a test that would have caught it.
- Notify. If personal data of users in the EEA or UK was affected, GDPR breach-notification rules may apply, including notifying the data protection authority within 72 hours in many cases. Check the rules that apply to you.
- Review. Write down what happened and what changed, even if you are the only reader.
FAQ
Is a static site safe by default? It removes most server-side risk: there is no database or login to attack. The remaining risks are the accounts that control it (Git host, hosting, DNS, registrar) and any third-party scripts you embed.
Should I pay for a penetration test before launch? For a small side project, the checklist above, dependency scanning and careful access-control tests usually come first. A professional test makes sense once you handle sensitive data or have paying business customers who ask for it.
Sources
- OWASP Top 10:2025
- OWASP Password Storage Cheat Sheet
- OWASP Authorization Cheat Sheet
- OWASP HTTP Security Response Headers Cheat Sheet
- GitHub Docs: About secret scanning
- GitHub Docs: About Dependabot alerts
- npm Docs: npm audit
- MDN: Set-Cookie
- General Data Protection Regulation (EU) 2016/679, Article 33
Last verified: . Prices, limits and policies come from the official pages listed under Sources, not from hands-on testing. Providers change them often, so confirm on the provider's own page before you buy. Spotted something out of date? Tell us.