· 12 min read · cybersecurity · application security · startups

Application Security Checklist for SaaS Startups

A prioritised security checklist for early-stage SaaS teams: auth, access control, secrets, dependencies, headers, logging, backups and pen testing.

Ten Peaks Tech

Most early-stage SaaS products are not insecure because the team is careless. They’re insecure because security work has no deadline attached to it. Features have launch dates, investors have board meetings, customers have renewal dates — and “tighten up our access control” sits on the backlog until something forces it up the list. Usually that something is a security questionnaire from a customer who wants to spend real money with you.

This checklist is for technical founders, first engineering hires, and small teams running a multi-tenant SaaS product in production. It assumes you have a web application, a database with customer data in it, a cloud account, and somewhere between two and fifteen engineers. It doesn’t assume you have a security team, a compliance programme, or budget for enterprise tooling.

The aim is to give you an order of operations. Everything here matters eventually, but not everything matters this week. We’ve split the work into three tiers: things that should be true before you have a single paying customer, things to fix in your next quarter, and things you’ll need in place before an enterprise buyer signs.


What Actually Goes Wrong

Breaches at small SaaS companies are rarely exotic. The recurring patterns are broken access control (a user changes an ID in a URL and sees someone else’s data), leaked credentials (an API key in a repository, a .env file in a public bucket), and unpatched dependencies with known exploits.

The OWASP Top 10 — a widely used community list of the most critical web application security risks — reflects this. Broken access control and injection flaws have sat near the top of it for years, and the list consistently emphasises design and configuration failures over novel attacks. Fix the boring things and you eliminate most of your realistic risk.


Authentication and Session Handling

Authentication is the area teams most often build themselves and most often get subtly wrong.

Should you build your own auth?

For most SaaS startups, no. A managed identity provider gives you password hashing, rate limiting, MFA, account recovery, session management and audit logging as a product rather than a project. If you do build it, use a purpose-built password hashing algorithm — bcrypt, scrypt or Argon2 — never a general-purpose hash like SHA-256, salted or not.

Beyond hashing:

  • Enforce rate limiting and lockout on login, password reset and MFA endpoints. Credential stuffing is automated and cheap.
  • Offer MFA. You needn’t force it on everyone on day one, but you should be able to enforce it per-tenant when an enterprise customer asks.
  • Store sessions in HttpOnly, Secure, SameSite cookies. If you keep JWTs in local storage, any cross-site scripting bug becomes a full account takeover.
  • Invalidate sessions on password change, and let users see and revoke active sessions.
  • Make password reset tokens single-use, short-lived and unguessable, and don’t reveal whether an email address exists in reset or signup responses.

Authorisation: The One That Bites Hardest

Authentication asks “who are you?” Authorisation asks “are you allowed to do this?” The second question is harder, and it is where multi-tenant SaaS products leak.

The classic failure is an insecure direct object reference (IDOR): your endpoint is /api/invoices/8412, a logged-in user changes the number, and your handler fetches by ID without checking which tenant owns the record. The user is perfectly authenticated. They’re just reading someone else’s data.

How do you prevent it structurally?

Don’t rely on developers remembering a check. Make the check the default:

  • Scope every query to the tenant. Fetch by (id, tenant_id), never by id alone. Put this in a repository layer or ORM scope so the unscoped version isn’t the convenient one.
  • Consider row-level security at the database layer if your stack supports it. It gives you a backstop when application code forgets.
  • Deny by default. New endpoints should require an explicit authorisation decision, not inherit permission by omission.
  • Check authorisation on the server for every request, including ones the UI “can’t” produce. Hiding a button is not access control.
  • Test it. A handful of integration tests where user A tries to read user B’s resources catches an entire class of regression.

Also check your object identifiers. Sequential integers make enumeration trivial and leak volume information to competitors. UUIDs don’t fix broken authorisation, but they remove the easy first probe.


Input Validation and Injection

Injection happens when data gets interpreted as code. The defence is the same everywhere: keep data and instructions separate.

  • SQL: use parameterised queries or an ORM’s binding. Never build SQL with string interpolation, including for ORDER BY and table names — allowlist those instead.
  • Command execution: avoid shelling out with user input at all. If you must, pass arguments as an array rather than a concatenated string.
  • Cross-site scripting: rely on your framework’s contextual escaping and treat every dangerouslySetInnerHTML-style escape hatch as needing a reviewer. Sanitise rich text server-side with a maintained library.
  • Server-side request forgery: if your product fetches user-supplied URLs (webhooks, image imports, link previews), block private IP ranges and cloud metadata endpoints, and resolve DNS before validating.
  • File uploads: validate type by content, store in object storage rather than the web root, generate your own filenames, and serve downloads from a domain that can’t execute scripts against your session cookies.

Validate at the boundary with a schema, and validate on output too — what you store is not necessarily safe in every context you later render it in.


Secrets Management

Secrets sprawl quietly. A key gets pasted into a config file to unblock a deploy, the file gets committed, and eighteen months later nobody can remember which of forty keys are live.

  • Keep secrets out of the repository — use your cloud provider’s secret manager or your platform’s environment variable store.
  • Add secret scanning to CI and pre-commit hooks so a leak is caught in minutes rather than never.
  • Rotate anything ever committed, logged or shared in chat. Assume it is public.
  • Give each environment and service its own credentials so revocation is surgical.
  • Scope keys to the narrowest permission that works. A read-only key in a client-side bundle is a footnote; an admin key there is a company-ending event.

Dependencies and Supply Chain

Your application is mostly other people’s code. Treat it that way.

  • Enable automated dependency update pull requests, and actually merge them. A backlog of 200 outdated packages is unpatchable in a crisis.
  • Run a vulnerability scan in CI and fail the build on high-severity issues in production dependencies.
  • Commit your lockfile and use npm ci-style installs so builds are reproducible.
  • Be deliberate about adding dependencies. Every package is a transitive trust decision, and the ones with the fewest maintainers and the most install scripts deserve the most scrutiny.
  • Pin, rebuild and scan container base images too. Application patches don’t fix an unpatched OS layer.

Security Headers and CSP

Headers are the highest ratio of protection to effort in this entire list.

HeaderWhat it does
Strict-Transport-SecurityForces HTTPS for future visits, blocking downgrade attacks
Content-Security-PolicyRestricts where scripts, styles and connections may come from
X-Content-Type-Options: nosniffStops browsers guessing content types
Referrer-PolicyPrevents leaking URLs (and any IDs in them) to third parties
Permissions-PolicyTurns off browser features you don’t use, like camera or geolocation

The content security policy is the one that takes real effort, because inline scripts and third-party tags will break. Start in report-only mode, collect violations for a couple of weeks, then enforce. Prefer nonces over broad allowlists, and resist unsafe-inline — it removes most of the protection you were buying. Configure CORS deliberately too: reflecting the Origin header back with credentials allowed is effectively no policy at all.


Logging, Monitoring and Incident Readiness

You cannot investigate what you didn’t record, and you cannot respond to what you never noticed.

  • Log authentication events, authorisation failures, permission changes, data exports and administrative actions — with actor, timestamp, source IP and target resource.
  • Never log passwords, tokens or request bodies containing personal data. Redact at the logging layer, not by asking developers to be careful.
  • Ship logs off the machine that produced them. Thirty days’ retention is a reasonable floor; enterprise buyers often ask for a year.
  • Alert on signs of compromise rather than signs of traffic: spikes in 403s, bulk data exports, new admin users, logins from unusual geographies.
  • Write a one-page incident plan now: who declares an incident, who talks to customers, where you communicate if your own systems are down, and what your notification obligations are. It needs to exist before you need it.

Backups you’ve actually tested

Backups are a security control, because ransomware and destructive mistakes are security events. Automate them, keep at least one copy in a separate account with separate credentials, encrypt them, and — the part everyone skips — restore one into a scratch environment on a schedule. An untested backup is a hypothesis.


Cloud and IAM Basics

  • No long-lived static keys for workloads. Use your provider’s workload identity mechanism so services get short-lived credentials automatically.
  • Separate accounts or projects per environment. A compromised staging deploy should not reach production data.
  • Turn on account-level logging and threat detection. It’s cheap relative to the alternative.
  • Keep databases and internal services off the public internet — private networking plus a bastion or identity-aware proxy, not a hand-maintained IP allowlist.
  • Enforce MFA on every human account in the cloud console, source control, your domain registrar and your email. Domain and email takeover bypasses everything else you’ve built.
  • Encrypt data at rest and in transit. Mostly a default now, but confirm rather than assume, especially for backups and analytics pipelines.

When Should You Get a Penetration Test?

A pen test is a point-in-time expert attempt to break your application. It’s genuinely useful, but it’s wasted money if you commission it before you’ve done the obvious work — you’ll pay a specialist to tell you your dependencies are old.

Get one when you’ve completed the “do first” and “do next” tiers below and one of these is true: you’re storing genuinely sensitive data, a customer’s procurement process requires a report, you’ve made a major architectural change, or you’re heading into a funding round or acquisition. Annually thereafter is a reasonable cadence, with automated scanning continuously in between.

When you commission one, agree scope in writing, insist on a retest after remediation, and give the tester credentials for a realistic environment — that finds far more than an unauthenticated scan of a login page.


The Prioritised Checklist

PriorityControlDone when
Do firstHTTPS everywhere with HSTSHTTP redirects, no mixed content
Do firstSecrets out of source controlScanner in CI, exposed keys rotated
Do firstTenant-scoped data accessQueries filter by tenant; tests prove it
Do firstParameterised queries throughoutNo string-built SQL in the codebase
Do firstMFA on cloud, repo, registrar, emailEnforced for all admins
Do firstAutomated, off-account backupsOne restore successfully tested
Do firstRate limiting on auth endpointsBrute force blocked and alerted
Do nextDependency scanning and updatesCI fails on high-severity issues
Do nextSecurity headers and CSPCSP enforced, not report-only
Do nextCentralised, redacted audit loggingSecurity events queryable for 30+ days
Do nextLeast-privilege IAM per environmentNo shared admin credentials
Do nextAlerting on suspicious behaviourSomeone gets paged, not emailed
Do nextWritten incident response planOne page, owned, rehearsed once
Before enterpriseThird-party penetration testReport plus completed remediation
Before enterpriseCustomer-facing MFA and SSOSAML or OIDC available per tenant
Before enterpriseTenant audit logs and data exportCustomers can self-serve evidence
Before enterpriseVendor and sub-processor registerMaintained and published
Before enterpriseFormal certification if requiredScope agreed, evidence collection running

The last row is deliberately vague, because the right answer depends on your market. UK buyers often ask about Cyber Essentials, a government-backed scheme covering baseline technical controls such as firewalls, secure configuration, access control, malware protection and patching. US enterprise buyers more often ask for a SOC 2 report, an audit against trust services criteria covering security and optionally availability, confidentiality, processing integrity and privacy. None of these make you secure on their own — they make your existing practices legible to a buyer.


Common Mistakes

Confusing compliance with security. You can pass an audit with genuinely dangerous authorisation bugs. The audit checks that you do what you said you’d do.

Ignoring internal tooling. Admin panels, support impersonation and internal dashboards routinely have weaker controls than the customer-facing product while holding far more access. If you have impersonation, log every use of it and make it visible to the customer.


How Ten Peaks Tech Can Help

We run application security reviews for SaaS teams — working through the areas above against your actual codebase and cloud setup, then handing back a prioritised remediation plan rather than a raw scanner dump. If you’d rather build the practices in as you go, our cybersecurity services and fractional CTO work both cover that.

Related reading: What Does a Fractional CTO Do?, Technical Due Diligence: What Investors and Acquirers Should Check, and Prompt Injection: How to Protect LLM-Powered Apps if your product has an AI feature.

Keep reading

· 10 min read

Prompt Injection: How to Protect LLM-Powered Apps

What prompt injection is, why prompts alone can't fix it, realistic attacks on RAG and agent systems, and a defence-in-depth checklist for engineers.

AI securitycybersecurityLLM

Tell us what you’re building.

A senior engineer replies within one business day.