IDS14-J. hiddenが指定された入力欄の内容を信頼しない
HTMLでは、ウェブフォームのフィールドにtype=hidden
を指定できる。hidden
が指定されたフィールドはサーバに値を送るが、ユーザにはその内容を変更する手段が提供されない。しかし、攻撃者がこれらの内容を変更する手段は存在する。また、パラメータの取得にGET
フォームを使うウェブサーブレットは、URLを通じてこれらのパラメータを受け入れる場合もある。URLでは、ユーザがウェブリクエストで任意のパラメータ名と値を設定できる。したがって、hidden
が指定された入力欄は、通常の入力欄より信頼できると考えるべきではない。
違反コード
以下の違反コード例は、通常のフィールドとhidden
が指定されたフィールドを受け入れ、ユーザにエコーバックするサーブレットを示している。通常のパラメータはブラウザに渡される前に無害化されるが、hidden
が指定されたフィールドは無害化されない。
public class SampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
String visible = request.getParameter("visible");
String hidden = request.getParameter("hidden");
if (visible != null || hidden != null) {
out.println("Visible Parameter:");
out.println( sanitize(visible));
out.println("<br>Hidden Parameter:");
out.println(hidden);
} else {
out.println("<p>");
out.print("<form action=\"");
out.print("SampleServlet\" ");
out.println("method=POST>");
out.println("Parameter:");
out.println("<input type=text size=20 name=visible>");
out.println("<br>");
out.println("<input type=hidden name=hidden value=\'a benign value\'>");
out.println("<input type=submit>");
out.println("</form>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
// 渡された文字列から、HTMLでセンシティブな文字を取り除く。
public static String sanitize(String message) {
// ...
}
}
param1
が渡されると、ウェブページは以下のように表示される。
Visible Parameter: param1
Hidden Parameter: a benign value
しかし、以下のようにURLにエンコードすることで、攻撃者はhidden
が指定されたパラメータの値を容易に設定できる。
http://localhost:8080/sample/SampleServlet?visible=dummy&hidden=%3Cfont%20color=red%3ESurprise%3C/font%3E!!!
このURLがブラウザに渡されると、ブラウザは以下のように表示する。
Visible Parameter: dummy
Hidden Parameter: Surprise!!!
適合コード
以下の解決法では、通常のパラメータに適用されるものと同じ無害化処理がhidden
が指定されたパラメータにも適用される。
public class SampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
String visible = request.getParameter("visible");
String hidden = request.getParameter("hidden");
if (visible != null || hidden != null) {
out.println("Visible Parameter:");
out.println( sanitize(visible));
out.println("<br>Hidden Parameter:");
out.println( sanitize(hidden)); // hiddenが指定された変数を無害化する
} else {
out.println("<p>");
out.print("<form action=\"");
out.print("SampleServlet\" ");
out.println("method=POST>");
out.println("Parameter:");
out.println("<input type=text size=20 name=visible>");
out.println("<br>");
out.println("<input type=hidden name=hidden value=\'a benign value\'>");
out.println("<input type=submit>");
out.println("</form>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
// 渡された文字列から、HTMLでセンシティブな文字を取り除く。
public static String sanitize(String message) {
// ...
}
}
この結果、悪意あるURLがブラウザに入力されると、サーブレットは以下のように表示する。
Visible Parameter: dummy
Hidden Parameter: <font color=red>Surprise</font>!!!
リスク評価
hidden
が指定された入力欄の内容を信頼すると、様々な厄介な問題を引き起こす可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
IDS14-J |
高 |
中 |
高 |
P6 |
L2 |
自動検出
ツール
|
バージョン
|
チェッカー
|
説明
|
---|---|---|---|
The Checker Framework |
2.1.3 |
Tainting Checker | Trust and security errors (see Chapter 8) |
CodeSonar |
8.1p0
|
JAVA.IO.INJ.CODE |
Code Injection (Java) |
Fortify | 6.10.0120 |
Hidden_Field |
Implemented |
参考文献
[Fortify 2014] | Fortify Diagnostic |
翻訳元
これは以下のページを翻訳したものです。
IDS14-J. Do not trust the contents of hidden form fields (revision 26)