# PHP/Laravel Security Linter **[English](#english) | [日本語](#japanese)** --- ## English A static security analysis tool for PHP and Laravel applications. Detects vulnerabilities through recursive taint analysis by tracking data flow across function calls. ### Features - **Comprehensive Vulnerability Detection**: XSS, SQL Injection, Command Injection, Path Traversal, and more - **Recursive Taint Analysis**: Tracks how user input propagates through function calls - **Blade Template Analysis**: Laravel-specific `{!! !!}` syntax and context-aware XSS detection - **Smart Escape Detection**: Recognizes escape functions like `htmlspecialchars()` - **Escape Bypass Detection**: Detects escape invalidation by functions like `html_entity_decode()` - **Syntax Highlighting**: Color-coded code snippets in terminal output - **Multi-language Support**: Japanese/English message output ### Installation #### Method 1: Docker (Recommended) No PHP or Composer environment required. Just Docker. **Step 1: Clone and build** ```bash git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git cd php-security-linter docker build -t php-security-linter:latest . ``` **Note:** For large projects, you may need to increase the PHP memory limit: ```bash # Build with 2GB memory limit (default: 1024M) docker build --build-arg PHP_MEMORY_LIMIT=2048M -t php-security-linter:latest . ``` **Step 2: Run** ```bash # Scan your project directory docker run --rm -v /path/to/your/project:/target:ro php-security-linter:latest /target # Scan current directory docker run --rm -v $(pwd):/target:ro php-security-linter:latest /target # With options (high severity only, JSON output) docker run --rm -v $(pwd):/target php-security-linter:latest /target -s high -f json -o /target/report.json ``` **Optional: Install wrapper command** For convenience, you can install a wrapper script: ```bash ./install.sh ``` After installation, use the `php-security-lint` command anywhere: ```bash cd /path/to/your/laravel-project php-security-lint . php-security-lint app/ -s high ``` #### Method 2: Direct Execution (PHP Required) Requires PHP 8.1+ and Composer. ```bash git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git cd php-security-linter composer install php bin/security-lint /path/to/target ``` ### Usage ```bash # Analyze a single file php bin/security-lint path/to/file.php # Analyze a directory php bin/security-lint app/ # Show high severity only php bin/security-lint app/ -s high # Show code context (3 lines) php bin/security-lint app/ -c # Show code context (5 lines) php bin/security-lint app/ -c 5 # Output as JSON php bin/security-lint app/ -f json -o report.json # Output in English php bin/security-lint app/ -l en ``` ### Options #### Output Options | Option | Description | |--------|-------------| | `-f, --format` | Output format: text, json, html, sarif, markdown | | `-s, --severity` | Minimum severity: low, medium, high, critical | | `-o, --output` | Output to file | | `-l, --lang` | Language: ja, en | | `-c, --context [N]` | Show N lines of code context (default: 3) | | `--verbose` | Show detailed information | | `-q, --quiet` | Suppress progress output | | `--no-colors` | Disable colored output | #### Exclude/Include Options | Option | Description | |--------|-------------| | `-e, --exclude` | Exclude pattern (can be used multiple times) | | `-i, --include` | Include pattern (overrides exclude) | | `--include-vendor` | Also analyze vendor directory | | `--include-tests` | Also analyze tests directory | | `--no-default-excludes` | Don't use default exclude patterns | | `--show-excluded` | Show excluded patterns | #### Analysis Options | Option | Description | |--------|-------------| | `-d, --recursive-depth` | Recursive analysis depth (default: 10) | ### Default Exclude Patterns The following directories/patterns are excluded by default: - `vendor/*` - Composer dependencies - `node_modules/*` - npm dependencies - `storage/*` - Laravel storage - `bootstrap/cache/*` - Laravel cache - `public/vendor/*` - Public assets - `.git/*`, `.svn/*` - Version control - `tests/*` - Test files - `cache/*`, `tmp/*`, `temp/*` - Temporary files To include these in analysis, use `--include-vendor` or `--include-tests`, or disable all with `--no-default-excludes`. ### Configuration File Place `.security-lint.json` in your project root to persist settings: ```json { "severity": "medium", "format": "text", "lang": "en", "exclude": ["custom/legacy/*"], "include": ["vendor/my-company/*"], "includeVendor": false, "includeTests": false } ``` ### Detectable Vulnerabilities #### XSS (Cross-Site Scripting) - Blade `{!! !!}` raw output - Output within JavaScript context - Output within event handler attributes - URL context (javascript: URLs) - Style injection - Template injection - Escape bypass functions - Dangerous hardcoded HTML #### SQL Injection - Tainted data in `DB::raw()` - Query construction via string concatenation - Direct PDO/MySQLi queries - Laravel Query Builder Raw methods #### Command Injection - `exec()`, `shell_exec()`, `system()`, etc. - `eval()`, `create_function()`, etc. - Dynamic file includes - Improper Symfony Process usage #### Path Traversal - Tainted paths in file operation functions - Tainted paths in Laravel Storage - File download/upload #### Authentication Security - Weak hash algorithms (MD5, SHA1) - Hardcoded credentials - Timing-vulnerable comparisons #### CSRF/Session - Missing CSRF tokens - Insecure session configuration - Session fixation #### Configuration Security - Debug output (phpinfo, var_dump) - Insecure unserialize - Sensitive information logging #### Laravel-Specific Security - Mass Assignment (missing $fillable/$guarded, using $request->all()) - Raw SQL injection (DB::raw, whereRaw without bindings) - CSRF protection (forms without @csrf) - File upload validation (extensions-only without mimes) - Route authentication (sensitive routes without auth middleware) - Rate limiting (auth routes without throttle middleware) ### Output Example ``` ╔════════════════════════════════════════════════════════════╗ ║ PHP/Laravel Security Linter v0.0.1 ║ ╚════════════════════════════════════════════════════════════╝ Analyzing: app/ HIGH (2) ──────────────────────────────────────────────────────────── [XSS] Blade's {!! !!} raw output may cause XSS vulnerability. 📍 resources/views/user.blade.php:15 ┌─ user.blade.php │ 12
│ 13

{{ $user->name }}

│ 14
│ 15 ▶ {!! $userName !!} │ 16
│ 17
└─ 🏷️ CWE-79 | A7:2017-XSS 💡 Use auto-escaped {{ }} instead. ════════════════════════════════════════════════════════════ Summary ──────────────────────────────────────────────────────────── Critical: 0 High: 2 Medium: 0 Low: 0 ──────────────────────────────────────────────────────────── Total: 2 Completed in 0.15 seconds ``` ### Exit Codes | Code | Meaning | |------|---------| | 0 | No issues found | | 1 | Medium/low severity issues found | | 2 | Critical/high severity issues found | ### CI/CD Integration #### GitHub Actions (Docker) ```yaml name: Security Scan on: [push, pull_request] jobs: security-lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Security Linter run: | docker run --rm -v ${{ github.workspace }}:/target \ php-security-linter:latest \ /target -s high -f sarif -o /target/security.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v2 with: sarif_file: security.sarif ``` #### GitLab CI ```yaml security-lint: image: php-security-linter:latest script: - security-lint . -s medium -f json -o security-report.json artifacts: reports: sast: security-report.json ``` ### Docker Details #### Manual Docker Usage ```bash # Build image docker build -t php-security-linter:latest . # Run (scan current directory) docker run --rm -v $(pwd):/target:ro php-security-linter:latest /target # With options docker run --rm -v $(pwd):/target:ro php-security-linter:latest \ /target/app -s high -f json ``` #### Environment Variables | Variable | Description | |----------|-------------| | `PHP_SECURITY_LINT_IMAGE` | Docker image to use (default: php-security-linter:latest) | --- ## 日本語 PHP および Laravel アプリケーション向けの静的セキュリティ解析ツールです。 再帰的なテイント解析により、関数呼び出しを通じた脆弱性を検出します。 ### 特徴 - **包括的な脆弱性検出**: XSS、SQLインジェクション、コマンドインジェクション、パストラバーサルなど - **再帰的テイント解析**: ユーザー入力が関数を通じてどのように伝播するかを追跡 - **Blade テンプレート解析**: Laravel 特有の `{!! !!}` 構文やコンテキスト別XSS検出 - **スマートなエスケープ検出**: `htmlspecialchars()` 等のエスケープ関数を認識 - **エスケープ破壊の検出**: `html_entity_decode()` 等によるエスケープ無効化を検出 - **シンタックスハイライト**: ターミナル出力でコードスニペットを色分け表示 - **多言語対応**: 日本語/英語のメッセージ出力 ### インストール #### 方法1: Docker(推奨) PHPやComposerの環境構築は不要です。Dockerのみで動作します。 **ステップ1: クローンとビルド** ```bash git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git cd php-security-linter docker build -t php-security-linter:latest . ``` **注意:** 大規模なプロジェクトでは、PHPのメモリ制限を増やす必要がある場合があります: ```bash # 2GBのメモリ制限でビルド(デフォルト: 1024M) docker build --build-arg PHP_MEMORY_LIMIT=2048M -t php-security-linter:latest . ``` **ステップ2: 実行** ```bash # プロジェクトディレクトリをスキャン docker run --rm -v /path/to/your/project:/target:ro php-security-linter:latest /target # カレントディレクトリをスキャン docker run --rm -v $(pwd):/target:ro php-security-linter:latest /target # オプション付き(高重大度のみ、JSON出力) docker run --rm -v $(pwd):/target php-security-linter:latest /target -s high -f json -o /target/report.json ``` **オプション: ラッパーコマンドのインストール** 便利なラッパースクリプトをインストールできます: ```bash ./install.sh ``` インストール後は `php-security-lint` コマンドでどこからでも使用できます: ```bash cd /path/to/your/laravel-project php-security-lint . php-security-lint app/ -s high ``` #### 方法2: 直接実行(PHP必須) PHP 8.1以上とComposerが必要です。 ```bash git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git cd php-security-linter composer install php bin/security-lint /path/to/target ``` ### 使用方法 ```bash # 単一ファイルの解析 php bin/security-lint path/to/file.php # ディレクトリの解析 php bin/security-lint app/ # 高重大度のみ表示 php bin/security-lint app/ -s high # コードスニペット表示 (前後3行) php bin/security-lint app/ -c # コードスニペット表示 (前後5行) php bin/security-lint app/ -c 5 # JSON形式で出力 php bin/security-lint app/ -f json -o report.json # 英語で出力 php bin/security-lint app/ -l en ``` ### オプション #### 出力オプション | オプション | 説明 | |-----------|------| | `-f, --format` | 出力形式: text, json, html, sarif, markdown | | `-s, --severity` | 最小重大度: low, medium, high, critical | | `-o, --output` | ファイルに出力 | | `-l, --lang` | 言語: ja, en | | `-c, --context [N]` | 問題行の前後N行のコードスニペットを表示 (デフォルト: 3) | | `--verbose` | 詳細情報を表示 | | `-q, --quiet` | 進捗を非表示 | | `--no-colors` | カラー出力を無効化 | #### 除外/包含オプション | オプション | 説明 | |-----------|------| | `-e, --exclude` | 除外パターン (複数回使用可能) | | `-i, --include` | 包含パターン (除外を上書き) | | `--include-vendor` | vendor ディレクトリも解析 | | `--include-tests` | tests ディレクトリも解析 | | `--no-default-excludes` | デフォルト除外パターンを使用しない | | `--show-excluded` | 除外されるパターンを表示 | #### 解析オプション | オプション | 説明 | |-----------|------| | `-d, --recursive-depth` | 再帰解析の深度 (デフォルト: 10) | ### デフォルト除外パターン 以下のディレクトリ/パターンはデフォルトで除外されます: - `vendor/*` - Composer 依存関係 - `node_modules/*` - npm 依存関係 - `storage/*` - Laravel ストレージ - `bootstrap/cache/*` - Laravel キャッシュ - `public/vendor/*` - 公開アセット - `.git/*`, `.svn/*` - バージョン管理 - `tests/*` - テストファイル - `cache/*`, `tmp/*`, `temp/*` - 一時ファイル これらを含めて解析したい場合は `--include-vendor` や `--include-tests` を使用するか、`--no-default-excludes` で全て無効化できます。 ### 設定ファイル プロジェクトルートに `.security-lint.json` を配置することで設定を永続化できます: ```json { "severity": "medium", "format": "text", "lang": "ja", "exclude": ["custom/legacy/*"], "include": ["vendor/my-company/*"], "includeVendor": false, "includeTests": false } ``` ### 検出可能な脆弱性 #### XSS (クロスサイトスクリプティング) - Blade の `{!! !!}` 生出力 - JavaScript コンテキスト内の出力 - イベントハンドラ属性内の出力 - URL コンテキスト (javascript: URL) - Style インジェクション - テンプレートインジェクション - エスケープ破壊関数の使用 - 危険なハードコード HTML #### SQLインジェクション - `DB::raw()` への汚染データ - 文字列連結によるクエリ構築 - PDO/MySQLi の直接クエリ - Laravel クエリビルダーの Raw メソッド #### コマンドインジェクション - `exec()`, `shell_exec()`, `system()` 等 - `eval()`, `create_function()` 等 - 動的ファイルインクルード - Symfony Process の不適切な使用 #### パストラバーサル - ファイル操作関数への汚染パス - Laravel Storage への汚染パス - ファイルダウンロード/アップロード #### 認証セキュリティ - 弱いハッシュアルゴリズム (MD5, SHA1) - ハードコードされた認証情報 - タイミング攻撃に脆弱な比較 #### CSRF/セッション - CSRF トークンの欠落 - 安全でないセッション設定 - セッション固定化 #### 設定セキュリティ - デバッグ出力 (phpinfo, var_dump) - 安全でない unserialize - 機密情報のログ出力 #### Laravel特有のセキュリティ - Mass Assignment ($fillable/$guarded の欠落、$request->all() の使用) - Raw SQL インジェクション (DB::raw、バインディングなしの whereRaw) - CSRF 保護 (@csrf のないフォーム) - ファイルアップロード検証 (mimes なしの extensions のみ) - ルート認証 (auth ミドルウェアのないセンシティブなルート) - レート制限 (throttle ミドルウェアのない認証ルート) ### 出力例 ``` ╔════════════════════════════════════════════════════════════╗ ║ PHP/Laravel セキュリティリンター v0.0.1 ║ ╚════════════════════════════════════════════════════════════╝ 解析中: app/ HIGH (2) ──────────────────────────────────────────────────────────── [XSS] Blade の {!! !!} による生出力はXSSの脆弱性を引き起こす可能性があります。 📍 resources/views/user.blade.php:15 ┌─ user.blade.php │ 12
│ 13

{{ $user->name }}

│ 14
│ 15 ▶ {!! $userName !!} │ 16
│ 17
└─ 🏷️ CWE-79 | A7:2017-XSS 💡 自動エスケープされる {{ }} を使用してください。 ════════════════════════════════════════════════════════════ サマリー ──────────────────────────────────────────────────────────── クリティカル: 0 高: 2 中: 0 低: 0 ──────────────────────────────────────────────────────────── 合計: 2 0.15 秒で完了 ``` ### 終了コード | コード | 意味 | |--------|------| | 0 | 問題なし | | 1 | 中/低重大度の問題あり | | 2 | クリティカル/高重大度の問題あり | ### CI/CD 統合 #### GitHub Actions (Docker) ```yaml name: Security Scan on: [push, pull_request] jobs: security-lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Security Linter run: | docker run --rm -v ${{ github.workspace }}:/target \ php-security-linter:latest \ /target -s high -f sarif -o /target/security.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v2 with: sarif_file: security.sarif ``` #### GitLab CI ```yaml security-lint: image: php-security-linter:latest script: - security-lint . -s medium -f json -o security-report.json artifacts: reports: sast: security-report.json ``` ### Docker 詳細 #### 手動でDockerを使用 ```bash # イメージのビルド docker build -t php-security-linter:latest . # 実行 (カレントディレクトリをスキャン) docker run --rm -v $(pwd):/target:ro php-security-linter:latest /target # オプション付き docker run --rm -v $(pwd):/target:ro php-security-linter:latest \ /target/app -s high -f json ``` #### 環境変数 | 変数 | 説明 | |------|------| | `PHP_SECURITY_LINT_IMAGE` | 使用するDockerイメージ (デフォルト: php-security-linter:latest) | --- ## Documentation / ドキュメント - [Detection Rules / 検出ルール詳細](docs/DETECTION_RULES.md) - [Quick Reference / クイックリファレンス](docs/QUICK_REFERENCE.md) ## License / ライセンス MIT License ## References / 参考資料 - [OWASP Top 10](https://owasp.org/www-project-top-ten/) - [CWE/SANS Top 25](https://cwe.mitre.org/top25/) - [Laravel Security](https://laravel.com/docs/security)