Shibuya.XSS techtalk #11 アウトラインメモ
Shibuya.XSS techtalk #11 - connpassに参加したのでアウトラインメモ
- Twitter #shibuyaxss: Shibuya.XSS techtalk #11 - Togetter
怪しいSSIDが多い #shibuyaxss pic.twitter.com/Gt02yJg4ie
— azu (@azu_re) May 16, 2019
“Post-XSS” - Takashi Yoneuchi
スライド: “Gimme a bit!” - Exploring Attacks in the “Post-XSS” World - Speaker Deck
- XSSがなくなった後の世界
- XS-Leaks、XS-Search(Cross Site Search)について
- ブラウザサイドの防御ライン
- CSP
- XSS Audit
- XSS Filter
- Framework
- dangerouslySetInnerHTMLみたいに危険なものを明示的にしてる
- Script Gadgetsを使ったXSS
- URLを経由のホワイトリストベースなCSPがあってもbypassできる
- googleapiが許可されているならangularを持ってきてXSSをbypassする
- Scriptが使えないならCSSなどを使って攻撃もできる
- Scriptless Attacks
@importで読み込んで1文字見つけて、また別のCSSをレスポンスを返して、また別の@importを実行させる
- Cross-Site Leaks
- ここでの定義: ブラウザに対してサイドチャネル攻撃をするための技術
- window.lengthなどクロスサイトでも読めるリソースを使って、クロスオリジンのコンテンツを推測する攻撃
- Cross-Site Search
- NTTのCharlotteとか、レスポンスにかかる時間から特徴
- #491473 Protected tweets exposure through the URL
- 検索して帰ってきた時間がながかった = そのコンテンツに関係ある結果がでたと推測できる
- XSS Auditor +
window.lengthiframeの数をwindow.lengthで取れる- XSS Auditorが、URLにscriptとか入れたときに、コンテンツ内にあるscriptとexact matchして誤反応する
- これを利用して、特定のURLにマッチする = XSS Auditor が反応する = Scriptタグの中身を推測できる = フラグの値を推測できる
var flag = trueをURLに入れたりvar flag = falseみたいな感じのをURLに入れる- XSS Auditorが反応するとiframeの数が変わるので、コンテンツを推測する
window.lengthはクロスサイトでも取れるので、クロスオリジンのコンテンツ推測ができる(Scriptの中身)
- Timing Attach(Web)
- 掛かった時間を元にした攻撃
- 分類
- 攻撃者が直接アクセスできる = Direct Timing Attack
- DBにどれぐらいのデータがあるかを推測する、解析する
- XSSのように特定のユーザーからリクエストをなげる = Cross Timing Attack
- Client-Site Timing
- XS-Leaksの一種
- レンダリングにかかる時間からコンテンツの中身を推測する
- XS-Leaksの影響はけっこう現実にでてきている
- 攻撃者が直接アクセスできる = Direct Timing Attack
- Cross-Origin Resource Policy
- imgタグでJSONを読もうとする = サイドチャネル攻撃っぽい ⇒ こういうのは弾けるようにしたい ⇒ Cross-Origin Resource Policy
- XS Leaks/Searchな問題に対処するために新しい仕様もでてきている
- 軽減策もでてきたのでBug Bountyでも支払うようになってきた
- SECCON Beginners
JSでDoSる - @kinugawamasato
-
脆弱性診断で、JavaScriptでNode.jsでアプリが落ちてしまうことが増えてきた
-
文字列処理: デコード/エンコード
- YoutubeのURLを投稿する自動的いページ内へ動画を埋め込む機能
v=%FFを渡すとエラーが起きてページが真っ白になったdecodeURIComponentするときに%FFは不正なので例外が発生してしまう- 対策: ユーザー入力をデコードする場合は
try...catchする encodeURIComponentも同様になる- ECMAScriptの仕様にもでてくる
-
文字列を埋め込むとエラーになる
- U+2028、U+2029も改行
- ES2019で修正される
- tc39/proposal-json-superset: Proposal to make all JSON text valid ECMA-262
- スクリプトブロックの制限
<script> var input = "<!--<script>"はダメという歴史的な仕様
- ドキュメントモード
<% %> - 対策: 文字列リテラルの中にユーザー入力をそのまま埋め込んではいけない
-
型の問題
- JSONは文字列以外の値も入る
- ユーザー入力で文字列じゃなくて数値を渡すようにするとエラーがおきた
{toString:null}を渡すとエラー
-
プロパティアクセス
- チャットアプリで特定のHTMLタグが利用できる
- ファイルアップロードで
.constructorという拡張子のアップロードすると使えなくなった - マップとしてのObjectとMap
-
ホワイトリストをオブジェクトで持っていた
- このときに タグで
toStringなどを渡すと問題がおきる <toString>タグを渡すとダメになる
whiteListTag = { “span”: “funcForSanitize” }
whiteListTag指定したタグ // こうしていた
- このときに タグで
-
Node.js固有の話
-
サーバサイドがNode.jsで作られたアプリ
-
次のようなJSONをAPIに送信すると、アプリが停止した
{“query”: { “length”: 1e10, “constructor”: {“name”:“value”}}}
-
[constructor.name](http://constructor.name)が “Array` なら配列と判断し、別の配列にコピーしていた -
lengthが1e10をみてforループを回していた -
メモリが必要になり落ちる
-
⇒ Out Of Memory
-
try-catchとかでキャッチできないので注意が必要になる
-
無限ループはNode.jsでは危険になる
-
「Site Isolationの話」 - @shhnjk
- Chromeのプロセスモデル
- ブラウザプロセス
- レンダラプロセス
- Site Isolationの背景
- PCの中身だけじゃなくてオンライン上のデータが重要
- Site Isolationができる前は、レンダリングプロセスのバグがあったらUXSSになる可能性がたかかった ⇒ レンダラが別れないとiframeで読んだものが読めてしまう可能性 ⇒ 分ける必要 ⇒ Site Isolation
- サイトごとにレンダラプロセスを隔離するChromeのセキュリティ機能
- Cross-Origin Read Blocking
- imageのパースは複雑なので、バグが起きやすいしプロセスが一緒くただと問題の範囲が広い
- Content-Typeを持つリソースがクロスオリジンなプロセスにロードできないようにするセキュリティ機能
- ロードしないので、プロセスの中にも入らなくて安全 = サイドチャネル攻撃しても取れない
- Spectre
- サイドチャネル攻撃を使うことで別プロセスのデータを読めるCPUの脆弱性
- これはアプリレベルでは防げないのでCPUレベル
- 同一プロセスにあるものは脆弱性がなくても読めてしまう
- ChromeによるSpectreの緩和策
- サイドチャネル対策にTimingの制度軽減
- 攻撃ベクターは増えるので効率的な緩和策ではない
- Spectre対策としてSite Isolation
- レンダラプロセスの保護
- クロスサイトを突き詰める
- スキーム + ドメイン
- URLのHOSTがドメインじゃない場合は、SchemeとHostが完全一致した場合に同一サイトとして判断される
- Blob URLはHostはnullになる
blob://null/xxxxxとなって同じサイト扱いになる = プロセス分離されないのでSpectreで取れる- Data URL
- ナビゲーションを開始したサイトを引き継ぐ
<iframe src="data:application/signed-exchange">を読むとクラッシュする- クラッシュ後に起動すると、ディスクキャッシュからData URLが同一サイトとしてみなされる
- 修正: Data URLのフラグメント自体をサイトとみなすようになった
data:text/html;...#中身##以降もボディとしてみなしていた =#前までが同じなら同一サイト ⇒ 問題
- CORBをバイパス
- CORSの確認自体はレンダラプロセスでおこならないでネットワークのプロセスなどでやる
- レンダラプロセスを信用しないSite Isolationにしていく方向
- Out-of-Renderer CORS
- Blob URLを使ったUXSS
- Blobのorigin偽装のバグ
- ナビゲーションコミット時のオリジン偽装
- Chrome University 2018: Life of a Navigation - YouTube
- オリジンは偽装できているけど、レンダラプロセスは変わらない
- APIによってレンダラプロセスで確認すると偽装はバレルけど、そこを通らないAPIは偽装がバレなかった
- Cache APIを使うといけた
- 気をつけてほしいこと(開発者)
- 信頼できないData URLをiframeで表示することはXSSではないが危険
- オリジンを引き継ぐので、同一プロセスになって、Spectreに弱い
- HTML、XML、JSON以外の機密ファイルでクロスサイトに読み込まれる必要がないものにはCORPヘッダを設定する
- 信頼できないData URLをiframeで表示することはXSSではないが危険
- 気をつけてほしいこと(ユーザー)
- 信頼できないファイルはローカルで開かない
- Site Isolationで変わったこと
- レンダラプロセスを掌握してもUXSSには直接は繋がらなくなった
- ブラウザプロセスでやることが増えたので攻撃できる面は増えた
- ブラウザのバグがサイトの設定で防げるようになってきた
- CORPなどはレンダラプロセスには読み込まないので、ブラウザにバグがあっても盗まれにくくなった
- SOPバイパスがSite Isolation関連で守られていないところに集中してきた
- Siteという概念が強くなった
「ブラウザセキュリティ機能はバイパスされる為にある」 - @shhnjk
- ブラウザセキュリティ機能はバイパスされる
*-policyは共通でバイパスできる方法がある- CSPのバイパス
- CSPが設定されていても、
javascript:スキームを使うとCSPがjavascript:がCSPを継承してなかったので実行できた - Safari
- CSPが設定されていても、
- CSPのバイパス
window.openでウィンドウ
- Referrer Policyのバイパス
about:blankページを開いたときにChromeではReferrer Policyが継承されてなかった
- CSP/iframe サンドボックス
- Service Workerが登録されたオリジン内のリクエストはService Workerを経由する
- CSP sandboxのページからのリクエストもService Workerを経由してしまうという脆弱性があった
- SameSiteクッキー
- “同一サイト” だけど= ドメインのみ(http_httpsの区別しない)
- Secure属性を着ける
- Laxはトップレベルナビゲーションのときだけ送れる
- SameSite Strictのバイパス
rel=noopenerの場合もSameSiteCookieの動きがバグっていた
- “同一サイト” だけど= ドメインのみ(http_httpsの区別しない)
- Dangling markup mitigation
\nand<- Prevent requests to HTTP(S) URLs containing raw
\\nand<. · Issue #546 · whatwg/fetch - Data URLをパースする際にスペースや改行が消えるので、imgのリクエストには改行がなくてDangling markup mitigationをバイパスできた
<a download>の無効化- クロスオリジンframebusting
- ユーザー操作なしでトップオリジンへのlocationを変えるのを防止する機能
- 伝えたかった
- 脆弱性を探す対象がセキュアだと思いこんではイケナイ
- Chromeがセキュアだと思い込んではいけない
- Import Mapsのバイパス
- fallbackの仕組みであるセキュリティ機能がバイパスできる
- CSPのNonceとかを無視してしまうのでいろいろバイパスできそう
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。