応答ヘッダーで HttpServletRequest.getQueryString()
を使用すると、アプリケーションがHTTP応答分割攻撃を受けやすくなると言われましたが、その方法はわかりません。
パーセントエンコードされた値をデコードする getParameter(String)
の場合は明らかですが、getQueryString()
はそれを行いません。ドキュメントから:
値はコンテナによってデコードされません。
私がやっていることを示すソースコードスニペット:
_String path = "some_url";
String qs = req.getQueryString();
if (qs != null)
path += "?" + qs;
// response instanceof HttpServletResponse
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
response.setHeader("Location", path);
_
問題を再現しようとしたところ、パーセントエンコードされた改行が応答でエコーバックされました。コードをgetParameter(…)
に変更すると、期待どおりに機能します(ただし、私のコンテナーはヘッダー値から改行を削除するのに十分なナイスですが、少なくとも理論上は機能します)。 スタックオーバーフローに関するこの同様の質問 は同じ質問をし、getQueryString()
がデコードしないことを指摘する回答へのコメントは応答を取得しませんでした。
ここで何か不足していますか?それとも私が間違ったアドバイスですか?
ユーザーからのデータを無害化せずに使用する一般的なパターンは、脆弱性の原因です。 XSSやSQLiなどの典型的なもの。この場合、ユーザーからの入力を受け取り、それを直接ヘッダーにします。これにより、応答の分割、ヘッダーインジェクション、およびおそらく別の問題が発生する可能性があります(例:JavaScriptをインジェクトできる場合、CSRFが発生する可能性があります)。しかし、あなたはそれを述べています:
私のコンテナは、ヘッダー値から改行を削除するのに十分いいです
したがって、これは実際の悪用を防ぎます。
次のような入力をフィルタリングしたとしても、
path += "?" + sanitize(qs);
適切なsanitize
関数(たとえば OWASPのAntiSamyプロジェクト から)に対して、静的アナライザーはこの結果を引き続き提供します。したがって、最終的には、この発見を誤検知としてマークすることになります(Fortifyを使用している場合はNot an issue
)。唯一の問題は、検出結果を誤検出としてマークする前にコード変更を含める必要があるかどうかです。
私の見解では、APIが明示的に改行やその他の特殊文字の安全な処理を担当している場合、ユーザー側でのアクションは不要です。 HttpServletResponse.setHeader のJavadocを見ると、特殊文字の処理方法についての言及がありません。したがって、仕様でこれの安全な処理が明示的に記述されていない限り(私はそうは思わないが、サーブレット仕様でこれを調べなかった)、入力を無害化して静的スキャナーを再実行することをお勧めします。私の予想どおり、この問題が引き続き報告される場合は、誤検知のマークを付けて、すべてが正常であることを確認してください。
仕様で指定されている場合にのみこの動作を信頼するべきだと私が思う理由は、それが保証される唯一の動作だからです。新しいバージョンのサーブレットコンテナまたは別のコンテナを使用すると、この動作が変わる場合があります。サイトが脆弱になる可能性がありますが、そのような変更を検出することはほとんどありません。