Upgrade to Pro — share decks privately, control downloads, hide ads and more …

脆弱性から学ぶシリーズ CVE-2024-34341 - Kashiwa.rb #5 LT

Koji NAKAMURA
November 14, 2024

脆弱性から学ぶシリーズ CVE-2024-34341 - Kashiwa.rb #5 LT

Koji NAKAMURA

November 14, 2024
Tweet

More Decks by Koji NAKAMURA

Other Decks in Technology

Transcript

  1. • 以下 JavaScript でコピーされる内容を Trix Editor にペーストする • HTML 部分だけを整形すると以下の通り

    脆弱性の内容 - noscript を利用した攻撃ベクトル document.addEventListener('copy', function(e){ e.clipboardData.setData('text/html', '<div><noscript><div class="123</noscript>456<img src=1 onerror=alert(1)//"></div></noscript></div>'); e.preventDefault(); }); <div> <noscript> <div class="123</noscript>456<img src=1 onerror=alert(1)//"></div> </noscript> </div>
  2. • 期待される DOM ツリー の構造はこう • ペーストした結果の構造はこうなっていた XSS が発生する機序 <div>

    <noscript> <div class="123</noscript>456<img src=1 onerror=alert(1)//"></div> </noscript> </div> <div> &lt;div class="123456 <img src=1 onerror=alert(1)//"> </div>
  3. • Sanitize noscript to prevent copy and paste XSS #1147

    ◦ https://github.com/basecamp/trix/pull/1147 • DEFAULT_FORBIDDEN_ELEMENTS に noscript を追加している ◦ noscript を許可しないという対応 この脆弱性に対する修正内容
  4. • まず内部処理 ◦ 表示ドキュメントの DOM ツリー追加前にサニタイズ処理がある ◦ HTMLSanitizer クラス ▪

    https://github.com/basecamp/trix/blob/v2.1.0/src/trix/models/html_sanitizer.js ◦ 入力された HTML 文字列から、表示ドキュメントとは別に DOM ツリーを作成 し、その DOM ツリーから許可されない要素や属性を除去する ◦ 処理済みの DOM ツリーが表示ドキュメントに追加される なぜ noscript タグが作用するのか?(1)
  5. • 表示ドキュメントとは別に DOM ツリーを作成する実装(抜粋) • まず HTML 文字列をブラウザの HTML パーサーに処理させている

    ◦ 文字列から onxxx 属性を正規表現で除去、とかはカオスなのでこれは正しい • createHTMLDocument("") したものに追加 ◦ 表示ドキュメントの DOM ツリーに追加すると script タグがその時点で評価・実行さ れるので、これも正しい ◦ が、ここに落とし穴がある なぜ noscript タグが作用するのか?(2) const doc = document.implementation.createHTMLDocument("") doc.documentElement.innerHTML = html
  6. • ここからは HTML の Spec を読むと機序が理解できる ◦ https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody • `<noscript>`

    が出現すると scripting flag による分岐がある ◦ > A start tag whose tag name is "noscript", if the scripting flag is enabled Follow the generic raw text element parsing algorithm. ◦ scripting flag が enabled の場合は raw text の扱いになる (!) ▪ なので `</noscript>` の並びまでが noscript タグの content になる ▪ script タグの中で `</script>` が出てきたら問答無用で script タグが終 了するアレです なぜ noscript タグが作用するのか?(3)
  7. • なのでこう解釈されてほしかった HTML は、 • scripting flag によってこう解釈されうる可能性もある なぜ noscript

    タグが作用するのか?(4) <div> <noscript> <div class="123</noscript>456<img src=1 onerror=alert(1)//"></div> </noscript> </div> <div> <noscript>&lt;div class="123</noscript> 456 <img src=1 onerror=alert(1)//"> </div> </noscript></div>
  8. • scripting flag とは? ◦ browsing context が non-null であれば

    scripting flag が enabled になる ◦ browsing context がある状態とは JavaScript のグローバルオブジェクトであ る window がある状態 = スクリプトが実行できる状態 ▪ (ここの説明がやや微妙だが、一旦そういうことで ...) • spec にコレっていう言及がある ◦ > A Document created using an API such as createDocument() never has a non-null browsing context. ◦ Trix Editor のサニタイズ処理では scripting flag は disabled で処理されてい たと言える なぜ noscript タグが作用するのか?(5)
  9. • Trix Editor の内部処理ではこう解釈される、 img 要素は認識できない • 表示ドキュメントの DOM ツリー追加時には

    img 要素が認識される なぜ noscript タグが作用するのか?(6) <div> <noscript> <div class="123</noscript>456<img src=1 onerror=alert(1)//"></div> </noscript> </div> <div> <noscript>&lt;div class="123</noscript> 456 <img src=1 onerror=alert(1)//"> </div> </noscript></div>
  10. • Trix Editor では scripting flag が enabled/disabled という差異があることでサニ タイズ処理がバイパスされる振る舞いに繋がっていた

    • 実際に処理される方法とは全く別のやり方で事前の処理、例えばバリデーション処 理をしたりってよくありませんか? • 例えば何かのパーサーに渡す入力文字列を正規表現でチェックとか 事前の処理と本来の処理に差異がある問題
  11. • CVE-2024-45048: XXE in PHPSpreadsheet encoding is returned ◦ https://github.com/advisories/GHSA-ghg6-32f9-2jp7

    ◦ PHPSpreadsheetライブラリにおいて細工した xlsx ファイルを処理させることで XXE(XML外 部実体攻撃)が可能という脆弱性 ◦ 事前の処理で XML の文字コード判定を /encoding="(.*?)"/ という正規表現で文字列抽出し て行っていた ◦ XML の仕様としてはシングルクォーテーションによるクォーテーションも認められている ◦ 文字コード判定をミスることで結果として XXE のサニタイズがバイパスされる ◦ 「正規表現による処理」と「 XML パーサーによる処理」の差異 実際にあった似たような「問題」(1)
  12. • CVE-2024-8372: AngularJS srcsetへの不適切なサニタイズによるコンテンツ・スプーフィ ング脆弱性 ◦ https://www.herodevs.com/vulnerability-directory/cve-2024-8372 ◦ <img ng-srcset="https://angularjs.org/favicon.ico

    xyz,https://angular.dev/favicon.ico" /> ◦ xyz の部分は本来は幅記述子もしくはピクセル密度記述子が入る ▪ e.g.) 640w, 960w, 1024w, 1x, 2x, 3x ◦ 正規表現による事前処理が幅記述子とピクセル密度記述子しか期待できていなかっ たためサニタイズ処理がバイパスされた ◦ ブラウザの HTML パーサー的には xyz と入っていても画像の表示処理はする ◦ 「正規表現による処理」と「HTML パーサーによる処理」の差異 実際にあった似たような「問題」(2)
  13. • 事前の処理と本来の処理に差異がある状況に遭遇したら気をつけよう ◦ 特に正規表現を使って何かの事前処理をするのは人類やりがち ◦ Trix Editor のように両方 HTML パーサーで処理させればOK!ということもな

    く scripting flag という普通は気づかない要素があることもある ◦ 仕様や本来の処理と本当に差異がないかは注意深く! • 脆弱性から学ぶと LT ネタが無限に生成される ◦ 関連する事象を調べ上げることで「へ〜なるほど!」って思えることに割と出く わすのでオススメ 得られる教訓
  14. EOF