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 的部分了~


<<:  第24天~Firebase

>>:  Composite 合成模式

#22 IPAPAPI - IP as Picture API

今天来用 Cloudflare Workers 写个有趣的东西吧! 你的 IP 是不是 ? 很酷吧!...

Day08_把四阶文件写的跟资治通监一样~你就赢啦XDDD"(拖走)

▉补一下,昨天说的,不知道怎麽评弱点跟威胁分数的话 技服中心 教材下载 共通性规范| https:/...

Day 29 | 来组合个画面吧 - Part 2

昨天稍微提了一些我切画面时, 对 HTML 的规划, 今天就来讲 CSS 的部分啦! (铁人赛剩一天...

哈罗,世界!

Photo by KOBU Agency on Unsplash 文章同步发布於:https://...

切换群集的 context

本篇文章实现从本地端的 K8s 群集操作 GKE。先从 GKE 上的群集 .kube/config ...