Skip to main content

In this article

qsにおけるPrototype Override Protection Bypass脆弱性の修正

著者
Headshot of Tim Kadlec

Tim Kadlec

2017年3月14日

0 分で読めます

先月、深刻度の高いPrototype Override Protection Bypass脆弱性がqsパッケージに存在することをデータベースに登録しました。ライブラリの更新版に含まれる修正は、約1週間前にリリースされました。この記事では、脆弱性の内容とその緩和方法を解説します。

qsは人気の高いnpmパッケージで、過去1か月のダウンロード数は4,000万件弱に上ります。クエリ文字列のパラメーターをオブジェクトに解析するために使われます。たとえば、次のように記述します。

qs.parse('a=b&c=d');
// {a:'b', c: 'd'}

もちろん便利ですが、qsの真価は高度な機能を利用できる点にあります。qsを使うと、角括弧([または])を使ってクエリ文字列内にネストされたオブジェクトを作成することもできます。

qs.parse('a[b]=c');
// {
//   a: {
//     b: "c"
//   }
// }

クエリ文字列のパラメーター内にネストされたオブジェクトを作成できる機能には、リスクも伴います。適切に検証しないと、オブジェクトのプロトタイプにあるプロパティを上書きされる可能性があります。たとえば、オブジェクトのhasOwnPropertyメソッドを上書きしようとすることができます。

qs.parse('a[hasOwnProperty]=b');

幸い、上記の方法は機能しません。デフォルトでは、qsはオブジェクトプロトタイプのプロパティを上書きするパラメーター(hasOwnPropertyなど)を無視します。パラメーター内に開き括弧と閉じ括弧があるかを確認し、その間の文字列を取り出して、オブジェクトプロトタイプと照合し、ネイティブプロパティかどうかを判定しています。プロトタイプの上書きを許可するオプションもありますが、qsでは強く非推奨とされています。

残念ながら、検証に不備があったため、対応する[または]がない文字をパラメーターの先頭に付けることで、オブジェクトプロトタイプのプロパティを上書きできてしまいました。

たとえば、次のようにすると、qsでプロトタイプの上書きを明示的に禁止していても、オブジェクトのhasOwnPropertyメソッドが上書きされます。

var paramData = qs.parse("]=hasOwnProperty", { allowPrototypes: false });
// {hasOwnProperty = true}

paramData.hasOwnProperty('toString');
// Results in Type Error: paramData.hasOwnProperty is not a function

最も起こりやすいのは、アプリケーションの不具合や予期しない脆弱化です。しかし、アプリケーションのロジックによっては、さらに深刻な影響が生じる可能性があり、場合によっては攻撃者がアプリケーションの実行フローを変更できることもあります。

修正方法

当社のセキュリティリサーチチームは2月13日にこの問題を発見し、パッケージのメンテナーに報告しました。メンテナーは迅速に対応し、3日後に6.0.3、6.1.1、6.2.2、6.3.1をリリースしました。

この修正により、パラメーターが]=で始まる場合の問題は解決しました。しかし、これだけでは不十分でした。攻撃者が[=を使うと、qsは依然として脆弱だったのです。そのため、メンテナーはロジックを更新し、より堅牢な修正版として6.4.0、6.3.2、6.2.3、6.1.2、6.0.4をリリースしました。

この問題に対処するには、パッケージをこれらのいずれかのバージョンに更新する必要があります。Snykでプロジェクトを監視している場合は、自動生成されたプルリクエストを使うか、CLIでsnyk wizardを実行するよう、すでに案内されているかもしれません。

それ以外の場合は、アプリケーションでqsパッケージを使用しているか確認する必要があります。package.jsonファイルに記載された直接依存関係として使用している場合も、直接依存関係のいずれかが取り込む未記載の依存関係として使用している場合も、最新版に更新してください。

カテゴリー: