セキュリティ4 択難易度 標準

状況

ログインした会員が自分の請求書を見る API のレビュー。requireLogin はログインしているかだけを確かめる。

最も優先すべき指摘は?

app.get('/api/invoices/:id', requireLogin, async (req, res) => {  const invoice = await db.get('SELECT * FROM invoices WHERE id = ?', req.params.id);  res.json(invoice);});

正答

  1. 存在しない id のときに、404 を返す処理が入っていない
  2. SELECT * ではなく、必要な列だけを選んで返すべき
  3. 請求書の持ち主か確かめておらず、id を変えれば他人の分も読める
  4. id は数値なので、プレースホルダではなく数値に変換して埋め込むべき

解説

requireLogin は「ログインしているか」しか見ておらず、取り出した請求書がその会員のものかを確かめていない。URL の id を 1 つずつ変えれば、他の会員の請求書が次々に読める(認可漏れ、IDOR)。WHERE に会員 ID の条件を足す(id = ? AND user_id = ?)など、サーバー側で持ち主かどうかを必ず確かめる。404 を返さないのは使い勝手の問題で、列の絞り込みは余計な情報を返さない改善だが、他人のデータが丸ごと見える問題に比べれば優先度は低い。数値に変換して埋め込むより、プレースホルダのままのほうが安全。

参考: cheatsheetseries.owasp.org

idorauthorizationapi

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

セキュリティクイズへ