網路安全 基礎
什麼是 SQL Injection?該如何避免?
什麼是 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 評分
