脆弱性・CVE速報深刻度: 高

joi と @hapi/content に正規表現の二次時間 DoS(CVE-2026-118772・119202): 空白や長いトークン 1 つで Node.js が数秒〜数分止まる。joi 18.3.1/17.13.9、@hapi/content 6.0.3 で修正

目次(5)

CVE-2026-118772

CVE-2026-119202

Node.js のバリデーションライブラリ joi と、hapi の HTTP ヘッダー解析部品 @hapi/content に、処理時間が入力長の 2 乗で増える脆弱性が 2026 年 10 月 30 日(UTC)に公開されました。どちらも GitHub Advisory で High(CVSS 7.5、認証不要・可用性のみ)です。CISA の KEV には載っていません。EPSS は CVE-2026-118772 が 0.47%、CVE-2026-119202 が 0.41% です(10/30 時点)。

2 件の内容

CVE対象内容修正版
CVE-2026-118772joi 17.1.1〜17.13.8、18.0.0〜18.3.0(@hapi/joi 16.0.0 以降も影響)Joi.string().email({ multiple: true }) が、区切り文字のない長い空白の並びを分割するときに時間が 2 乗で増える17.13.9、18.3.1(どちらも 10/28 公開)
CVE-2026-119202@hapi/content 6.0.2 以下(旧名 content 3.0.6〜4.0.6)Content.disposition() が、Content-Disposition の中の = を含まない長いトークンの解析に 2 乗の時間を使う6.0.3(10/21 公開)

CVE-2026-118772: joi の email(multiple)

  • multiple を有効にすると、値を正規表現で分割します。空白の並びの途中の各位置で、先頭の \s* が並びの最後まで読み進めて区切りを見つけられず、戻ってやり直すため、空白が n 個なら n² 回の処理になります。
  • 勧告の計測(joi 18.3.0、Node.js 26)では、空白 25,000 個で 244 ms、100,000 個で 3,349 ms、200,000 個で 13,579 ms です。修正版ではいずれも 1 ms 以下です。
  • Node.js は 1 つのスレッドで処理するため、その間は他のリクエストも処理できません。公開の経路で、長さの上限なしにこのスキーマで検証している場合は、認証なしで起こせます。
  • 回避策(更新できない場合): .email() の前に .max() を付ける(例 Joi.string().max(1000).email({ multiple: true }))。ただし abortEarly: false を使うと max が失敗しても email が動くため、この組み合わせは避けます。.trim() は前後の空白しか除かないので回避策になりません。

CVE-2026-119202: @hapi/content の Content-Disposition

  • 解析に使う正規表現は、パラメーター名の部分に先頭の固定がなく、= が続かない長い文字の並びで失敗します。そのたびに次の文字からやり直すので、時間が長さの 2 乗になります。
  • hapi では、@hapi/pez が multipart/form-data の各パートのヘッダーに対してこの関数を呼びます。そのため、payload.multipart を有効にしている経路では、ハンドラーや検証より前に起こります。長さの上限は payload.maxBytes(既定 1 MB)だけです。
  • 勧告の計測(@hapi/content 6.0.2)では、32,000 バイトのトークンで 0.424 秒、64,000 バイトで 1.670 秒、128,000 バイトで 7.173 秒です。報告者は、既定の上限に近い 1,024,000 バイトで 542 秒を測っています。6.0.3 では 1,024,000 バイトでも 0.013 秒です。
  • 回避策: 取り除くものはありません。更新が必要です。更新までの間は、マルチパートを受ける経路の payload.maxBytes を小さくすると 1 リクエストあたりの遅延は減ります。ただし 64 KB のトークンでも 1 秒以上止まります。

対応

  • joi を 18.3.1 以降(17 系なら 17.13.9 以降)に、@hapi/content を 6.0.3 以降に更新してください。hapi 本体を使っている場合は、依存の @hapi/content が 6.0.3 以降になっているか npm ls @hapi/content で確かめます。
  • @hapi/joi(16.0.0〜17.1.1)は修正版が出ていません。勧告の対象になっているため、joi への移行か、上の回避策を検討してください。
  • content(旧名、3.0.6〜4.0.6)にも修正版はありません。

確認できていない点

  • 勧告に、実際の攻撃が確認された記載はありません。KEV にも載っていません。
  • 上の時間は勧告が示した計測値です。実行環境の CPU や Node.js の版で変わります。
  • NVD の評価は、この記事の時点で未確認です。数値は GitHub Advisory の値です。

この記事について

出典

この記事を共有