Hateburo: kazeburo hatenablog

Operations Engineer / 運用系小姑 / Perl Monger

クラウドサービスにおける ReDoS 対策

正規表現のマッチングにかかる処理時間が指数的に増えることでDoS脆弱性が発生し、それを利用した攻撃を ReDoS 攻撃と呼びます。

詳しくは、

owasp.org

最近書かれた、立命館コンピュータクラブの記事もよくまとまっております。

www.rcc.ritsumei.ac.jp

クラウドサービスにおける ReDoS 対策

f:id:kazeburo:20211224094719p:plain

クラウドのサービスでは、お客様にサーバやミドルウェアの設定として正規表現ワイルドカードを入力していただくことがあります。そうした場合に正規表現がReDoSの対象とならないよう、チェックしなければなりません。

さくらのクラウドのエンハンスドロードバランサではコントロールパネルにてワイルドカードを入力する箇所がいくつかあります。ワイルドカードはL7ロードバランサとして利用しているHAProxyの設定では正規表現に変換されて使用されます。

以前は、マッチングの負荷を抑えるため、ワイルドカード文字 *? を利用する数を数個に制限しておりましたが、現在ではその制限を緩和し、 ReDoS につながる正規表現をチェックする以下のライブラリを使って負荷になる正規表現にならないか確認しています。

github.com

safe-regexのREADMEにも書かれてますが、より正確なチェックをするには別のライブラリがおすすめされています。

github.com

また、立命館コンピュータクラブの記事でも紹介されている recheck もあります。

makenowjust-labo.github.io

今回はワイルドカードからの変換であり、自由に正規表現が指定できないので safe-regex を利用しています。

ワイルドカード文字の個数制限をやめてReDoSチェックの導入する提案はフロントエンドのエンジニアから頂き、開発も一緒にやりました。さくらのクラウドの開発チームはフロントエンド、バックエンド、基盤などの役割を問わず改善のアイディアを出し合って開発を進めています。

正規表現チェックサーバ

さくらのクラウドのコントロールパネルは JavaScript/TypeScript で作られていますので、上記のライブラリはフロントエンドそのまま使えますが、APIや基盤の制御、ミドルウェアの設定の生成をするサーバ側はPHPPerlまたはGoといった言語で書かれているので、そのまま使うことはできません。

そこで、davisjam/safe-regex を呼び出すだけのAPIサーバを Node.js で作り hacobune で動作させ、PHP/Perlから利用するようにしました。小さいAPIを作るのは Mackerel の Plugin をインストールするための release Tag キャッシュサーバ と同じアイディアです。

APIサーバのコードは例によってGitHubにあります。

github.com

使い方

$ docker run -p 3000:300 ghcr.io/kazeburo/safe-regex-api:latest

APIはシンプルに、正規表現をPOSTする形となります。

$ curl -sSf -XPOST --data-urlencode 'regexp=[a-z]+' localhost:3000/is_safe_regexp
{"error":false,"is_safe":true}

expressのmiddlewareの機能により、form-urlencodedまたはJSONでPOSTできます。

curl -sSf -XPOST -H 'Content-type: application/json' -d '{"regexp":"[a-z]+"}' localhost:3000/is_safe_regexp 
{"error":false,"is_safe":true}

安全でない正規表現を送るとis_safefalse となることがわかります

$ curl -sSf -XPOST --data-urlencode 'regexp=(a+)+' localhost:3000/is_safe_regexp
{"error":false,"is_safe":false}

まとめ

  • クラウドサービスでもReDoS チェックやってます
  • Node.jsで極小API書いてhacobuneにデプロイし、サーバ側のチェックを実現しています
  • さくらのクラウドの開発チームでは役割を問わず改善のアイディアを出し合って開発を進めています