オーバーロングシーケンス UTF8 とは?

UTF-8 はISO 10646 の 31 ビット空間を 8 ビットに写像するエンコード方法です。 このエンコード、デコードを不正に行うことで、UTF-8 パーサーの脆弱性が攻撃される場合が過去にありました。

ある exploit では URL に %c0%af というシーケンスが利用されました。これがなぜ問題になるのかみてみましょう。

ここに見られる %c0%af は UTF-8 の URL エンコードです。これをデコードしてみましょう。

c0 af を 2 進数に直すと次のようになります。

11000000 10101111

ここで 110 で始まるシーケンスに関する UTF-8 のエンコードルールは次のようになります。

00000080 - 000007FF の場合、ISO 10646 のコードを 2 進数で 0000000 00000000 00000xxx xxyyyyyy と表したとき、 110xxxxxx, 10yyyyyy の 2 バイト列を UTF-8 のコードとする。

これに照らすと、(1) と合わせてxxxxx = 00000, yyyyyy = 101111 となります。

11000000 10101111
110xxxxx 10yyyyyy
表1: エンコードルールとの対応

したがって、元のビットシーケンスは 00000xxx xxyyyyyy の x と y を埋めることにより 00000000 00101111 と分かります。 これを 16 進数であらわすと 2F となります。これは ISO 10646 (ISO 646) のコード表から / (スラッシュ) をあらわすことが分かります。

上記のように %c0%af (c0 af) をデコードすると / となることが分かりましたが、しかし本来 UTF-8 エンコード規則では 00000000 - 000007F の範囲は下位のバイトをそのまま UTF-8 のコードとすべきなのです。 つまり、正しい / のUTF-8 表現は (文字コードそのままの) 2F です。

デコード規則に照らすと c0 af は 2f と等価であることは分かるものの、2f と比べて冗長であり不正です。 このような無効な UTF-8 コードは Overlong Sequence (オーバーロングシーケンス) と呼ばれています。

独自でパーサなどを書かれる場合は、このようなシーケンスにも注意を払うのをお忘れないようにしましょう。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説