がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

入力時無毒化の弊害への考察:突っ込み

あえて。あえて「サニタイズ」書かずに「入力時無毒化」と書いてみます*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で意味のある記号をエスケープすること(HTMLを無効化)

えと…HTML出力限定?

HTMLを表示する時、プログラマー、もしくはデザイナーが責任もってサニタイズするべきだと思ってます。

デザイナーがやる仕事なの?

又、サニタイズが必要なのは文字列なので、数値や日付などはサニタイズの意味が無いでしょう。INT型なら(int)でキャストしてしまえばサニタイズの必要はありませんから。

日付だと例えば/とか入るけど。んで「ノーチェックでいいやとか思ったらそこからアタックされた」らどうするんだべさ?


http://slashdot.jp/comments.pl?sid=413123&threshold=-1&commentsort=3&mode=thread&pid=1396392

事件は入力段階で起こるんでないの?

入力しただけではなにも起きない。
入力データが「攻撃者が意図している出力先」に「(攻撃者にとって)適切に」出力された時に事件が起きる。
SQLJavaScriptのアタック用のタグとかコードとか書いたの入れてもなにもしてくれないでしょ?
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);
}

今気づいたのですが。例えば、出力として

&lt;A href=&quot;test&amp;test&quot;&gt;

と出力したい時。上述ルーチンを通してしまうと、「サンプルコードで一度デコードを行ってからエスケープを行っているのは実体参照化された文字列に更に実体参照化していくと「&amp;amp;amp;」とえらい事になるからです。」という余計な処理(アイデア?)のおかげで、意図する出力にならなかったりします。


おいといて。

別に出力時のエスケープと併用しても問題ないかなと思いますし。

二重エスケープになって思いっきり問題有りすぎると思うのですが如何でしょうか?


番外編
http://www.softek.co.jp/Sec/mod_security3.html

クロスサイトスクリプティング対策

SecFilter "[\"]" deny または SecFilter "[']" deny
SecFilter "[<]" deny
SecFilter "[>]" deny

Webアプリケーションによっては上記の文字列を通常のリクエストに使用することも考えられます。その場合は、制限を緩める必要があるかもしれません。

…えと「その場合は、制限を緩める必要がある」場合どうするのさ?


続きますw

*1:んと…このへん微妙なのですが。厳密には、サニタイズはあくまで「無毒化」程度の意味しかないと私は思ってるのですが、大抵のところで「入力時に」と書かれています…なんでだろ? どこかに原典あるのかしらん?

*2:まぁその後に「しかし独立行政法人情報処理推進機構では、サニタイジングのタイミングをHTML生成時のタイミングで行うことを推奨している。」と書かれてるのですが