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

PHPの各PDOドライバは、静的プレースホルダ/動的プレースホルダのどちらを使用しているのか?

目次今のところの結論MySQL (PDO_MYSQL)の場合その他のデータベース用ドライバ参考 今のところの結論 データベースにも依るだろうが、そもそもプリペアドステートメントが使えないSQL文法があ …

no image

セキュリティに関連するリンク集

情報は随時追加します。 目次毎日チェックするとよいウェブページ一般Webアプリケーション関連WordPress関連インシデント 毎日チェックするとよいウェブページ IPA 独立行政法人 情報処理推進機 …

no image

パス名パラメータの未チェック/ディレクトリ・トラバーサル by IPA「安全なウェブサイトの作り方 第7版」

安全なウェブサイトの作り方:IPA 独立行政法人 情報処理推進機構の、「パス名パラメータの未チェック/ディレクトリ・トラバーサル」から一部抜粋する。(この資料はPDFでしか提供されていない) …

PHP

Laravel 5 でのセキュリティ対策 (PHP)

目次1. ユーザーによる入力値の検証入力パラメータ値のエンコーディングが正しいことをチェックするMiddlewareの例制御文字を禁止するバリデーションルールを追加する例1. バリデーション用のクラス …

セキュリティ

アプリケーションをインストールする際は、事前に実行ファイルのウイルスチェックを行っておきましょう

目次1. はじめに2. VirusTotal とは?3. VirusTotal(日本語ページ)を使う手順4. VirusTotal(英語ページ)を使う手順5. おわりに 1. はじめに 以下の状況にお …