node-postgresのクエリでのSQLインジェクション

node-postgresのクエリでのSQLインジェクション

説明

利用者の入力をSQLに直接連結すると、攻撃者がクエリの構造を変え、意図しないデータベース操作を実行できる可能性があります。クエリの用途によっては、認証の回避、情報漏えい、データの削除につながります。

想定される影響

  • 不正な入力で認証用クエリを回避されるおそれがあります。
  • 権限のない利用者に機密情報を閲覧される可能性があります。
  • データベースのレコードを不正に追加、変更、削除されるおそれがあります。

対処方法

  • 値をSQLに連結せず、クエリパラメーターとしてバインドしてください。
  • 数値やメールアドレスなど、想定する型と形式に従って入力を検証してください。
  • ORMやクエリビルダーでも値をバインドするAPIを使ってください。テーブル名や列名は値パラメーターで表せないため、固定の許可リストから選んでください。

例

接続とクエリの部分だけを抜粋しています。CommonJSでは非同期関数内に置き、エラー処理と接続の後処理を追加してください。

変更前

javascript
const { Client } = require('pg')
const client = new Client()
await client.connect()
let query = 'SELECT * FROM users WHERE id = ' + userInput;
const res = await client.query(query);
await client.end();

変更後

javascript
const { Client } = require('pg')
const client = new Client()
await client.connect()
const res = await client.query('SELECT * FROM users WHERE id = $1', [userInput]);
await client.end();

変更前はuserInputをSQLに連結するため、クエリを変更される可能性があります。変更後は$1に入力をバインドし、SQL構文ではなく値として扱います。

参考資料