laravel-security-scanner maintained by laramint
laravel-security-scanner
Laravel-aware security rules for laramint/php-security-scanner. Installs as an Extension and adds Laravel-specific detections on top of the base ruleset.
Install
composer require --dev laramint/laravel-security-scanner
The scanner auto-discovers the extension via composer/installed.json. To force-load it, pass --extension=LaraMint\\LaravelSecurityScanner\\LaravelExtension on the CLI.
Rules added
| ID | Default severity | Detects |
|---|---|---|
laravel.debug-code |
medium | dd/ddd/dump/ray/var_dump/print_r calls left in code |
laravel.sql-injection |
critical | Tainted input in whereRaw, orderByRaw, selectRaw, DB::raw, DB::statement, unprepared |
laravel.mass-assignment |
high | Model::create($request->all()) / ->fill($request->input()) / ->update(request()->all()) |
laravel.unsafe-validator |
high | Validator::make() / $request->validate() called with tainted or non-literal rules |
laravel.cookie-insecure |
medium | Cookie::queue(...) with secure=false, httpOnly=false, or sameSite=none |
laravel.csrf-bypass |
high | VerifyCsrfToken::$except wildcard route or ->withoutMiddleware('csrf') |
laravel.env-leak |
medium | echo env(...) / return env(...) — leaks secrets, breaks under config:cache |
laravel.blade-raw-echo |
medium | {!! $expr !!} raw output in Blade — bypasses auto-escaping |
laravel.open-redirect |
high | redirect()->to()/away() or Redirect::to() with tainted URL |
laravel.ssrf.http-client |
high | Http::get/post/put/sink/baseUrl(...) with tainted URL |
laravel.unsafe-storage-path |
high | Storage::get/put/download/disk(...) / File::get/put / response()->download with tainted path |
laravel.file-upload-validation |
high | Validator rule file/image without mimes: / mimetypes: / max: constraints |
laravel.unsafe-auth |
critical | Auth::loginUsingId($tainted) / onceUsingId($tainted) — authentication bypass |
laravel.unsafe-crypt |
high | Crypt::decrypt() / decryptString() / decrypt() on tainted ciphertext |
laravel.artisan-call |
critical | Artisan::call($tainted) / queue($tainted) — attacker picks the command |
laravel.process-shell |
critical | Process::run($tainted) / start($tainted) (Laravel 10+ Process facade) |
laravel.config-injection |
high | config([$k => $v]) / Config::set() / config()->set() with tainted key or value |
laravel.tainted-view-name |
high | view($tainted) / Route::view(_, $tainted) / View::make($tainted) |
laravel.session-fixation |
high | Session::setId($tainted) / session()->setId($tainted) |
laravel.mail-tainted-header |
medium | Mail::to/cc/bcc/subject($tainted) — recipient / header injection |
The base php-security-scanner rules (eval, SQLi, XSS, path traversal, deserialize, SSRF, CORS, mcrypt, MD5-as-password, openssl-CBC-static-IV, hardcoded secrets, …) all continue to apply when this extension is installed.
Extra taint awareness
LaravelExtension::register() also teaches the taint engine about Laravel:
request()andIlluminate\Http\Request::{all,input,get,post,query,json,header,cookie,file,string,integer,boolean}are HTTP sources.e()andblade_escape()clear HTML taint (so blade-escaped output is not flagged for XSS).
Writing your own rule
Implement LaraMint\PhpSecurityScanner\Rules\Rule (or extend AbstractRule) and register it in your own Extension::register(). See src/Rules/ for examples.
Development
composer install
vendor/bin/phpunit
vendor/bin/phpstan analyse
License
MIT.