Files
php-security-linter/docs/QUICK_REFERENCE.md
Yutaka Kurosaki 6280290898 Initial commit: PHP/Laravel Security Linter v1.0.0
A static security analysis tool for PHP and Laravel applications
with recursive taint analysis capabilities.

Features:
- Comprehensive vulnerability detection (XSS, SQL Injection,
  Command Injection, Path Traversal, CSRF, Authentication issues)
- Recursive taint analysis across function calls
- Blade template analysis with context-aware XSS detection
- Smart escape detection and escape bypass detection
- Syntax highlighting in terminal output
- Multi-language support (Japanese/English)
- Docker support for easy deployment
- Multiple output formats (text, JSON, HTML, SARIF, Markdown)
- CI/CD integration ready (GitHub Actions, GitLab CI)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 15:18:53 +09:00

291 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# セキュリティリンター クイックリファレンス
## XSS 検出パターン
### Blade テンプレート
```
重大度: CRITICAL
├── <script>{!! $var !!}</script> # JS内の生出力
└── onclick="{!! $var !!}" # イベントハンドラ内の生出力
重大度: HIGH
├── {!! $var !!} # 生出力
├── {!! func($var) !!} # 関数がエスケープしない場合
├── {!! html_entity_decode(...) !!} # エスケープ破壊
├── {!! '<script>...' . $var !!} # 危険なハードコードHTML
├── onclick="{{ $var }}" # イベントハンドラ
└── @include($var) # テンプレートインジェクション
重大度: MEDIUM
├── <script>{{ $var }}</script> # JS コンテキスト
├── href="{{ $var }}" # URL コンテキスト
├── style="{{ $var }}" # CSS インジェクション
└── <svg>{{ $var }}</svg> # SVG コンテキスト
重大度: LOW
├── data-x={{ $var }} # 引用符なし属性
└── @json($var) in <script> # JSON ディレクティブ
```
### 安全なパターン(検出されない)
```blade
{!! htmlspecialchars($var) !!} ✓ エスケープ関数
{!! e($var) !!} ✓ Laravel ヘルパー
{!! '<div>' . e($var) . '</div>' !!} ✓ 安全な連結
{!! csrf_field() !!} ✓ 組み込み関数
{!! $errors !!} ✓ Laravel 組み込み
{!! Markdown::parse($var) !!} ✓ Markdown プロセッサ
{!! safeFunc($var) !!} ✓ エスケープを返す関数
```
---
## SQLインジェクション 検出パターン
```
重大度: HIGH
├── DB::raw("... $var ...")
├── DB::select("... $var ...")
├── ->whereRaw("... $var ...")
├── ->orderByRaw($var)
├── $pdo->query("... $var ...")
├── $mysqli->query("... $var ...")
└── "SELECT * FROM t WHERE id = $var"
```
### SQLサニタイザー関数これらは安全と判定
```php
intval($var), (int)$var 型キャスト
floatval($var), (float)$var 型キャスト
mysqli_real_escape_string($conn, $var) エスケープ
$pdo->quote($var) PDO エスケープ
filter_var($var, FILTER_VALIDATE_INT) 検証
```
### SQLサニタイザー破壊パターン危険
```php
stripslashes(mysqli_real_escape_string(...))
urldecode(addslashes($var))
html_entity_decode($pdo->quote($var))
```
### 安全なパターン
```php
DB::select('SELECT * FROM t WHERE id = ?', [$id]);
$query->where('column', '=', $value);
$query->whereRaw('col = ?', [$value]);
"SELECT * FROM t WHERE id = " . intval($id)
```
---
## コマンドインジェクション 検出パターン
```
重大度: CRITICAL
├── exec($cmd . $input)
├── shell_exec($cmd . $input)
├── system($cmd . $input)
├── `$cmd $input`
├── eval($code)
├── include($userPath)
└── preg_replace('/.../e', ...)
重大度: HIGH
├── call_user_func($userCallback)
├── Process::fromShellCommandline($cmd)
└── Artisan::call($userCmd)
```
### コマンドサニタイザー関数(これらは安全と判定)
```php
escapeshellarg($arg) 引数エスケープ
escapeshellcmd($cmd) コマンドエスケープ
basename($path) ファイル名のみ
intval($var) 型キャスト
```
### コマンドサニタイザー破壊パターン(危険)
```php
urldecode(escapeshellarg($var))
str_replace("'", "", escapeshellarg($var))
stripslashes(escapeshellcmd($var))
```
### 安全なパターン
```php
$process = new Process(['cmd', $arg1, $arg2]);
exec(escapeshellcmd($cmd) . ' ' . escapeshellarg($a));
exec('ls -la ' . escapeshellarg($path));
exec('kill ' . intval($pid));
```
---
## パストラバーサル 検出パターン
```
重大度: HIGH
├── file_get_contents($userPath)
├── fopen($userPath, 'r')
├── unlink($userPath)
├── move_uploaded_file($tmp, $userDest)
└── response()->download($userPath)
重大度: MEDIUM
├── Storage::get($userPath)
└── Storage::put($userPath, $content)
```
### パスサニタイザー関数(これらは安全と判定)
```php
basename($path) ディレクトリ除去
realpath($path) パス正規化
pathinfo($path, PATHINFO_BASENAME) ファイル名抽出
intval($id) 数値ID
Str::random(40), Str::uuid() 安全なファイル名
$file->hashName() ハッシュファイル名
```
### 危険なパストラバーサルパターン
```
.. ✗ ディレクトリトラバーサル
../ ..\\ ✗ Unix/Windows
%2e%2e ✗ URLエンコード
%252e%252e ✗ ダブルエンコード
```
### パスサニタイザー破壊パターン(危険)
```php
urldecode(basename($var)) %2e%2e -> ..
base64_decode($var) トラバーサル隠蔽
$file->getClientOriginalName() ユーザー制御
```
### 安全なパターン
```php
$safePath = basename($userInput);
$realPath = realpath($path);
if (str_starts_with($realPath, $allowedDir)) { ... }
'/docs/' . intval($id) . '.txt'
$request->file('doc')->hashName()
```
---
## 認証 検出パターン
```
重大度: HIGH
├── md5($password)
├── sha1($password)
├── $password = 'hardcoded'
└── base64_encode($password)
重大度: MEDIUM
├── $token == $userToken # タイミング攻撃
└── password_hash($pw, ..., ['cost' => 4])
```
### 安全なパターン
```php
password_hash($pw, PASSWORD_ARGON2ID);
password_verify($input, $hash);
hash_equals($expected, $actual);
Hash::make($password);
```
---
## CSRF/セッション 検出パターン
```
重大度: HIGH
└── <form method="POST"> without @csrf
重大度: MEDIUM
├── session_start() without secure options
├── Cookie without httponly
└── session_regenerate_id() without true
```
### 安全なパターン
```blade
<form method="POST">
@csrf ✓
@method('PUT') ✓
</form>
```
```php
session_start([
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Strict',
]);
session_regenerate_id(true);
```
---
## 設定 検出パターン
```
重大度: HIGH
├── phpinfo()
└── unserialize($data) without allowed_classes
重大度: MEDIUM
├── dd($var), dump($var)
├── var_dump($var), print_r($var)
├── error_reporting(-1)
├── ini_set('display_errors', '1')
└── Log::info($password)
```
---
## CLI 使用方法
```bash
# 基本
php bin/security-lint <path>
# オプション
-f, --format 出力形式 (text|json|html|sarif|markdown)
-s, --severity 最小重大度 (low|medium|high|critical)
-o, --output ファイルに出力
-l, --lang 言語 (ja|en)
-e, --exclude 除外パターン
-d, --recursive-depth 再帰深度 (default: 10)
--verbose 詳細表示
# 例
php bin/security-lint app/ -s high -f json -o report.json
php bin/security-lint resources/views/ -l en
```
---
## 終了コード
| コード | 意味 |
|--------|------|
| 0 | 問題なし |
| 1 | 中/低重大度の問題あり |
| 2 | クリティカル/高重大度の問題あり |