作成日:2018-05-02, 更新日:2022-03-29
基本
もろもろ偽装もあり得るので、絶対的に安心という訳ではない。
以下は順不同。
呼び出し元の確認
PHP側で「$_SERVER['HTTP_REFERER']」をチェック。
想定外なドメインやページなどから来てたら、拒否するなり、終了させるなりする。
ajaxから来たのか確認
jqueryなどのライブラリを使ったajax通信の場合は「$_SERVER['HTTP_X_REQUESTED_WITH']」が「XMLHttpRequest」になる。
※『ajaxのときは「HTTP_X_REQUESTED_WITH」がある。そして値は「XMLHttpRequest」になる』が正解か?
ファイルのup
例えば、PHPファイルなどのような何かを実行できるようなファイルをup。
そのファイルにアクセス(実行させる)→悪いコトされる可能性を考慮する
ファイル名を変更して、実行されにくくする
推測されにくいファイル名にする。
upしたファイルにアクセスできないようにする
.htacessなどで、非公開にしたフォルダに入れるなり、アクセス禁止にするなり・・・。
▼.htacessでアクセス拒否(ブラウザのみ)
Deny from all
CSRF対策
form送信時のCSRF(Cross-site Request Forgery:リクエスト強要)対策。
規定のフォームを通さずに来たデータを無視するってヤツ。
・FuelPHPの場合:FuelphpでCSRF対策
不正なデータ:XSS、Script Insertion
「XSS(クロス・サイト・スクリプティング)」、「Script Insertion(スクリプト埋め込み)」ってヤツらの対策。
パラメータにスクリプトを埋め込んで何かするってヤツ。
・「XSS」は「他所のページにリダイレクトさせる」。
・「Script Insertion」は「スクリプトを実行させる」って感じ。
例えばスクリプトじゃないけど・・・「<b>zebra</b>」という値を受け取った場合。
・処理せず表示→「zebra」:「<b>」が「bタグ」として扱われる。
・処理して表示→「<b>zebra</b>」:「<b>」を「<b>」に変換して表示することによってタグじゃなく文字列として扱う。
対策は、スクリプトをただの文字列扱いにする。
PHPで対策:htmlspecialchars()
$hoge = htmlspecialchars($_GET['hoge'], ENT_QUOTES);
SQL Injection
「XSS」、「Script Insertion」のSQL版。
DBへのクエリ発行時に何かを実行させようとするってヤツ。
対策は、受け取ったデータを文字列等に変換してからクエリ発行。
PHP
▼例えば下記のような命令とクエリ(PHP)
$q = 'select * from 〇〇〇 where 〇〇〇 = "' . $_GET[〇〇〇] . '"';
▼「$_GET[〇〇〇]」の値の例
・「zebra」などのような文字列なら「select * from 〇〇〇 where 〇〇〇 = "zebra"」となり、問題無し。
・「"; delete 〇〇〇 "」などのようなクエリだったら「select * from 〇〇〇 where 〇〇〇 = ""; delete 〇〇〇 ""」となり、問題アリ。
これは、「管理者が用意したクエリを実行」ってのを希望しているのに「利用者が用意したクエリも実行」となるのが問題。
PDOを使っているならバインディングが用意されている。
※PDOを使っていなくても似たような何かが用意されているはず。最悪、自分でエンコードするなりすればOK。
具体例:下記のようなソース
$val = 'hoge'; $sql = 'select * from `kushi` where id="' . $val . '"';
▼想定している「$val="1";」なSQL
SELECT * FROM `kushi` where id="1"
→実行結果は「id="1"」を満たすレコードのみ表示。
▼想定外の「$val='" or 1="1';」なSQL
SELECT * FROM `kushi` where id="" or 1="1"
→実行結果は全件表示
インラインフレームでの読込み拒否
クリックジャッキングの対策。
対象ページで、何かを出力する前に下記。
header('X-Frame-Options: DENY'); // 拒否 // header('X-Frame-Options: SAMEORIGIN'); // 同一ドメインのみOK
タイミングセーフ、タイミング攻撃
「タイミング攻撃」って何?ってコトで少し調べてみた。
ざっくりと「タイミング攻撃」を知りたかっただけなので最新の情報を調べたわけじゃない。
タイミング攻撃の対策
タイミング攻撃の対策は「hash_equals()」っていう関数を使う。
→「hash_equals()」がタイミングセーフな文字列比較関数となる。
※情報が古いので現段階ではもっと異なる関数があるかもしれない。
タイミング攻撃
▼このようなソースのとき(※「===」が「==」でも同じ)
if ( $pwd === $_GET['pwd'] ) { // OK }
「===」の内容
やっている内容が
1.文字数の比較
2.文字列の1文字目の比較
3.文字列の2文字目の比較(以下、同様)
の順番。
タイミング攻撃の解析方法
・「1.文字数の比較」で一致しないときはすぐに「false」が返ってくる
・「2.文字列の1文字目の比較」で一致しないとすぐに「false」が返ってくる
・「3.文字列の2文字目の比較」以降も同様
→レスポンスの時間で「true / false」を解析することが可能