網路安全 基礎

什麼是 SQL Injection?該如何避免?

AI 練習作答

什麼是 SQL Injection?

SQL Injection(SQL 注入) 是指攻擊者透過在輸入欄位中插入惡意的 SQL 語法,操控後端資料庫執行非預期的查詢,達到竊取、竄改、刪除資料,甚至取得系統權限的目的。

攻擊範例

假設後端有這樣的查詢:

// 危險:直接將使用者輸入拼接進 SQL
const query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"

攻擊者在帳號欄位輸入:

' OR '1'='1

最終 SQL 變成:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '...'
-- '1'='1' 永遠為真,繞過登入驗證!

更危險的攻擊

-- 刪除整個資料表
'; DROP TABLE users; --

-- 取得所有使用者資料
' UNION SELECT username, password FROM users --

防範方式

1. 使用參數化查詢(Parameterized Queries)— 最重要

讓資料庫明確區分「SQL 語法」和「使用者輸入的資料」:

// ✅ 安全:使用 Prepared Statement
const query = 'SELECT * FROM users WHERE username = ? AND password = ?'
db.execute(query, [username, password])

// Node.js + MySQL 範例
connection.query(
  'SELECT * FROM users WHERE id = ?',
  [userId],
  (err, results) => { /* ... */ }
)

2. 使用 ORM(Object-Relational Mapping)

ORM 如 Prisma、Sequelize、TypeORM 預設使用參數化查詢:

// Prisma 範例(安全)
const user = await prisma.user.findUnique({
  where: { username: username }
})

3. 輸入驗證與白名單過濾

  • 驗證輸入格式(數字、Email 格式等)
  • 拒絕包含 SQL 關鍵字的輸入(黑名單,非主要防線)

4. 最小權限原則

資料庫帳號只給必要的權限(SELECT/INSERT),不給 DROP、DELETE 等危險操作。

5. 錯誤訊息不要暴露 SQL 細節

// ❌ 危險:洩露資料庫結構
res.json({ error: "SQL Error: Table 'users' doesn't exist" })

// ✅ 安全:通用錯誤訊息
res.status(500).json({ error: '伺服器錯誤,請稍後再試' })

✦ AI 模擬面試

輸入你的答案,AI 即時分析精準度與改進空間

登入後即可使用 AI 評分