あえて。あえて「サニタイズ」書かずに「入力時無毒化」と書いてみます*1。
先日もまぁドカドカと叩いたのですが、ちと色々と考察を。
元ネタとして、キーワード「入力時 サニタイズ」でググって色々なサイトを見に行ってます。
# つまらん事に「入力時のサニタイズは駄目よん」なPageが多くてネタ探しに苦労しましたw
端的に書くと。入力時に処理してしまうと
- 適切なエスケープが出来ない(HTML出力用のエスケープ処理とSQL出力用のエスケープ処理とコマンドライン出力用のエスケープ処理はそれぞれ「全く異なる」処理…ってのは今更だよね?)
- 二重エスケープ、エスケープ漏れ(後述)などの発生で面倒な配慮が必要
っていう問題があります。
とりあえず各記事に改めて丁重に突っ込みw
http://www.hotfix.jp/archives/word/2004/word04-17.html
一般的にサニタイジングは、入力データのチェック時に行うこと、とされている。
どんな一般よ? *2
http://www.intel.co.jp/jp/business/glossary/27072949.htm
ここも同じ事が書いてある。…コピペ?
http://maglog.jp/mcierror/index.php?module=Article&action=ReaderDetail&article_id=46518
入力の正規化というのは常に必要で、ウェブに限らず普通のWinアプリでも一緒なんだが、こう考えるとわかりやすいだろう。
と書くといかにも正論ちっくなのだが。実際に処理を書けという話をしてちゃんとうなずける処理が書けた状況を見た事がない。
「そんなまか不思議な処理はない」のだから当然なのだが。
http://www.oopstyle.net/doc/57.html
えと…HTML出力限定?
デザイナーがやる仕事なの?
又、サニタイズが必要なのは文字列なので、数値や日付などはサニタイズの意味が無いでしょう。INT型なら(int)でキャストしてしまえばサニタイズの必要はありませんから。
日付だと例えば/とか入るけど。んで「ノーチェックでいいやとか思ったらそこからアタックされた」らどうするんだべさ?
http://slashdot.jp/comments.pl?sid=413123&threshold=-1&commentsort=3&mode=thread&pid=1396392
事件は入力段階で起こるんでないの?
入力しただけではなにも起きない。
入力データが「攻撃者が意図している出力先」に「(攻撃者にとって)適切に」出力された時に事件が起きる。
SQLにJavaScriptのアタック用のタグとかコードとか書いたの入れてもなにもしてくれないでしょ?
HTMLにinsert文とか書いてもDBにinsertは出来ないでしょ?
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=28217&forum=7&start=16
はい、ただしXSSに対応したサニタイジングとSQLインジェクションに対応したサニタイジング
は別物ですので注意が必要です。通常は、SQLインジェクションへの対応は入力時、XSSへの
対応は出力時に行います。
は? なぜ?
いずれも「出力時に出力のTOPにあわせたエスケープが必要」なだけですが。
http://www1.mahoroba.ne.jp/~mitt/itmemo/webappsecurity/04.htm
1.入力値チェックの強化
入力値に特殊な文字列が含まれている場合はエラー扱いにする。
2.サニタイジング(sanitizing)(無害化)
有害となる文字そのものを無害な文字に変換する。
・<→&lt;
・>→&gt;
・&→&amp;
・"→&quot;
・'→&#39;
………すみませんそろそろ突っ込むの疲れてきました orz
http://blog.webcreativepark.net/2008/10/24-201629.html
foreach($_GET as $key => $value){
$_GET[$key] = htmlspecialchars(htmlspecialchars_decode($value,ENT_QUOTES),ENT_QUOTES);
}
foreach($_POST as $key => $value){
$_POST[$key] = htmlspecialchars(htmlspecialchars_decode($value,ENT_QUOTES),ENT_QUOTES);
}
今気づいたのですが。例えば、出力として
<A href="test&test">
と出力したい時。上述ルーチンを通してしまうと、「サンプルコードで一度デコードを行ってからエスケープを行っているのは実体参照化された文字列に更に実体参照化していくと「&amp;amp;」とえらい事になるからです。」という余計な処理(アイデア?)のおかげで、意図する出力にならなかったりします。
おいといて。
別に出力時のエスケープと併用しても問題ないかなと思いますし。
二重エスケープになって思いっきり問題有りすぎると思うのですが如何でしょうか?
番外編
http://www.softek.co.jp/Sec/mod_security3.html
SecFilter "[\"]" deny または SecFilter "[']" deny
SecFilter "[<]" deny
SecFilter "[>]" denyWebアプリケーションによっては上記の文字列を通常のリクエストに使用することも考えられます。その場合は、制限を緩める必要があるかもしれません。
…えと「その場合は、制限を緩める必要がある」場合どうするのさ?
続きますw