Skip to content
Ajgori Technologies
All posts

Security 7 min read

How to secure a Laravel application before launch

A pre-launch security checklist for Laravel applications, from debug mode and authorisation to validation, rate limiting and dependency updates.

On this page
  1. Laravel security checklist: production configuration and debug mode
  2. Authorisation on every route
  3. Validating input and file uploads
  4. Rate limiting logins and forms
  5. Keeping dependencies updated
  6. Summary

A practical Laravel security checklist for launch covers five areas: production configuration and debug mode, authorisation on every route and action, validation of all input and file uploads, rate limiting on logins and forms, and keeping dependencies updated. Laravel provides strong tools for each, but they only protect an application when they are configured and used consistently. Working through the list before launch catches the mistakes that are easy to miss during development.

Laravel is a PHP framework for building web applications. This guide is written for developers and technical leads, with short examples that match Laravel 13. It is a pre-launch review, not a full security audit. If you would like an independent review of your application, our cybersecurity service page explains how we work.

Laravel security checklist: production configuration and debug mode

Configuration mistakes are easy to make and can be damaging, because they can expose information about the whole application.

  1. Turn off debug mode. Laravel's documentation is explicit: in production, APP_DEBUG should always be false. If it is true, detailed error pages can expose sensitive configuration values to anyone who triggers an error.
  2. Set the environment correctly. APP_ENV should be production on the live server, so environment-specific behaviour works as intended.
  3. Keep .env out of version control. The documentation warns that committing the .env file is a security risk, because anyone with access to the repository would see its credentials. Store production secrets in the server's environment or an encrypted environment file.
  4. Use a unique application key. APP_KEY is used for encryption. Generate it once per environment and never share it between projects.
  5. Serve the application from the public directory. The deployment guide explains that the web server should point to public/index.php, and that serving from the project root would expose sensitive files.
  6. Cache configuration as part of deployment. Running php artisan optimize caches configuration, routes and views. Once configuration is cached, the .env file is not loaded, so make sure env() is only called inside configuration files.
  7. Force HTTPS. Serve the whole application over HTTPS and redirect plain HTTP requests.

A quick check on the live server confirms the basics:

php artisan about --only=environment

This shows the environment and whether debug mode is enabled.

Security headers are another production setting to check, explained in our guide to HTTP security headers.

Authorisation on every route

Authentication confirms who a user is. Authorisation decides what they are allowed to do. A common and serious problem is missing authorisation: a logged-in user who can view or change another user's records simply by changing an ID in the web address.

  1. Protect routes with authentication middleware so only signed-in users reach private areas.
  2. Check permissions for every action on a record, not only whether the user is logged in. Laravel's authorization features, such as policies and gates, keep these rules in one place.
  3. Authorise in controllers, jobs and API endpoints alike. Background jobs and APIs are easy to forget.
  4. Scope queries to the current user or organisation where records belong to them, so users cannot load other people's data.
  5. Test authorisation. Add feature tests that confirm a user cannot view or change another user's records.

A policy check in a controller can be as short as this:

use Illuminate\Support\Facades\Gate;

public function update(Request $request, Invoice $invoice)
{
    Gate::authorize('update', $invoice);

    // Validate and update the invoice...
}

If the current user is not allowed to update the invoice, Laravel stops the request with a "forbidden" response.

Validating input and file uploads

Every piece of data sent to your application should be treated as untrusted until it has been validated.

  1. Validate every request. Use Laravel's validation, often through form request classes, to check types, lengths, formats and allowed values.
  2. Only accept the fields you expect. Use validated data when creating or updating models, rather than passing the whole request.
  3. Escape output. Blade's {{ }} syntax escapes output by default. Be careful with any place that outputs raw HTML, and only do so with content you trust or have cleaned.
  4. Use the query builder and Eloquent safely. They use parameter binding, which protects against injection. Take extra care with any raw SQL.
  5. Validate uploaded files strictly. Check the file type and size, and store uploads outside the public web root unless they are meant to be public.

For uploads, Laravel's File rule makes the intent clear:

use Illuminate\Validation\Rules\File;

$request->validate([
    'invoice' => ['required', File::types(['pdf'])->max('10mb')],
]);

Laravel's mimes rule checks the file's contents to guess its type, not only the name the user gave it. Even so, never trust an uploaded file enough to execute it.

Rate limiting logins and forms

Rate limiting restricts how often an action can be performed. It slows down password-guessing attacks and stops automated abuse of forms.

  1. Limit login attempts by email address and IP address, so repeated failures are slowed down.
  2. Limit password reset and registration requests, which are also common targets.
  3. Limit public forms, such as contact and quote forms, to reduce spam and abuse.
  4. Limit API endpoints to protect the application and any paid third-party services behind them.

Laravel's route rate limiting lets you define named limiters and attach them with the throttle middleware. Laravel's starter kits already include login rate limiting, but custom login forms and other forms need their own limits.

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('contact', function (Request $request) {
    return Limit::perMinute(5)->by($request->ip());
});

The named limiter is then applied to the route with ->middleware('throttle:contact').

For admin accounts, add a second login step as well, and our guide to two-factor authentication for admins covers the options.

Keeping dependencies updated

A Laravel application depends on the framework itself and many other packages. Security fixes in any of them only protect you once they are installed.

  1. Check for known vulnerabilities. Composer's audit command checks installed packages against security advisories and also reports abandoned packages:
composer audit
  1. Apply updates regularly, not only when a problem is reported. Small, frequent updates are easier to test than large, rare ones.
  2. Stay on a supported Laravel version. Laravel publishes a support policy with dates for bug and security fixes for each release.
  3. Keep PHP and server software supported as well.
  4. Remove packages you no longer use, since each one is code that must be kept up to date.
  5. Run your test suite before deploying updates, so a fix does not break a feature.

Our guide on how to upgrade an old Laravel application safely explains how to catch up if an application has fallen behind.

Before you launch

A final pass through these points is worth the time:

  • Debug mode is off and the environment is set to production.
  • Secrets are not in version control, and the application key is unique.
  • Every route that changes or shows private data checks authorisation.
  • All input and uploads are validated.
  • Logins and public forms are rate limited.
  • composer audit reports no known vulnerabilities.
  • Backups are running and have been restored successfully at least once.

If you are hiring help for a Laravel project, our guide on what to check before hiring a Laravel developer lists the security questions to ask.

If the application connects to suppliers or payment services, our guide to API security best practices covers storing keys and verifying webhooks.

Summary

  • Turn off debug mode, set the production environment, protect secrets and serve only the public directory.
  • Authorise every action on every record, in controllers, jobs and APIs, and test it.
  • Validate all input, escape output and check file uploads strictly.
  • Rate limit logins, password resets, public forms and APIs.
  • Audit and update dependencies regularly and stay on supported versions.

A careful pre-launch review turns Laravel's security features into real protection. If you'd like your Laravel application reviewed before launch, you can tell us about it here.

Security

Related posts

Security

How to secure a WordPress site

A prioritised checklist for securing a WordPress site, starting with the steps that close the most common ways in.

9 min read

Working on something?

Get in touch and tell us about it.