ASP(Active Server Pages)はパーセントエンコード文字列のデコード時に半端なパーセント記号を除去する

yamagataさんの日記経由。MS ASPは、不正なパーセントエンコードされた文字列をデコードする際に、パーセント記号「%」を除去するようです。下表に、ASPでのデコード例と、その他の処理系を代表してPerlCGIモジュール(CGI.pm)でのデコード例を挙げました。

元の文字列 デコード後(ASP) デコード後(CGI.pm) 備考
%41%31%21 A1! A1! 正常パターン
%XJ XJ %XJ %の後が16進文字列でない
%AJ AJ %AJ %の後一文字だけ16進文字列
DEC%ORD DECORD DEC%ORD %が除去される
DEC%%%ORD DECORD DEC%%%ORD 複数の%が除去される

yamagataさんも指摘されているように、アプリケーション側で脆弱性対策をしている場合には、このような挙動の違いは気にしなくてもよいことです。アプリケーションプログラマは、デコード後の文字列を正しい入力として扱って、HTMLエスケープなり、SQL文字列リテラルエスケープなどをすればよいからです。
一方、IDS/IPS/WAFの場合は、このような挙動の違いは重要です。WAF側で「問題なし」と判定された文字列が、ASP記述のアプリケーションでは攻撃を受ける可能性があるからです。

IDS/IPS/WAF側でこの問題に対応するのは、少し面倒な気がします。拡張子などでASPかどうかを判定してパーセントデコードのロジックを動的に切り替えるか、半端なパーセント記号はアプリ側で除去されてもよいように、安全側に倒してパーセントデコードのロジックやシグネチャを変更するなどでしょうか。