Day02-入口管制(一)

前言

要打造安全的 API Server,第一步就是不要让奇怪的资料跑进来,也就是要做 input validation

只要可以在一开始把奇怪的请求、资料给挡掉,那就可以大幅降低这些资料进到资料库、进而弄坏某个功能的机会

检查格式

所以具体而言要做什麽呢?首先是要过滤掉语法或格式错误的请求,譬如说信箱格式错误、电话号码长度不对等等,或是你明明要求输入 4 到 16 字的密码,使用者却只给你一大串 30 个字,这些都可以在一开始就过滤掉

虽然这些过滤听起来很简单,但实际上还满琐碎的,所以我推荐直接用别人的 library,像是 Node.js 的 validator 跟 Go 的 govalidator 都很不错,这样不只可以省下许多时间,还可以避免掉自己造轮子的 bug

实际的案例就像这样,使用者填了他的个人资料送出後,我用 Node.js 的 express-validator(包装成 middleware 形式的 validator)对信箱、电话做验证,如果格式有什麽错误那就把错误送回前端,没有的话则是请求成功

const { body, validationResult } = require('express-validator')

//                vvvv |信箱格式验证| vvvv   vvvvvvv |手机格式验证| vvvvvvv
app.post('/user', body('email').isEmail(), body('phone').isMobilePhone(), (req, res) => {
    const errors = validationResult(req)
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() }) // 格式有错就回传 400
    }
    User.create({ username: req.body.username, phone: req.body.phone }) // 格式正确才进资料库
  },
)

检查语义

除了语法、格式上的错误之外,另外一个很容易被忽略的是语义错误,譬如说使用者填的出生年份是 2050 年(从未来穿越回来的?)、入住日期比退房日期来得晚、网路订餐一次订 5000 份等等

像这类格式正确、内容错误的请求最好在一开始就挡掉,毕竟任何资料的值都有一个合理的范围,如果不小心把这些值存进资料库,哪天在计算时就可能引发意想不到的错误

同样以 Node.js 为例,如果我做的是一个订房网站,那除了确定入住、退房日期都是正确的日期格式外,还要确认退房时间比入住时间来得晚才行

// 自己写一个 middleware 用来确认入住、退房时间
const isCheckInBeforeCheckout = body('checkIn').custom((checkIn, { req }) => {
    if(new Date(req.body.checkOut) < new Date(checkIn)) {
        // 如果退房时间比入住时间早
        throw new Error ('你的入住时间怪怪 der')
    }
    return true
})

//                                vvv 确认入住、退房时间 vvv
app.post('/order', /* 其他验证 */, isCheckInBeforeCheckout, (req, res) => {
    const errors = validationResult(req)
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() })
    }
    // 没问题才新增订单到资料库
    Order.create({ checkIn: req.body.checkIn, checkOut: req.body.checkOut })
  },
)

不能只靠前端检查

看到这边你可能会想说:我上 Airbnb 订房时他的 UI 设计得很好,所以根本不可能发生「入住日期比退房日期来得晚」的情况

但万一攻击者是直接用 Postman 或 Curl 这类工具发起恶意请求呢?所以不管你的前端设计、防范得再好,後端的 API Server 收到请求时务必要再做一次完整的检查,否则这类奇怪的资料一旦进了资料库,後果将不堪设想

小结

今天用两个小例子讲了 API server 的入口管制应该做什麽事:简单来说就是不管请求是从哪来的,只要资料进到 API server 就要从严处理,而且不管是在格式还是语义上都要进行确人,才不会有一些怪怪的资料趁机渗透进来哦~


<<:  【Day 02】C 语言的程序结构

>>:  Day02 X 为什麽要在前端做效能优化?

110/09 - 把照片储存在Android/data/packageName/files/

今天来实作使用ActivityResultContracts.TakePicture()开启相机,拍...

D13 - 用 Swift 和公开资讯,打造投资理财的 Apps { 加权指数K线图实作.1 }

目标: 做出台湾加权指数 K 线图 之前做出来的台股申购是独立的功能,为了不影响前面已经完成的功能,...

【Windows】安装 Apache Web Server(含多版本PHP并存)

前言 架设php最简单的方法,大概是用xampp。但是有时候专案会用到不同php版本,需要切换。就算...

.Net Core Web Api_笔记09_web api的属性路由模板两种写法_路由模板使用

在.net core mvc跟.net core web api专案中预设各自采用的一些配置 有不太...

跌破有色眼镜,就是打破惯性框架

「再一双拥抱真理的手臂,让第三只眼睛可以破开谜语。」 在尝试将刚刚学会的概念再做一次练习,发现到想像...