ryokatsu.dev

論文を読む(Exposing and Addressing Security Vulnerabilities in Browser Text Input Fields)


社会人大学生しているのに、論文とか読んでいないなーと思い手始めに何か読んでみようと思って読んだ。

論文の探し方

まず論文をどうやって探すかということで調べてみると色々なサイトがあったが、今回はarXivを利用した。コンピュータサイエンス系の論文が多くタイトルだけみても面白い。徐ろに検索バーに「HTML」という単語を入れて検索結果を眺めてたらExposing and Addressing Security Vulnerabilities in Browser Text Input Fieldsというのに目が止まり今回はこの論文を読むことにした。

論文の読み方

自分は英語のスキルがほとんどないので、DeepLさまの力をお借りした。DeepLのアプリでpdfをそのまま翻訳させて日本語になったpdfをiPadで読んだ。(無料版だと文字数制限があるので有料版で) ※もしかすると翻訳が違っていることもあり解釈が間違っているかもだけど。。

TL;DR

  • 拡張機能はページのコンテンツを操作できちゃう
  • inputタグはセキュアではない!
  • WeakMapすごい

拡張機能の怖さ

この論文は、ブラウザの拡張機能で、ページのコンテンツを改ざんできてしまい危険だよというのを提唱している論文だった。実際の計測と提案までが書かれたものになっている。論文は最初に内容を全部読まない人のためのTL;DR的なものが書かれていることが多いようなので、ここだけ読むだけでも良さそうだなとは思った。続きが気になればそのまま読むし、微妙であれば読むのをやめることもできる。

実際に、拡張機能からJavaScriptを実行して社会保険番号やクレジットカード番号、パスワードなどを取得できてしまうというもので、これらの取得は、HTMLのinputタイプに限定して話が進む。

拡張機能の審査についても書かれており、実際に審査を通過した拡張機能は、その後特に監視されることもなくそのまま使われることが多いというのも書かれていた。(まあそれはそうか。。そこまでチェックできないよね)

拡張機能のパーミッション設定などがあることは、恥ずかしながら知らずこのあたりは知見になった。(ホストパーミッションと、APIパーミッションがありそれぞれ設定するもの)しかもこのパーミッション設定は、粒度が粗いらしく、ここで分かることとして拡張機能とHTML要素の間にセキュリティの境界がないことを意味しているとのことだった。

以前まではManifest V2とルールでやっていたが、これは抜け穴が多くeval()の実行などもできてしまったとのことで現状は、Manifest V3になりセキュリティ的に大きな変更点があり(webRequest APIの廃止など)eval()などは実行できなくなった。しかしスクリプトの操作自体の変更はされておらず引き続き拡張機能とHTML要素の間にセキュリティの境界がないことになっている(SafariとFirefoxに関してはまだV2とのこと)

これも何となく知っていたけど、明確には知らなかったこととして拡張機能がロードされるとDOMツリーに統合され、DOM APIを介してすべてのDOMにアクセスできてしまうとのことだった。(document.querySelectorなどで)これは開発しているとたまに「拡張機能が悪さをして変な挙動になる」ことがあるけどまさにこれのことだった。

実際に悪意のある拡張機能がどのようにコンテンツを抽出するかのサンプルコードが乗っていた

(P23. Exposing and Addressing Security Vulnerabilities in Browser Text Input Fields)

fetch('server_url') // Retrieve CSS selector
  .then(response => response.text()) .then(data => {
  var els = document.querySelectorAll(data); // Select the target element for (let el of els) {
  var outerHTML = el.outerHTML
  var typeA = checkForTypeA(outerHTML); // Determine if Type-A if (typeA){
  el.addEventListener(text, sourceExtractionScript) }
    else{
      el.addEventListener(text, valueExtractionScript)
      }
    }
  }
);

この攻撃で、ユーザーが認証情報などを入力するのを待ってログインボタンなどをクリックしたときにHTMLをキャプチャしてouterHTMLでHTMLのソースをコピーし正規表現などを使用してパスワードタイプの入力フォームだけを更にキャプチャしてサーバーに送信するといった例です。CSSセレクタ(input['type=password']など)を特定すれば簡単にJavaScriptで.valueなんかで取得できてしまう。。。

計測

実際の計測は論文中の図を見るのが分かりやすいが、Seleniumとクローラーを使ってinput=passwordに限定していくつかのWEBサイトで一意のユーザー名やパスワードを自動入力させてキャプチャするということをしている。

上位10,000ドメインのうち、8,410ウェブサイトのログインページを特定 した。このうち、7,140のウェブサイトでパスワードフィールドを発見した。 (P.30 Exposing and Addressing Security Vulnerabilities in Browser Text Input Fields)

とのことでこれらのサイトすべてからパスワードを抽出できたとという結果だった。

拡張機能側でも脆弱性のあるものがどれだけあるかを計測して12.5% (17.3K) の拡張機能が、すべてのウェブページの機密情報を抽出するのに必要な許可を持っていることが分かったとのことだった。(これも論文に図があるので参照すると良い)

ここから分かることとして、やはり仮説というか現状セキュリティ的に危ないことが分かった。他にも色々書かれているが詳細は省く。

対応策・提案

仮説の通り境界がないことが分かったので機密性の高いinputのソリューションを提案している。それはHTMLInputElementに新しいSecureInputというものだ。詳しいソースコードはosf.ioに公開されていた。

このコードを読んでまず気になるのは、WeakMapを利用して入力された値をマスクされた文字列として保存している点で、これだけでほとんどの機密情報へのアクセスが失敗することになるということだった。攻撃者が仮に他の入力フォームに切り替えをした場合にユーザーに警告を発することで保護することができるということだった。

WeakMapは、弱い参照という理解しかなく、ほとんどお目にかかることがなかったがこういう使い方があるのかと学びになった。

コード上にもあくまでデモとはなっているのでもちろん本番では使えないが、いいアイデアだなとは思った。

最後に

かなり詳細を省いているが、論文自体はもっと詳しく書いているので読んでみると面白い。この論文自体はコードも含めて2時間ぐらいで読んだのでこれぐらいの量であれば、週一とかで読んで見るのはありだなと思った。 ブログを適当に読むのもいいが、こういうのもたまには良いというということでこれからも読みたいと思う。論文探しは意外と大変な気もしているので、その辺はうまく探せる方法を模索していきたい。

今回読んだ論文 https://arxiv.org/abs/2308.16321