laramint/php-security-scanner
Installation:
composer require --dev laramint/php-security-scanner
Add to composer.json under require-dev to ensure it runs only in development.
Basic Scan:
vendor/bin/php-security-scanner scan src/
src/ directory recursively.--format).First Use Case: Integrate into CI/CD (e.g., GitHub Actions) to block merges with critical vulnerabilities:
# .github/workflows/security.yml
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install --dev
- run: vendor/bin/php-security-scanner scan src/ --fail-on=critical
Pre-Commit Hooks:
Use husky or pre-commit to run lightweight scans on staged files:
vendor/bin/php-security-scanner scan --changed-files
Custom Rulesets:
Extend default rules via php-security-scanner.json:
{
"rules": {
"Laravel.Eloquent.InsecureQuery": {
"enabled": true,
"severity": "high"
}
}
}
Integration with Laravel:
// app/Console/Commands/SecurityScan.php
public function handle() {
$scanner = new \Laramint\SecurityScanner\Scanner();
$results = $scanner->scan(base_path('app'));
$this->output->table(['File', 'Issue', 'Severity'], $results);
}
$this->app->singleton(SecurityScanner::class, function () {
return new SecurityScanner(config('security-scanner.ruleset'));
});
API-Driven Scans:
Use the --json flag to parse results programmatically:
$output = shell_exec('vendor/bin/php-security-scanner scan --json');
$issues = json_decode($output, true);
False Positives:
echo $_GET['input']).php-security-scanner.json:
"whitelist": {
"files": ["app/Helpers/SafeOutput.php"],
"functions": ["app\\Helpers\\sanitizeOutput"]
}
Performance:
vendor/, node_modules/, and test directories:
vendor/bin/php-security-scanner scan --exclude="vendor|node_modules|tests"
Laravel-Specific Quirks:
{!! $input !!}).// app/Providers/AppServiceProvider.php
public function boot() {
\Laramint\SecurityScanner\Rules::addCustomRule(
'Blade.XSS',
'/\{\{\!\s*\$([^\}]+)\s*\}\}/',
'Potential XSS in Blade: {{!! $variable !!}}'
);
}
Hardcoded Secrets:
.env).--secret-pattern to define custom patterns:
vendor/bin/php-security-scanner scan --secret-pattern="DB_PASSWORD=.*"
--verbose to debug rule matching:
vendor/bin/php-security-scanner scan --verbose
vendor/bin/php-security-scanner scan --dry-run
Custom Rules:
Implement Laramint\SecurityScanner\RuleInterface for project-specific checks:
class LaravelCsrfRule implements RuleInterface {
public function matches(string $fileContent): bool {
return str_contains($fileContent, "'_token' =>");
}
public function getSeverity(): string { return 'medium'; }
}
Reporters:
Extend Laramint\SecurityScanner\Reporter\AbstractReporter to format output (e.g., Slack alerts):
class SlackReporter extends AbstractReporter {
protected function formatIssue(Issue $issue): string {
return "🚨 *$issue->getSeverity()* in $issue->getFile(): $issue->getMessage()";
}
}
Integration with Laravel Valet:
Add to ~/.valet/Laravel/valet-secure.sh:
#!/bin/bash
cd "$1" && vendor/bin/php-security-scanner scan --fail-on=high
How can I help you explore Laravel packages today?