セキュリティ4 択難易度 応用

状況

商品一覧を、画面で選んだ列で並べ替える API(DB は SQLite)。sort はクエリ文字列から受け取る。

この並べ替えの安全な直し方は?

const sort = req.query.sort; // 例: "price"const sql = `SELECT id, name, price FROM items ORDER BY ${sort}`;const rows = await db.all(sql);

正答

  1. ORDER BY ? と書き、sort をプレースホルダの値として渡す
  2. 許可する列名の一覧と照合し、一致したときだけ SQL に入れる
  3. sort に含まれるシングルクォートを取り除いてから SQL に入れる
  4. sort の長さを 20 文字以内に制限してから SQL に入れる

解説

プレースホルダで渡せるのは値だけで、列名やテーブル名、ASC / DESC のような SQL の構文の一部は渡せない。ORDER BY ? にすると「'price' という定数」で並べることになり、エラーにならないまま並べ替えが効かなくなる。列名を入力から受け取るときは、price・name など許可する列名の一覧を用意し、一致したときだけその列名を SQL に入れる(一致しなければ既定の列にする)。シングルクォートを取り除いても、ORDER BY の後ろは文字列の中ではないので、クォートを使わない式で書き換えられる。長さの制限も、短い攻撃文字列は防げない。

参考: cheatsheetseries.owasp.org

sql-injectionorder-byallowlist

この問題を含む セキュリティ のテストを制限時間つきで解く

セキュリティクイズへ