FlawOpen

flawopen.com/JavaScript の SQL Injection/Sequelize

Sequelize query() は SQL Injection に安全?

リファレンスガイド
要点

クエリパラメーターは封印された値カードのようなものです。SQL は値を命令とは別に受け取ります。Sequelize v6 では bind が値を別送し、replacements は送信前にエスケープして挿入します。信頼できない入力から文字列を組み立てると両方を迂回します。テーブル名や列名には使えません。

危険 — 入力値を SQL に連結
sequelize.query(
  `SELECT * FROM users WHERE id = ${userId}`
)
強化 — 値を別途バインド
sequelize.query(
  "SELECT id FROM users WHERE id = $id",
  { bind: { id: userId },
    type: QueryTypes.SELECT }
)

値を SQL 構文に混ぜない

Sequelize v6 では replacements は Sequelize がエスケープして送信前に挿入し、bind は SQL テキストと別に値を送ります。どちらもユーザー値の連結を避けますが、構文はメソッドや方言で異なります。パラメーターはテーブル名、列名、ソート順、任意の SQL 断片には使えません。選択可能な構造はアプリ管理の固定 allowlist に対応付けます。モデルメソッドは一般的な構造化値を処理できますが、raw SQL とリテラル式も確認が必要です。

Sequelize クエリの監査方法

rg -n 'sequelize\.query\(|Sequelize\.literal\(' --glob '*.{js,ts,mjs,cjs}' .

よくある質問

Sequelize のモデルメソッドは常に SQL Injection に安全ですか?

通常の構造化値は Sequelize のクエリ構築で処理されます。ただし raw SQL、リテラル式、アプリが組み立てた文字列を確認してください。パラメーター化はレコード認可や業務ルールの検証を代替しません。

参考資料

関連項目 SQL インジェクション(CWE-89)の仕組みと各言語での防ぎ方 — flawopen.com SQLAlchemy text() は SQL Injection に安全? sqlx のコンパイル時クエリ検査は SQL インジェクションを防ぎますか? ストアドプロシージャは SQL インジェクションを防ぎますか? TypeORM QueryBuilder は SQL Injection に安全? Django ORMとSQL Injection:安全な書き方 Doctrine ORMのSQLインジェクション対策