Skip to main content

Sequelize ORM npmライブラリにSQLインジェクション攻撃の脆弱性が見つかる

著者

2019年9月11日

0 分で読めます

オブジェクト関係マッパー(ORM)は、一般にORMとも呼ばれ、データベースコードを言語構造に抽象化することで、開発者による管理を支援するSQLライブラリ群です。

SQL ORMライブラリはSQLインジェクションの防止に効果的ですが、残念ながら、アプリケーションレベルのSQLインジェクション攻撃につながるセキュリティバグがライブラリ自体に存在する可能性もあります。

SQLインジェクション攻撃に注意すべき理由

ORMを使う大きなメリットの一つは、SQLインジェクションの脆弱性を防ぐために入力をエスケープする手法である、プリペアドステートメントを利用できることです。しかし、OWASP Top 10でインジェクション攻撃は主要なリスクとして挙げられており、Akamaiのインターネットの現状に関するレポートでは、SQLインジェクションの脆弱性が現在、すべてのWebアプリケーション攻撃のほぼ3分の2(65.1%)を占めることが明らかになっています。

以前、SQLインジェクションとORMについて詳しく解説しました。この記事では、Snykチームが人気のnpmライブラリsequelizeで発見した、最近のSQLインジェクションの事例に焦点を当てます。

Snyk、npmのSequelize ORMライブラリにSQLインジェクションを発見

2019年6月、Snykは、Node.jsアプリケーションで広く使われているnpmライブラリSequelizeを利用するアプリケーションで、SQLインジェクション攻撃につながる可能性のある攻撃経路を発見しました。Sequelizeに影響するSQLインジェクションの脆弱性は3件で、CVEとしてCVE-2019-10752、CVE-2019-10749、CVE-2019-10748が割り当てられています。

問題を確認した直後、sequelizeのメンテナーであるJan Aagaard Meier氏とSushant Dhiman氏に連絡し、責任ある形で調査結果を開示するとともに、脆弱性とその原因となる脆弱なコードパスを示すSQLインジェクションの事例を共有しました。

Sequelizeがセキュリティとユーザー保護に迅速に取り組んでいることを示すように、メンテナーはすぐに対応し、ライブラリの3.x系と5.x系で修正をリリースしました。脆弱性を修正し、SQLインジェクションを防ぐためのアップグレードパスをユーザーに提供しています。

MySQL/MariaDBのJSONパスキーにおけるSQLインジェクションのセキュリティ修正を示す、Sequelize v5.8.11のGitHubリリースページ

Sequelizeプロジェクトは、PostgreSQLに影響する脆弱性を修正したバージョン3.35.1と、MySQLおよびMariaDBの方言における脆弱性を修正したバージョン5.8.11をリリースしました。安全なバージョンを利用するため、できるだけ早くアップグレードすることを強くおすすめします。sequelizeの安全なバージョンをご利用ください。

上記3件のうち最も最近のSQLインジェクション脆弱性は、Sequelizeバージョン5.15.1で修正されました。以下に、公式リリースノートに記載された事例を紹介します。

Sequelize v5.15.1のリリースノートのスクリーンショット。SQLインジェクション脆弱性の修正について説明し、攻撃例を示しています。

MySQLおよびMariaDBにおけるSQLインジェクションの事例

バージョン5.8.11未満のsequelizeはすべて、MySQLおよびMariaDBの方言でJSONパスキーが適切にエスケープされないため、SQLインジェクションに対して脆弱です(CVE-2019-10748)。

sequelizeにおける次のSQLインジェクションの例をご覧ください。

class Project extends Sequelize.Model {}

Project.init({
  name: Sequelize.STRING,
  meta: Sequelize.JSON,
}, {
  sequelize,
  tableName: 'projects',
});

(async () => {
  await sequelize.sync();

  console.log(await Project.findAll({
    where: {meta: {"a')) AS DECIMAL) = 1 UNION SELECT VERSION(); -- ": 1}},
    attributes: ['name'],
    raw: true,
  }));
})();

metaデータベースフィールドはJSONオブジェクトを想定していますが、指定されたキーはシングルクォートをエスケープするための適切なサニタイズが行われていません。クエリが想定する)) AS DECIMAL)というテキストとともにシングルクォートが渡されると、このコードを悪用できます。

このSQLインジェクションの例では、UNIONなどのSQLクエリを追加で実行したり、セミコロンでクエリを完全に終了させて、; DROP TABLE USERSのような後続処理を追加したりできることを示しています。

PostgreSQLの方言では、sequelizeのバージョン3.35.1未満すべてに、同様のSQLインジェクション脆弱性があります。

自分も影響を受けますか?どうすればよいですか?

Snykでプロジェクトを監視していて、脆弱なバージョンのsequelizeが見つかった場合は、Snykから定期的に通知が届きます。また、GitHubリポジトリを接続している場合は、修正済みバージョンのsequelizeにアップグレードするプルリクエストが自動的に作成されます。

Snykのセキュリティリサーチチームは、さまざまな言語エコシステムのセキュリティ脆弱性を発見するため、継続的に調査を行っています。最近の事例には、npmライブラリlodashのセキュリティ脆弱性や、幅広い言語エコシステムにまたがり、数千ものアプリケーションに影響するZip Slip脆弱性につながった大規模な調査があります。

Snykでプロジェクトを監視していない場合、このパッケージが使われているかどうかは以下から確認できます。または、CLIを使ってプロジェクトをローカルでテストすることもできます。

安全なコーディング規約を実践し、OWASPが推奨するSQLインジェクション対策チートシートなどのベストプラクティスに従うこともおすすめします。

Sequelizeの脆弱性を発見しましたか?Snykはセキュリティコミュニティを大切にしており、オープンソースパッケージの脆弱性を責任ある形で開示することが、ユーザーのセキュリティとプライバシーの保護につながると考えています。Sequelizeの脆弱性を発見した場合は、Snyk Open Source Package Vulnerability Disclosureプログラムに報告してください。あとは私たちにお任せください。https://snyk.io/vulnerability-disclosure/

CTFを始めよう

オンデマンドのバーチャル入門ワークショップで、CTFチャレンジの解き方を学びましょう。