Files
php-security-linter/README.md
Yutaka Kurosaki 91bcb53ab5 Add PHP_MEMORY_LIMIT option for install.sh
- Document environment variable usage: PHP_MEMORY_LIMIT=2048M ./install.sh
- Update both English and Japanese sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:05:42 +09:00

20 KiB
Raw Blame History

PHP/Laravel Security Linter

English | 日本語


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

No PHP or Composer environment required. Just Docker.

Step 1: Clone and build

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:

# Build with 2GB memory limit (default: 1024M)
docker build --build-arg PHP_MEMORY_LIMIT=2048M -t php-security-linter:latest .

Step 2: Run

# 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:

./install.sh

# Or with custom memory limit
PHP_MEMORY_LIMIT=2048M ./install.sh

After installation, use the php-security-lint command anywhere:

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.

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

# 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:

{
    "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       <div class="user-info">
  │   13           <h2>{{ $user->name }}</h2>
  │   14           <div class="bio">
  │   15 ▶             {!! $userName !!}
  │   16           </div>
  │   17       </div>
  └─
  🏷️  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)

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

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

# 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: クローンとビルド

git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git
cd php-security-linter
docker build -t php-security-linter:latest .

注意: 大規模なプロジェクトでは、PHPのメモリ制限を増やす必要がある場合があります

# 2GBのメモリ制限でビルドデフォルト: 1024M
docker build --build-arg PHP_MEMORY_LIMIT=2048M -t php-security-linter:latest .

ステップ2: 実行

# プロジェクトディレクトリをスキャン
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

オプション: ラッパーコマンドのインストール

便利なラッパースクリプトをインストールできます:

./install.sh

# メモリ制限を指定する場合
PHP_MEMORY_LIMIT=2048M ./install.sh

インストール後は php-security-lint コマンドでどこからでも使用できます:

cd /path/to/your/laravel-project
php-security-lint .
php-security-lint app/ -s high

方法2: 直接実行PHP必須

PHP 8.1以上とComposerが必要です。

git clone https://opensource.rogarithm.net/rogarithm/php-security-linter.git
cd php-security-linter
composer install
php bin/security-lint /path/to/target

使用方法

# 単一ファイルの解析
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 を配置することで設定を永続化できます:

{
    "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       <div class="user-info">
  │   13           <h2>{{ $user->name }}</h2>
  │   14           <div class="bio">
  │   15 ▶             {!! $userName !!}
  │   16           </div>
  │   17       </div>
  └─
  🏷️  CWE-79 | A7:2017-XSS
  💡 自動エスケープされる {{ }} を使用してください。

════════════════════════════════════════════════════════════
サマリー
────────────────────────────────────────────────────────────
  クリティカル:  0
  高:            2
  中:            0
  低:            0
────────────────────────────────────────────────────────────
  合計:          2

0.15 秒で完了

終了コード

コード 意味
0 問題なし
1 中/低重大度の問題あり
2 クリティカル/高重大度の問題あり

CI/CD 統合

GitHub Actions (Docker)

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

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を使用

# イメージのビルド
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 / ドキュメント

License / ライセンス

MIT License

References / 参考資料