iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Security

從以卵擊石到堅若磐石之 Web API 安全性全攻略系列 第 24

Day24-你的資料安全嗎(二)

前言

昨天講了在各個資料庫中都通用的權限管理,而今天要則是要談談所有 SQL 的頭號公敵:SQL injection

SQL injection 原理

雖然大部分人都已經知道 SQL injection 的原理了,不過這邊還是再簡單說明一下,所謂的 SQL injection 就是在 SQL 裡面插入一些怪怪的東西,藉以達到攻擊的效果

譬如說這是一個用 Node.js 寫成的 API Server,使用者輸入帳號密碼後,程式就會用使用者輸入的帳號密碼組合出 SQL statement 到資料庫中撈看看有沒有對應的使用者

const express = require("express")
const app = express()

app.post('/api/login', (req, res) => {
    // 使用者輸入的帳號密碼
    const { email, password } = req.body
    
    // 用帳號密碼組出 sql statement
    const statement = `SELECT * FROM users WHERE email='${email}' AND pass='${hash(password)}'`
    const user = await db.query(statement);
    
    // 有撈到東西就代表登入成功
    if (user) {
        res.json('login success')
    }
})

但因為使用者可以自己決定要輸入什麼資料,只要懂一些 SQL 語法,就可以輸入 1' OR '1'='1' -- 作為 email,然後把整個 SQL statement 變成 SELECT * FROM users WHERE email='1' OR '1'='1',讓他百分之百登入成功

格式驗證

要防範這類的攻擊,要做的第一件事情就是之前在 Day2 講的格式驗證,如果你有去檢查使用者輸入的 email 格式是不是怪怪的,那像 1' OR '1'='1' -- 這種奇怪的輸入在第一時間就會馬上被拒絕掉,完全沒有通過的可能

雖然格式驗證並不是正規用來防禦 SQL injection 的做法,而且厲害的駭客還是可以想其他方法既通過驗證又達成 injection,但假如你的 API Server 真的有 SQL injection 的漏洞,那有一些基本的驗證也會讓這些漏洞更難被觸發,因此我個人建議格式驗證還是要有,反正安全性這種東西當然是越高越好,而且格式驗證的成本也滿低的不至於拖慢 Server 的速度

Prepared Statement

除了格式驗證之外,正規的做法是使用資料庫中 Prepared Statement 的功能,這樣就可以預先把變數的位置保留下來,等真正要進行 query 才把那些變數以「值」的方式丟給 SQL Server

如此一來資料庫在處理時就知道 emailhash(password) 這兩個字串並不是語法而是單純的值,所以如果攻擊者使用 1' OR '1'='1' -- 作為 email 想要進行 SQL injection,資料庫就不會把它當成語法來看待,而是會真的到 table 裡面去找找看有沒有誰的 email 是 1' OR '1'='1' --(當然不會有XD),所以就不會找到任何使用者,也就不會讓攻擊者成功登入

app.post('/api/login', (req, res) => {
    // 使用者輸入的帳號密碼
    const { email, password } = req.body
    
    // 用 ? 把變數的位置保留下來,在 query 時才把值給 SQL Server
    const statement = `SELECT * FROM users WHERE email=? AND pass=?`
    const user = await db.query(statement, [email, hash(password)]);
    
    if (user) { res.json('login success') }
})

小結

今天講了怎麼透過格式驗證及 Prepared Statement 來防範 SQL injection,雖然這已經是業界常識所以大家應該都已經很熟了XD,不過還是不厭其煩的幫大家複習一下

關於今天的內容有什麼問題歡迎在下方留言,沒問題的話明天就要來講講 NoSQL 的部分了~


上一篇
Day23-你的資料安全嗎(一)
下一篇
Day25-你的資料安全嗎(三)
系列文
從以卵擊石到堅若磐石之 Web API 安全性全攻略30

尚未有邦友留言

立即登入留言