DependabotAlert-glob-parent-CVE-2020-28469
2021年7月16日
6/7に報告された「glob-parent」のDependabot Alertのメモ。
この脆弱性はv5.1.2より前のバージョンにて発生し、v5.1.2で改善されたが、v6.0.0で再発しているっぽい?正規表現を使わない方向で議論が進んでいる様子だけどなかなかマージされないので、この記事は先んじて公開してしまいます。
GitHub Advisory Databaseでのカテゴリは「high severity」。記事執筆時点での最新バージョンはv5.1.2だったが、ほっといたらv6.0.0が出てた。
ちなみにsynk.ioだと「MEDIUM SEVERITY」にカテゴライズされている。
GitHub Advisory Database番号は「CVE-2020-28469」
glob-parentとは
glob-parentはgulp.jsチームが開発しているライブラリで、globパターンで指定されたファイルパスから、globが始まる直前までのパス(親)を返すライブラリ。gulp.jsの下に生えているけど、gulpとは関係なく使うことができる。使い方はUsageを見れば分かる。
にしてもWeekly Downloadsの数がハンパない。tailwindcss、lerna、eslintなどのメジャーライブラリから参照されているからだろうか。
脆弱性について
glob-parentに存在していた脆弱性は「Regular Expression Denial of Service (ReDoS)」と呼ばれるもの。
冒頭に書いたsynkのページを見ればだいたい分かるけど、名前にある通り大きな負荷をかけてサービスを停止させるDoSの一つ。
ReDoSの詳細はyamoryさんが公開しているその正規表現の書き方で大丈夫? ReDoS 攻撃の怖さと対策方法が詳しい。
簡単に言うと、多くの正規表現エンジンは文字を先頭から1文字ずつ評価していくが、正規表現にマッチしない文字に出会った時は最初の文字に戻って別の評価方法を試す、という処理を何度も行う。(これをバックトラックというらしい)
たとえば文字列の最後の文字だけが正規表現にマッチしないケースなどは、文字列自体が長くなればなるほど処理に時間がかかる。なるほど…。
ちなみに、正規表現エンジンがどういう評価をしているのかはregex101 デバッガーを使うとわかりやすい。
私は正規表現についてちゃんと理解できていないのと、理解できていないものはできるだけ使わないようにしているので正規表現であまりハマることはないけど「場合によっては遅くなる」というバグはなかなか気が付きにくいので辛い。
glob-parentで定義されていた正規表現は以下のようなもの。
/[\{\[].*[\/]*.*[\}\]]$/;
これは{
か[
で始まり、}
か]
で終わる文字列にヒットする正規表現だが、中間部分に書かれている.*[\/]*.*
は、改行コード以外の文字が0文字以上と「/」が0文字以上にヒットする。
この正規表現は以下のように修正された。
/[\{\[].*[\}\]]$/
中間部がシンプルになったことで、処理は軽くなったものの、根本的な解決には至っていない。根本的に解決するためには、正規表現を取り除く必要がある。