Design

Laravel security: the rules that actually get broken

A working checklist for developers shipping Laravel applications — the settings, defaults and habits that decide whether an app leaks.

14 min readBy Zasya Engineering team

This is for developers writing Laravel applications. If you are the person buying or commissioning the build rather than writing it, the companion piece — what to require from a team building your backend — covers the same ground in terms you can hold a supplier to.

Almost nothing below is obscure. These are the rules that get broken under deadline, in a hurry, or by someone who assumed the framework had already handled it.

The short version

If you remember nothing else from this guide, remember these:

  1. Debug mode off in production, and no debugging or queue dashboards reachable.
  2. Every route that touches user data has an authorization check — not merely a login check.
  3. Validate through a form request, then persist only the validated data. Never the whole request.
  4. Never build SQL by concatenating strings.
  5. Use escaped output in templates. Unescaped output only ever with a sanitiser.
  6. Leave CSRF protection and cookie flags on. Nothing about this is temporary.
  7. Hash passwords. Never encrypt them.
  8. Rate limit login and anything expensive.
  9. Private files belong on a private disk, never in the public directory.
  10. Never log passwords, tokens or card numbers.

Setup, once per project

With debug mode on, any error page shows environment variables — database passwords, API keys — to whoever triggered the error. It does not take an attacker to trigger it; it takes a typo in a URL.

The application key must be unique per environment. It encrypts sessions and cookies, so if staging and production share one, anyone who can log into staging can forge a production session.

Note that the security configuration moved between Laravel 10 and 11 — middleware, CSRF exceptions and trusted proxies all live somewhere new. Treat that file as sensitive whichever version you are on: a one-line change can switch off protection for the entire application, and it reads as boilerplate in a diff.

Headers, and why each one is there

  • HSTS — the browser refuses to talk to the site over plain HTTP, so a login page cannot be downgraded.
  • No-sniff — stops the browser guessing that an uploaded file is HTML and executing it.
  • Frame options — stops the site being loaded in an invisible frame on someone else's page.
  • Referrer policy — stops URLs, which may contain tokens, leaking to third-party scripts.

Keep debugging tools out of production

Request-recording tools capture request bodies — including passwords and one-time codes — and serve them over HTTP. Queue dashboards let anyone retry or delete jobs. After every deploy, confirm that those routes, the environment file and the version-control directory all return 403 or 404. This is a thirty-second check that has caught real incidents.

Authentication

Never encrypt a password, and never use a fast general-purpose hash for one. Encryption can be reversed — that is the entire problem. Use the framework's password hashing.

Define the password policy once. If signup, reset and admin-create each carry their own rules, the weakest of them is your real policy.

Regenerate the session on login. The framework's own attempt helper does this for you, but a custom login — a magic link, an SSO callback, impersonation — must do it explicitly. Without it, a session identifier an attacker planted before login stays valid afterwards, as that user.

Rate limit login on two axes, not one: per-IP alone is defeated by rotating proxies, and per-account alone lets one attacker work through many accounts.

Do not leak which accounts exist. One generic message for a wrong address and a wrong password; password reset always says that if the address exists, a link has been sent. Otherwise the login form becomes a tool for enumerating your users.

Administrators need more: a separate guard, two-factor authentication, and a shorter session lifetime. An admin account can read every user's data, and a password alone is not proportionate protection for that.

Authorization is not authentication

This is the single most common real-world hole. A route checks that someone is logged in, and never checks that this particular user may see this particular record. Changing an identifier in the URL then returns somebody else's data.

Every route that reads or writes user-owned data needs an explicit ownership or permission check, expressed in one place rather than repeated inline where one copy will eventually be missed.

Input, output and storage

  • Validate with a form request and persist only the validated result. Passing the entire request into a model is how fields nobody intended to expose get written.
  • Use the query builder or parameter binding. Concatenated SQL is the oldest vulnerability there is and it still ships.
  • Escape template output by default; unescaped output only through a sanitiser, never on user-supplied content.
  • Private files go on a private disk with access mediated by the application. A file in the public directory is public, whatever the filename.
  • Never log secrets. Logs get shipped to third-party services, opened in support tickets and pasted into chat.

Before release

A short pre-release pass catches most of what matters: debug off, dashboards unreachable, headers present, every data route authorization-checked, rate limits on login and anything expensive, no secrets in logs, private files on a private disk, and dependencies updated.

None of this is exotic. It is a list, run every time, by someone whose job it is to run it — which is the actual difference between an application that holds up and one that does not.

Apply this thinking

Web Development

Zasya builds modern websites, web applications, landing pages, portals, and business platforms that are fast, secure, SEO-ready, and easy to maintain.

Business websites and marketing sitesLanding pages and campaign micrositesWeb applications and dashboardsCustomer portals and self-service platformsAdmin dashboards and back-office systemsNext.js and React frontendsNode.js and Laravel backendsSEO-ready architectureCore Web Vitals optimizationCMS integrations

Start a conversation

Let's find where value is leaking in your ecosystem.

Bring us the workflow, the channel, or the half-built thing that's stuck. In 30 minutes we'll tell you plainly which parts should connect, where intelligence pays back — and what it takes to ship.

Book a value call See customer stories30 min · free · no commitment