PHPセキュリティルール
PHP Safeスキャナーが確認する18のルール。それぞれに脆弱な例、安全な修正方法、CWE・OWASPの参照番号を掲載しています。
インジェクション 8
変数で組み立てたSQL(SQLインジェクション)
入力をSQLに直接連結すると、攻撃者がクエリ自体を書き換え、データベースのあらゆるデータを読み取り・変更・削除できます。プリペアドステートメントはクエリと値を別々に送るため、入力がSQLになることはありません。
詳しく →シェルコマンドの実行
シェルに渡された入力に ; や | を入れると別のコマンドを追加でき、攻撃者にサーバーを乗っ取られます。値を厳密に検証し、すべての引数をエスケープしましょう。
詳しく →eval() によるコード実行
eval()は受け取った文字列をPHPコードとして実行します。その一部でもリクエスト由来なら、攻撃者がサーバー上で任意のコードを実行できます。
詳しく →preg_replace の /e 修飾子
/e修飾子は置換文字列をPHPコードとして実行していました。PHP 7で削除されたため、使い続けていると古いサーバーでは危険で、新しいサーバーでは動きません。
詳しく →ユーザー入力によるファイル読込
リクエストの値でincludeパスを作ると、攻撃者がシステムファイルやPHP入りの画像、外部コードを読み込めます。サーバー全体を乗っ取られる最短ルートの一つです。
詳しく →変数で作ったinclude パス
変数で作ったincludeパスは、その変数にユーザー入力が絶対に入らない場合だけ安全です。上流のコードでリクエスト値が入っていることが多いので確認しましょう。
詳しく →信頼できないデータへの unserialize()
unserialize()は任意のオブジェクトを生成できるため、攻撃者は既存クラスを連結して(ガジェットチェーン)ファイル削除やコード実行を行えます。JSONは単純なデータしか作りません。
詳しく →リクエストデータへの extract()
extract()はリクエストの全フィールドを変数にするため、攻撃者はフォームに項目を一つ足すだけで $is_admin などの変数を上書きできます。
詳しく →出力・リダイレクト 2
ファイル・アップロード 2
暗号化・通信 3
md5() または sha1() の使用
md5やsha1は高速なため、漏えいしたパスワードハッシュは毎秒数十億回の試行で解読されます。password_hash()は意図的に遅く、ソルト付きです。
詳しく →予測可能な乱数
rand()、mt_rand()、uniqid()は予測可能です。パスワード再設定、セッション、CSRFのトークンは暗号論的に安全な乱数で作る必要があります。
詳しく →SSL証明書の検証を無効化
証明書の検証を切ると、通信経路上の誰でも呼び出し先APIになりすまし、APIキーを含むデータを盗み見たり改ざんしたりできます。
詳しく →