前回に引き続き、
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アプリケーション作成の手助けとなれば幸いです。