Laravel Security Scoring Methodology
How we grade Laravel open source projects. 39 framework-aware static analysis checks across five categories: code patterns, configuration, routes, filesystem, and dependencies. Every check, every threshold, every rule, published openly. The engine is open source: stack-shield/laravel-analyser.
Grading Rubric
| Grade | Criteria |
|---|---|
| A | Zero high or critical findings, fewer than 3 medium findings |
| B | Zero critical, at most 1 high, fewer than 6 medium |
| C | At most 2 high findings |
| D | Everything else |
Only grade A is displayed publicly. B/C/D grades are visible only to claimed maintainers.
What Counts Toward the Grade
Critical, high and medium findings from graded checks count. Low and informational findings are reported but never change a grade.
Advisory checks point at code worth a look but cannot prove a problem from source alone, because the protection may live elsewhere: authorization in a policy, validation in a form request, HTTPS forced by the proxy. Maintainers see these findings; they never count toward the grade. Advisory checks are marked below.
Routes are resolved the way Laravel registers them, including group middleware, prefixes, route files mapped by service providers, middleware aliases and groups, and controller middleware. A debug route behind authentication, or a CSRF exemption for a webhook, is not a finding.
Known vulnerabilities come from the Packagist advisory database, the same source as composer audit, checked against the versions in composer.lock. Each vulnerable package counts once at its most severe advisory. Development dependencies are advisory because they do not ship to production. An advisory published in the last 14 days is shown but does not count yet, giving maintainers time to release a fix.
Security Checks
Unvalidated request data ($request->all(), except()) passed to create, fill or update on an unguarded model, or to forceFill/forceCreate
DB::raw, whereRaw, selectRaw and similar built from request input
eval, shell_exec, system and similar reachable from request input
Controllers using request data without visible validation
Passwords, API keys and secrets written into source code
Uploads written to a publicly served location with no file type validation
rand()/mt_rand() generating tokens, passwords, codes and other secrets
Redirects to a URL taken from the request
MD5 or SHA-1 stored as, or compared with, a password
unserialize() on request data; on other data it is advisory
Request data rendered with {!! !!}; other variables are advisory
Controllers with store/update/destroy and no visible authorization
Deleting every row of a table in an action reachable without authentication
A real APP_KEY committed to the repository, or a key that is too short
Non-standard cipher in config/app.php
APP_DEBUG=true in committed production env files
Debugbar, Ignition or the dump server in require instead of require-dev
Debug log level in a production env file
Insecure session cookie settings
Wildcard CORS origins combined with credentials
Mail driver set to log or array in production
TrustProxies hardcoded to trust every proxy
Broadcasting channels without authorization checks
QUEUE_CONNECTION=sync in a production env file
File cache driver in a production env file
No HTTPS forcing in the application
Installed package versions with published security advisories
A Laravel version that no longer receives security fixes
.env, .git and similar files under public/
Sensitive files in public storage
Sensitive files with overly permissive permissions (local scans only)
Config files writable in production (local scans only)
Database dumps or archives named like backups under public/
Login, password reset and two-factor submissions with no rate limiting on the route, its group, or in the login code
User-scoped routes with model binding and no auth middleware
CSRF exemptions covering state-changing routes authenticated by the session, or exempting every route
API routes with no rate limiting on the routes or the api middleware group
Debug, test or phpinfo routes reachable without authentication
Overly broad catch-all route parameters