前回に引き続き,
UTF-7によるXSSは,
そして,
- レスポンスヘッダ,
meta要素のどちらでもcharsetが指定されていない - charsetにIEが解釈できないエンコーディング名が指定されている
- meta要素でcharsetを指定しているときに,
meta要素より前に攻撃者が文字列を挿入可能
これらの条件において,
レスポンスヘッダ, meta要素のどちらでもcharsetが指定されていない
たとえば,
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head><title>test page</title></head>
<body>
+ADw-script+AD4-alert(1)+ADw-/script+AD4-
</body>
</html>
見ての通り,
IEを使ってこのようなHTMLを開いた場合,
あるいは,
<meta http-equiv='content-type' content='text/html;charset=UTF-7'>
...
<iframe src='http://example.com/target.html'></iframe>
charsetにIEが解釈できないエンコーディング名が指定されている
HTTPレスポンスヘッダあるいはHTMLのmeta要素内で文字エンコーディング名を指定したとしても,
IEが理解できない文字エンコーディング名としてよくあるのは,
- EUC (正しくは "EUC-JP" です)
- UTF8 (正しくは "UTF-8" です)
- JIS ("ISO-2022-JP"を指定します)
- CP932/
MS932 など ("Shift_ JIS"を指定します)
これらが文字エンコーディング名として "text/
IEが確実に解釈できるエンコーディング名の代表的なものは以下の通りです。
- EUC-JP
- UTF-8
- ISO-2022-JP
- Shift_
JIS
文字エンコーディング名を出力する際には,
meta要素でcharsetを指定しているときに, meta要素より前に攻撃者が文字列を挿入可能
IEが正しく解釈できる文字エンコーディング名を出力している場合でも,
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head>
<title>+ADw-/title+AD4APA-script+AD4-alert(1)+ADw-/script+AD4-</title>
<meta http-equiv="content-type" content="text/html;charset=Shift_JIS">
</head>
...
たとえば,
まとめ
このように,
攻撃側は,
前回の繰り返しになりますが,
Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=Shift_JIS
Content-Type: text/html; charset=EUC-JP
のいずれかを出力するというシンプルなルールで完全に防ぐことができます。
本稿が少しでもみなさんのセキュアなWebアプリケーション作成の手助けとなれば幸いです。