Security

Relative Path Overwrite (RPO) の動作について

投稿日:2022年6月6日 更新日:

1. はじめに

Webサイトに関する脆弱性の1つに「Relative Path Overwrite (RPO)」があります。

こんな感じの脆弱性です。

URLを少し工夫してWebページにアクセスすると、そのページ内にある「相対パスで読み込み指定されているCSSファイル」の部分で、CSSファイルの代わりにアクセス対象であるHTMLファイルが読み込まれてしまう(HTMLファイルがCSSファイルとして読み込まれてしまう)。

➡ そのHTMLファイルの中に、うまいことCSSが記述されていると、ちゃんとCSSとして評価されて実行されてしまう(HTMLがQuirksモードで実行されるように記述されている必要もある)。つまり、アクセス対象のHTMLファイルに対して、同じHTMLファイル内のCSSコードが適用される。

➡ そのHTMLファイルの中に「ユーザーが入力した文字列が出力される箇所」があった場合、ユーザーが入力した任意のCSSが実行されることになる!(その箇所がHTMLエスケープされていても、CSSには影響がない)

次では、もう少し具体的にRPOの動作ついて説明します。

2. Relative Path Overwrite (RPO) の動作を説明する

RPOといってもいろいろなタイプがあるようですが、ここで取り上げるのはかなりシンプルなケースになります。

(1) 前提

以下を満たすWebページがあるとします。

  1. ユーザーが登録した情報が表示される。
  2. CSSファイルが相対パスで読み込まれている。
    • 例:「<link rel=”stylesheet” href=”main.css”>」
  3. DOCTYPE として「<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>」が出力されている。
    • この記述により、HTMLがQuirksモードで実行される。
  4. URLは「https://example.com/index.html」であるが、「https://example.com/index.html/」にアクセスしても、同じページが表示される。

(2) どうやって問題が起きるか

以下の操作によって、ユーザーが入力した任意のCSSが正常に動作してしまいます。

  1. ユーザーが登録情報の1つに「{}*{color:blue;}」を登録する。
    • 今回は例として「*{color:blue;}」としましたが、この部分に任意のCSSを指定します。
    • これが index.html に表示されます。
  2. ブラウザで「https://example.com/index.html/」にアクセスする。
    • 相対パスで指定していたCSSファイルの部分で、ブラウザは /index.html/main.css にリクエストを送るが、サーバーは index.html を返してしまう。
    • その index.html には「{}*{color:blue;}」が出力されている。この出力箇所がHTMLエスケープ処理されていたとしても、あくまでHTMLに対するエスケープ処理なので、CSSのエスケープにはならない。
  3. ブラウザは index.html をレンダリングするが、同時に index.html をCSSとしても利用することになる。
    • ブラウザが index.html をCSSとして解釈するかどうかは、「DOCTYPE」「CSSの書き方」の2つが重要です(ブラウザにも依るようですが)。今回はCSSの部分で最初に「{}」と書いており、これによってブラウザはCSSとして解釈してくれる。他にも書き方がある。
  4. index.html に出力されたCSSが適用されて、index.html が表示される。

ブラウザのデベロッパーツールを使い、「CSSファイルを取得するリクエストのURL」や「そのリクエストが返した内容」を観察するとよいです。

デモページを用意しました。

デモページ

🔗 RPO の実験

3. 対策

  • 相対パスでCSSを読み込むのはやめましょう。
  • DOCTYPE は「<!DOCTYPE html>」と指定すべきです。
  • レスポンスヘッダに「X-Content-Type-Options: nosniff」を出力することでも、この脆弱性は避けられるようです。

4. おわりに

今どき、古い DOCTYPE が使われていることはあまりないと思いますが、本記事に書いた仕様のページがあった場合、最新の Chrome でもこの現象が起きてしまうのが怖いところです。

5. 参考

PHP

PHPで baseタグを出力する(RPO対策)

2022.06.17

📂-Security

執筆者:labo


comment

メールアドレスが公開されることはありません。

関連記事

Web Security

CSP Level 3 で Strict CSP を利用する

CSP Level 3 で Strict CSP を利用する方法について説明します。

amazon

Amazon.co.jp の2段階認証で、スマートフォンを紛失した場合に備える

目次1. はじめに2. バックアップコードの機能がない3. スマートフォン紛失時のログイン手段として「コードが要求されない端末」を利用する4. 現時点でのまとめ 1. はじめに Amazon.co.j …

no image

クリックジャッキング(Clickjacking)対策

対策 方法1:CSP(Content Security Policy) の frame-ancestors ディレクティブを使う。 方法2:HTTP レスポンスヘッダに、X-Frame-Options …

no image

IPA の「CMSを用いたウェブサイト構築における情報セキュリティ対策 4つのポイント」の重要な部分を抜粋する

目次1. はじめに2. CMS を構築されたウェブサイトを狙う攻撃と対策2.1. 脆弱性やウェブサイトの運用上の不備を悪用2.1.1. ソフトウェアの脆弱性2.1.2. 運用上の不備2.2. 認証を突 …

セキュリティ

GnuPGでファイルを暗号化・復号する手順

USBメモリにデータを入れて持ち運ぶ場合、なんの対策もしていないと「USBメモリの紛失」がそのまま「データ流出」につながります。これを防ぐ1つ方法は、予めファイルを暗号化した状態で保存しておくことです …