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

^ReDoSの色々$

LHazy
July 15, 2020

 ^ReDoSの色々$

LHazy

July 15, 2020
Tweet

More Decks by LHazy

Other Decks in Technology

Transcript

  1. 連接・選択・繰り返し • 連接 ◦ 単純に隣り合う文字を表す。ただの文字列も正規表現。 ◦ 例:abcd、hogefuga、regex • 選択 ◦

    並べた正規表現のどれかを選ぶ。 ◦ 例:Java(S|s)script ← JavaScript、または、Javascriptを表す。 • 繰り返し ◦ ある正規表現を繰り返し適用する。 ◦ 例:(0|1)* ← 0か1が繰り返し出現する文字列にマッチする。つまり、バイナリ。
  2. 文字クラス・特殊文字・キャプチャ • 文字クラス ◦ アルファベット、数字などのまとまった文字達を表す。 ◦ 例:[a-zA-Z]、[0-9]、[02468] • メタ文字 ◦

    数字や非単語構成文字(記号)や行頭、行末などを表す特別な記号 ◦ 例:^\s++$ ← 空白のみで構成される行 • キャプチャ ◦ 正規表現のグループ化、演算の優先度の変更、部分的な取り出しに利用できる ◦ 例:YYYY/MM/DDをYYYY-MM-DDに変換する正規表現と JavaScriptコード。                 > '2020/07/15'.replace(/(\d\d\d\d)\/(\d\d)\/(\d\d)/, '$1-$2-$3'); '2020-07-15' >
  3. 繰り返しについてもう少し • スター演算子 ◦ 0回以上の繰り返しを表す ◦ 例:\d* ← 空文字か任意個の数字列にマッチ • プラス演算子 ◦

    1回以上の繰り返しを表す ◦ 例:\d+ ← 一つの数字か任意個の数字列にマッチ • 疑問符演算子 ◦ 0回か1回の繰り返しを表す ◦ 例:\d? ← 空文字か1個の数字にマッチ • 範囲量指定子 ◦ n~m回の繰り返しを表す。( n < m) ◦ 例:\d{2,10} ← 2個以上、10個以下の数字の繰り返しにマッチ
  4. (欲張りな|控え目)な量指定子 • 欲張りな量指定子 ◦ 可能な限り長くマッチしようとする。「 *」、「+」、「?」、「{n,m}」が欲張る。 ◦ 例:(\d*)(\d*) ← 左のグループが全ての数字を消費する。 • 控え目な量指定子

    ◦ 可能な限り短くマッチしようとする。「 *?」、「+?」、「??」、「{n,m}?」が控え目。 ◦ 例:(\d*?)(\d+) ← 左のグループは控え目なため、右のグループが欲張る。
  5. 答え 1. 最初の「x+」が10個の(全て)の「x」にマッチする。 2. 2番目の「x+」が失敗する。 3. 最初の「x+」が「x」を一つ手放して、9個の「x」にマッチする。 4. 2番目の「x」が1個の「x」にマッチする。 5.

    グループに繰り返し「+」がついているが、これ以上マッチする部分が ない為、1回のマッチで終了する。 6. 「y」が「y」とマッチする。
  6. マッチ対象に「y」がなかったら? 1. 最初の「x+」が2つ「x」を手放して8つの「x」にマッチ。 2. 2番目の「x+」が2個の「x」にマッチ。 3. グループの繰り返しに失敗。 4. yのマッチに失敗。 5.

    2番目の「x+」が「x」を手放して1つの「x」にマッチ。 6. グループの繰り返しに失敗。 7. yのマッチに失敗。 8. 最初の「x+」が3つの「x」を手放して8つの「x」にマッチ。 9. 2番目の「x」が3つの「x」にマッチ。 10. 以下、繰り返し。 文章で説明するとめんどい。。。
  7. Stack Overflowの例 • 2016年7月20日にReDoSで34分の停止が発生。 • 「-- play happy sound for

    player to enjoy」の後に2万個のスペースが続く 投稿が原因でDoSった。 • 原因の特定に10分、コードの修正に14分、修正の適用に10分かかった らしい。。。対応、早くない?! • 行頭と行末のスペースを除去するために「^[\s\u200c]+|[\s\u200c]+$」 という正規表現を使用していた。 • https://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016
  8. Expressの例 • 2016年にExpress が依存する nagotiator という Accept-Language ヘッダー を扱うライブラリでReDoSが見つかった。 •

    修正コミット ◦ https://medium.com/node-security/regular-expression-denial-of-service-affecting-express-js-9c397c164c43 • 以下のようなコードを書いてるとDoSる。 app.get('/', (req, res) => { if (req.acceptsLanguages ('ja')) { res.send('ピエン'); } else { res.send });
  9. w3af • 右のようなReDoSを引き起こしそうな文字列を送信して RTTが通常より4倍遅くなればReDoSと判定。 • 「a」や「1」は10個ずつ増やしていき、最終的に80個 まで試す。 • ソースコードは以下。 ◦

    https://github.com/andresriancho/w3af/blob/master/w3af/plugins/audit/redos.py aaaaaaaaaaX! aaaaaaaaaaaaaaaaaaaaX! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX! [email protected]! [email protected]! [email protected]! 11111111119! 111111111111111111119! 1111111111111111111111111111119!
  10. safe-regex • regexp-tree というライブラリを使って正規表現をASTに変換して、 ASTを再帰的に走査して、一番ネストした * 演算子を探す。 • ネストの深さが「1」以上、または、* 演算子が25個より多く

    使用されている場合は危険と判定。 • 「星の高さ」という概念を基にしている。 • 例えば、(b|aa*b)*aa* の星の高さは 2 。 • 入れ子になった * 演算子は組み合わせ爆発を誘発しやすい。 • リポジトリ ◦ https://github.com/davisjam/safe-regex/
  11. google/re2 • Googleが開発した正規表現エンジン。 • ユーザーからの信頼できない入力に対してリスクなく正規表現を扱えるよう 設計・実装されている。 • 入力された文字列に対して線形時間でマッチングを行えることを 保証している。 •

    その代わりに、他の正規表現エンジンと比べて機能が制限されている。 ◦ https://github.com/google/re2/wiki/WhyRE2 • 先述のCloudflareの事例で、事後対応としてRE2の採用が上がっている。
  12. まとめ • ReDoSは正規表現のマッチングの計算量の増大により引き起こされる。 • ReDoSはビジネスロジック、ライブラリ、ミドルボックス等至る所に 潜んでいる。 • WAFでの防御ができない。むしろ、WAFが攻撃対象になる。 • 現時点では脆弱性診断が難しい。

    • 予防のために、パフォーマンスに関する作法を学ぼう。 • ツールを使用して疑わしい正規表現をチェックする。 • 正規表現エンジンや言語の設定で計算リソースを制限する。
  13. 参考文献 • 正規表現技術入門 ー最新エンジン実装と理論的背景ー ◦ https://gihyo.jp/book/2015/978-4-7741-7270-5 • 詳説 正規表現 ◦ https://gihyo.jp/book/2015/978-4-7741-7270-5 •

    正規表現入門 星の高さを求めて ◦ https://www.slideshare.net/sinya8282/ss-32629428 • Runaway Regular Expressions: Catastrophic Backtracking ◦ https://www.regular-expressions.info/catastrophic.html • The Impact of Regular Expression Denial of Service (ReDoS) in Practice ◦ https://medium.com/bugbountywriteup/introduction-987fdc4c7b0 • The Regular Expression Denial of Service (ReDoS) cheat-sheet ◦ https://levelup.gitconnected.com/the-regular-expression-denial-of-service-redos-cheat-sheet-a78d0ed7d865 • A Sense of Time for JavaScript and Node.js ◦ https://medium.com/@davisjam/a-sense-of-time-for-javascript-and-node-js-68c9114f5d48 • 正規表現とセキュリティ / Regular Expressions and Their Security-Related Aspects ◦ https://speakerdeck.com/lmt_swallow/regular-expressions-and-their-security-related-aspects