Maintain the whole PHP runtime
Run a supported PHP release and apply security updates to the interpreter, extensions, Composer packages, framework, web server, and operating system. Remove extensions and packages the application does not use. The PHP security manual stresses that safe operation depends on both coding practices and runtime configuration.
Use production settings: disable display of errors to visitors, log errors to a protected destination, and avoid exposing unnecessary version information. Run PHP-FPM pools under dedicated, non-root accounts. Restrict filesystem permissions so application code is not writable by the web process unless a specific directory needs it. Separate uploads, cache, logs, and generated files from executable code.
Keep Laravel’s safeguards intact
Use Blade’s escaped output syntax for untrusted values. Review every use of raw output and sanitize rich HTML with an appropriate allowlist. Keep CSRF middleware enabled for browser sessions and document any excluded route. Validate all request data server-side with explicit rules, including nested values and uploaded files.
Use policies and gates for authorization. A route protected by login middleware still needs object-level permission checks. Avoid mass-assignment mistakes by maintaining $fillable or $guarded rules and by passing only validated, intended fields into models. Do not expose sequential identifiers without verifying access to the referenced record.
Protect sessions, identity, and secrets
Use HTTPS throughout and configure cookies with Secure, HttpOnly, and an appropriate SameSite value. Rotate the session identifier after authentication and privilege changes. Use Laravel’s password hashing and rate-limiting facilities rather than custom cryptography or authentication logic. Add multi-factor authentication for privileged users where the risk warrants it.
Generate a unique application key per environment, protect it like a secret, and plan carefully before rotating it because encrypted application data can depend on it. Keep .env files outside public access and out of version control. Use narrow credentials for databases, mail, storage, queues, and third-party APIs.
Handle queries, files, and remote services safely
Use Eloquent or parameterized queries and never concatenate untrusted values into SQL. Dynamic column names and sort directions need allowlists because bound parameters protect values, not identifiers. Validate ownership as well as existence when retrieving records.
For uploads, restrict size and type, inspect content rather than trusting the extension, generate storage names, and store untrusted files outside executable or public paths when possible. Serve downloads through controlled responses with safe content types and authorization checks.
Set timeouts and destination allowlists for outbound HTTP requests to reduce server-side request-forgery risk. Validate webhook signatures using the provider’s documented canonical format, enforce freshness where available, and make event handling idempotent.
Deploy with reproducible controls
Commit composer.lock, install production dependencies without development packages, audit dependencies, and do not run Composer as root in deployment images. Cache configuration only after production values are correct. Disable debug mode and development tooling. Protect queue dashboards, schedulers, storage endpoints, and health routes from public exposure.
Centralize logs and alert on repeated authentication failures, authorization denials, unexpected administrative changes, and application errors. Test backup restoration and keep deployment rollback procedures available.
PHP and Laravel review checklist
- PHP, Laravel, Composer packages, extensions, and the OS are supported and patched.
- Debug output is disabled and sensitive configuration is outside the web root.
- Blade escaping, validation, CSRF, policies, and mass-assignment controls are preserved.
- Database queries are parameterized and object-level authorization is tested.
- Uploads, outbound requests, queues, webhooks, and scheduled tasks have explicit controls.
- The PHP process and service credentials follow least privilege.
- Logs, backups, incident response, and rollback have operational owners.












