PHP/Laravel セキュリティリンター 検出ルール一覧
このドキュメントでは、セキュリティリンターが検出できる脆弱性パターンを詳細に説明します。
目次
- XSS (クロスサイトスクリプティング)
- SQLインジェクション
- コマンドインジェクション
- パストラバーサル
- 認証セキュリティ
- CSRF/セッションセキュリティ
- 設定セキュリティ
1. XSS (クロスサイトスクリプティング)
1.1 Blade テンプレートの生出力
| パターン |
重大度 |
説明 |
{!! $var !!} |
HIGH |
エスケープされていない変数の出力 |
{!! $array['key'] !!} |
HIGH |
配列アクセスの生出力 |
{!! $obj->prop !!} |
HIGH |
プロパティアクセスの生出力 |
安全と判定されるパターン:
1.2 エスケープ破壊関数の検出
エスケープ処理を無効化する関数呼び出しを検出します。
| 関数 |
説明 |
html_entity_decode() |
HTMLエンティティをデコード |
htmlspecialchars_decode() |
htmlspecialchars の逆変換 |
urldecode() |
URLエンコードをデコード |
rawurldecode() |
rawurlencode の逆変換 |
base64_decode() |
Base64 デコード |
json_decode() |
JSON デコード |
stripslashes() |
スラッシュを除去 |
stripcslashes() |
C スタイルのスラッシュを除去 |
検出例:
1.3 危険なハードコード HTML の検出
文字列リテラル内の危険な HTML を検出します。
| 検出パターン |
説明 |
<script> |
スクリプトタグ |
<iframe> |
iframe タグ |
<object>, <embed> |
プラグインタグ |
<meta>, <link>, <base> |
メタ情報タグ |
<form> |
フォームタグ(フィッシング) |
onclick=, onerror= 等 |
イベントハンドラ |
javascript: |
JavaScript プロトコル |
vbscript: |
VBScript プロトコル |
data:...;base64 |
Data URL |
検出例:
1.4 JavaScript コンテキスト
| パターン |
重大度 |
説明 |
<script>{{ $var }}</script> |
MEDIUM |
script 内の Blade 出力 |
<script>{!! $var !!}</script> |
CRITICAL |
script 内の生出力 |
@json($var) in <script> |
LOW |
JSON ディレクティブの使用 |
推奨される対策:
1.5 URL コンテキスト
javascript: URL によるXSSを検出します。
| パターン |
重大度 |
href="{{ $url }}" |
MEDIUM |
src="{{ $url }}" |
MEDIUM |
action="{{ $url }}" |
MEDIUM |
formaction="{{ $url }}" |
MEDIUM |
安全と判定されるパターン:
1.6 イベントハンドラ
| パターン |
重大度 |
onclick="{{ $var }}" |
HIGH |
onerror="{{ $var }}" |
HIGH |
onload="{{ $var }}" |
HIGH |
onclick="{!! $var !!}" |
CRITICAL |
推奨される対策:
1.7 Style インジェクション
| パターン |
重大度 |
style="{{ $css }}" |
MEDIUM |
style="color: {{ $color }}" |
MEDIUM |
1.8 引用符なし属性
| パターン |
重大度 |
data-value={{ $var }} |
LOW |
1.9 テンプレートインジェクション
| パターン |
重大度 |
@include($var) |
HIGH |
@extends($var) |
HIGH |
@component($var) |
HIGH |
@each($var, ...) |
HIGH |
1.10 SVG コンテキスト
| パターン |
重大度 |
<svg>{{ $var }}</svg> |
MEDIUM |
1.11 @php ブロック
| パターン |
重大度 |
@php echo $var; @endphp |
MEDIUM |
1.12 PHP の echo/print
| パターン |
重大度 |
echo $taintedVar; |
HIGH |
print $taintedVar; |
HIGH |
printf("%s", $taintedVar) |
HIGH |
1.13 ユーザー定義関数の再帰解析
リンターは、ユーザー定義関数を再帰的に解析して、戻り値がエスケープされているかを判定します。
2. SQLインジェクション
2.1 Laravel クエリビルダー
| パターン |
重大度 |
DB::raw($userInput) |
HIGH |
DB::select($query . $userInput) |
HIGH |
->whereRaw($userInput) |
HIGH |
->selectRaw($userInput) |
HIGH |
->orderByRaw($userInput) |
HIGH |
->havingRaw($userInput) |
HIGH |
->groupByRaw($userInput) |
HIGH |
安全なパターン:
2.2 PDO
| パターン |
重大度 |
$pdo->query($sql . $input) |
HIGH |
$pdo->exec($sql . $input) |
HIGH |
$pdo->prepare($sql . $input) |
HIGH |
2.3 MySQLi
| パターン |
重大度 |
$mysqli->query($sql . $input) |
HIGH |
mysqli_query($conn, $sql . $input) |
HIGH |
2.4 文字列連結によるクエリ構築
| パターン |
重大度 |
"SELECT * FROM users WHERE id = " . $id |
HIGH |
"SELECT * FROM users WHERE id = {$id}" |
HIGH |
2.5 SQLサニタイザー関数の検出
リンターは以下のサニタイザー関数を認識し、適切に使用されている場合は安全と判定します。
| 関数/メソッド |
説明 |
intval(), floatval() |
型キャスト(最も安全) |
(int), (float) |
型キャスト演算子 |
mysqli_real_escape_string() |
MySQLi エスケープ |
PDO::quote() |
PDO エスケープ |
pg_escape_string(), pg_escape_literal() |
PostgreSQL エスケープ |
addslashes() |
基本的なエスケープ(非推奨) |
filter_var() + FILTER_VALIDATE_INT |
検証フィルター |
安全と判定されるパターン:
2.6 SQLサニタイザー破壊パターン
サニタイズ後に以下の関数を使用すると、サニタイズが無効化されます。
| 関数 |
説明 |
stripslashes() |
エスケープを解除 |
urldecode() |
URLデコードで特殊文字を復活 |
html_entity_decode() |
HTMLエンティティをデコード |
base64_decode() |
Base64 デコード |
sprintf() |
フォーマット文字列で迂回可能 |
危険なパターン:
2.7 ユーザー定義関数の再帰解析
リンターはユーザー定義関数を再帰的に解析し、安全かどうかを判定します。
3. コマンドインジェクション
3.1 シェル実行関数
| 関数 |
重大度 |
exec($cmd . $input) |
CRITICAL |
shell_exec($cmd . $input) |
CRITICAL |
system($cmd . $input) |
CRITICAL |
passthru($cmd . $input) |
CRITICAL |
proc_open($cmd . $input, ...) |
CRITICAL |
popen($cmd . $input, ...) |
CRITICAL |
`$cmd $input` (バッククォート) |
CRITICAL |
3.2 コード実行関数
| 関数 |
重大度 |
eval($code) |
CRITICAL |
create_function($args, $code) |
CRITICAL |
assert($expr) (文字列引数) |
CRITICAL |
preg_replace('/.../e', ...) |
CRITICAL |
3.3 コールバック関数
| 関数 |
重大度 |
call_user_func($userCallback) |
HIGH |
call_user_func_array($userCallback, ...) |
HIGH |
array_map($userCallback, ...) |
HIGH |
array_filter($arr, $userCallback) |
HIGH |
3.4 ファイルインクルード
| 関数 |
重大度 |
include($userPath) |
CRITICAL |
include_once($userPath) |
CRITICAL |
require($userPath) |
CRITICAL |
require_once($userPath) |
CRITICAL |
3.5 Symfony Process
| パターン |
重大度 |
Process::fromShellCommandline($cmd . $input) |
HIGH |
new Process($stringCmd . $input) |
HIGH |
安全なパターン:
3.6 Laravel Artisan
| パターン |
重大度 |
Artisan::call($userCommand) |
HIGH |
3.7 コマンドサニタイザー関数の検出
リンターは以下のサニタイザー関数を認識し、適切に使用されている場合は安全と判定します。
| 関数 |
説明 |
escapeshellarg() |
単一の引数をエスケープ |
escapeshellcmd() |
コマンド全体をエスケープ |
basename() |
ファイル名部分のみ抽出 |
intval(), floatval() |
型キャスト |
安全と判定されるパターン:
3.8 コマンドサニタイザー破壊パターン
サニタイズ後に以下の関数を使用すると、サニタイズが無効化されます。
| 関数 |
説明 |
stripslashes() |
エスケープを解除 |
urldecode() |
URLデコードで特殊文字を復活 |
str_replace() |
エスケープ文字を削除可能 |
preg_replace() |
エスケープ文字を削除可能 |
sprintf() |
フォーマット文字列で迂回可能 |
危険なパターン:
3.9 ユーザー定義関数の再帰解析
リンターはユーザー定義関数を再帰的に解析し、安全かどうかを判定します。
4. パストラバーサル
4.1 ファイル操作関数
| 関数 |
重大度 |
file_get_contents($userPath) |
HIGH |
file_put_contents($userPath, ...) |
HIGH |
fopen($userPath, ...) |
HIGH |
readfile($userPath) |
HIGH |
unlink($userPath) |
HIGH |
copy($userPath, ...) |
HIGH |
rename($userPath, ...) |
HIGH |
4.2 ファイルアップロード
| パターン |
重大度 |
move_uploaded_file($tmp, $userDest) |
HIGH |
4.3 Laravel Storage
| パターン |
重大度 |
Storage::get($userPath) |
MEDIUM |
Storage::put($userPath, ...) |
MEDIUM |
Storage::delete($userPath) |
MEDIUM |
Storage::download($userPath) |
MEDIUM |
4.4 レスポンスダウンロード
| パターン |
重大度 |
response()->download($userPath) |
HIGH |
response()->file($userPath) |
HIGH |
4.5 パスサニタイザー関数の検出
リンターは以下のサニタイザー関数を認識し、適切に使用されている場合は安全と判定します。
| 関数 |
説明 |
basename() |
ディレクトリ成分を除去(最も効果的) |
realpath() |
パスを正規化し、存在を確認 |
pathinfo(..., PATHINFO_BASENAME) |
ファイル名部分のみ抽出 |
intval() |
数値IDに限定 |
Str::random(), Str::uuid() |
安全なファイル名生成 |
$file->hashName() |
ハッシュベースの安全なファイル名 |
安全と判定されるパターン:
4.6 危険なパストラバーサルパターン
以下のパターンが文字列リテラルに含まれている場合、警告します。
| パターン |
説明 |
.. |
ディレクトリトラバーサル |
../, ..\\ |
Unix/Windows トラバーサル |
%2e%2e |
URLエンコードされた .. |
%252e%252e |
ダブルURLエンコード |
..%c0%af, ..%c1%9c |
オーバーロング UTF-8 エンコード |
4.7 パスサニタイザー破壊パターン
サニタイズ後に以下の関数を使用すると、サニタイズが無効化されます。
| 関数 |
説明 |
urldecode() |
%2e%2e → .. |
rawurldecode() |
URLデコード |
base64_decode() |
Base64 でトラバーサルを隠蔽可能 |
hex2bin() |
16進数でトラバーサルを隠蔽可能 |
html_entity_decode() |
HTMLエンティティをデコード |
chr() |
文字を構築可能 |
危険なパターン:
4.8 ユーザー定義関数の再帰解析
リンターはユーザー定義関数を再帰的に解析し、安全かどうかを判定します。
5. 認証セキュリティ
5.1 弱いハッシュアルゴリズム
| 関数 |
重大度 |
md5($password) |
HIGH |
sha1($password) |
HIGH |
sha256($password) |
MEDIUM |
hash('md5', $password) |
HIGH |
5.2 不適切なパスワードハッシュ
| パターン |
重大度 |
password_hash($pw, PASSWORD_MD5) |
HIGH |
password_hash($pw, ..., ['cost' => 4]) |
MEDIUM |
5.3 ハードコードされた認証情報
| パターン |
重大度 |
$password = 'secret123' |
HIGH |
$apiKey = 'sk-xxx...' |
HIGH |
['password' => 'hardcoded'] |
HIGH |
5.4 タイミング攻撃
| パターン |
重大度 |
$token == $userToken |
MEDIUM |
strcmp($secret, $input) |
MEDIUM |
推奨:
5.5 Base64 エンコード
| パターン |
重大度 |
base64_encode($password) |
HIGH |
6. CSRF/セッションセキュリティ
6.1 CSRF トークン
| パターン |
重大度 |
<form method="POST"> without @csrf |
HIGH |
Form missing csrf_field() |
HIGH |
6.2 メソッドスプーフィング
| パターン |
重大度 |
PUT/PATCH/DELETE form without @method |
LOW |
6.3 セッション設定
| パターン |
重大度 |
session_start() without options |
MEDIUM |
Missing cookie_httponly |
MEDIUM |
Missing cookie_secure |
MEDIUM |
Missing cookie_samesite |
MEDIUM |
6.4 セッション固定化
| パターン |
重大度 |
session_regenerate_id() without true |
MEDIUM |
session_regenerate_id(false) |
MEDIUM |
6.5 Cookie セキュリティ
| パターン |
重大度 |
Cookie without httponly |
MEDIUM |
Cookie without secure |
MEDIUM |
Cookie without samesite |
MEDIUM |
7. 設定セキュリティ
7.1 デバッグ出力
| 関数 |
重大度 |
phpinfo() |
HIGH |
var_dump($var) |
MEDIUM |
print_r($var) |
MEDIUM |
dd($var) |
MEDIUM |
dump($var) |
MEDIUM |
7.2 エラー表示
| パターン |
重大度 |
error_reporting(-1) |
MEDIUM |
ini_set('display_errors', '1') |
MEDIUM |
ini_set('display_startup_errors', '1') |
MEDIUM |
7.3 安全でないデシリアライズ
| パターン |
重大度 |
unserialize($data) |
HIGH |
unserialize($data, ['allowed_classes' => true]) |
HIGH |
安全なパターン:
7.4 機密情報のログ出力
| パターン |
重大度 |
Log::info($password) |
MEDIUM |
logger($apiKey) |
MEDIUM |
7.5 ハードコードされた設定
| パターン |
重大度 |
'debug' => true |
MEDIUM |
'key' => 'hardcoded-secret' |
HIGH |
再帰的なテイント解析
リンターは、関数呼び出しを通じてユーザー入力(テイントデータ)がどのように伝播するかを追跡します。
テイントソース(汚染源)
サニタイザー(浄化関数)
以下の関数を通過したデータは、対応する脆弱性に対して安全と判定されます:
解析の深度
デフォルトで最大10レベルの関数呼び出しを追跡します。
使用例
重大度レベル
| レベル |
説明 |
| CRITICAL |
即時対応が必要。直接的な攻撃が可能 |
| HIGH |
早急な対応が必要。重大な脆弱性 |
| MEDIUM |
計画的な対応が必要。潜在的なリスク |
| LOW |
改善推奨。ベストプラクティス違反 |
制限事項
- 静的解析の限界: 実行時の値は判定できません
- 動的なメソッド呼び出し:
$obj->$method() は追跡困難
- 外部ライブラリ: vendor 内のコードは解析対象外
- フレームワーク固有の機能: 一部のLaravel固有パターンは検出できない場合があります
- 偽陽性: 安全なコードが危険と判定される場合があります
バージョン
- ドキュメント作成日: 2024
- 対応 PHP バージョン: 8.0+
- 対応 Laravel バージョン: 9.x, 10.x, 11.x