🔒 SQLインジェクションを理解して対策する
このページで学ぶこと
- SQLインジェクションとは何かがわかる
- 実際に攻撃を体験して危険性を実感できる
- Prisma を使えば自動的に安全である理由がわかる
SQLインジェクションとは
SQLインジェクション は、ユーザーの入力を通じて悪意のある SQL を実行させる攻撃です。
攻撃者が入力: ' OR '1'='1
↓
実行されるSQL: SELECT * FROM users WHERE email = '' OR '1'='1'OR '1'='1' は常に true なので、すべてのユーザーのデータが取得されてしまいます。
攻撃を体験してみよう
脆弱なコードを書く
まずわざと脆弱なコードを書いて、SQLインジェクションを体験しましょう。
// ⚠️ app/api/vulnerable-search/route.js(脆弱なコード — 絶対に本番で使わない)
import { NextResponse } from 'next/server'
import { prisma } from '../../../lib/prisma'
export async function GET(request) {
const { searchParams } = new URL(request.url)
const email = searchParams.get('email')
// ❌ 危険:ユーザー入力をSQLに直接埋め込んでいる
const result = await prisma.$queryRawUnsafe(
`SELECT * FROM users WHERE email = '${email}'`
)
return NextResponse.json(result)
}以下のURLにアクセスしてみましょう(localhost:3000 で開発サーバーが動いている状態で)。
# 通常のリクエスト
http://localhost:3000/api/vulnerable-search?email=test@example.com
# 攻撃リクエスト(シングルクォートを入れる)
http://localhost:3000/api/vulnerable-search?email=' OR '1'='12番目のURLで全ユーザーのデータが返ってきたら、攻撃成功です。
実際の攻撃では、パスワードのハッシュや個人情報が丸ごと盗まれます。
Prisma は自動で安全
Prisma の通常の操作は**プレースホルダー(パラメータ化クエリ)**を使うため、SQLインジェクションが起きません。
// ✅ 安全(Prismaの通常操作)
const user = await prisma.user.findFirst({
where: { email: userInput } // userInput がどんな文字列でも安全
})内部では以下のようなSQLが実行されます。
-- プレースホルダーを使ったSQL(安全)
SELECT * FROM users WHERE email = $1
-- $1 に userInput の値が別途渡される$1 と値を分離して渡すため、値の中に SQL の記号が含まれていても、SQL として解釈されません。
$queryRaw を使うときの注意
複雑な条件で生のSQLを書きたいときは $queryRaw を使います。
この場合もテンプレートリテラル(タグ付きテンプレート)を使えば安全です。
// ✅ 安全(テンプレートリテラルを使う)
const result = await prisma.$queryRaw`
SELECT * FROM users WHERE email = ${userInput}
`
// ❌ 危険($queryRawUnsafe に直接文字列を渡す)
const result = await prisma.$queryRawUnsafe(
`SELECT * FROM users WHERE email = '${userInput}'`
)対策まとめ
| 状況 | 対応 |
|---|---|
| 通常のCRUD操作 | Prismaの通常操作を使えばOK(自動で安全) |
| 生のSQLを書きたい | $queryRaw + テンプレートリテラルを使う |
$queryRawUnsafe | ユーザー入力を絶対に渡さない |
Prisma を使っている限り、通常の操作では SQLインジェクションは起きません。
安心して開発に集中してください。
ただし、「生のSQL($queryRawUnsafe)を使わなければいけない状況」になったら必ずプレースホルダーを意識してください。
確認しよう
- 脆弱なエンドポイントを作り、SQLインジェクションを体験した
- Prismaの通常操作がなぜ安全かを説明できる
- プレースホルダー(パラメータ化クエリ)とは何かを説明できる
AIに聞いてみよう
「SQLインジェクション以外にもDBに関連するセキュリティリスクにはどんなものがありますか?」
次のステップ
Last updated on