你已经看到了如何验证来自外部世界对你的Express应用程序的输入。
当你运行一个面向公众的服务器时,你会很快学会一件事:永远不要相信输入。
即使你进行了消毒,并确保人们不能使用客户端代码输入奇怪的东西,你仍然会受到人们使用工具(甚至只是浏览器的devtools)直接向你的端点发送的影响。
或者机器人尝试人类已知的各种可能的利用组合。
你需要做的是对你的输入进行消毒。
你已经用于验证输入的express-validator 包也可以方便地用于执行消毒。
假设你有一个接受姓名、电子邮件和年龄参数的POST端点。
const express = require('express')
const app = express()
app.use(express.json())
app.post('/form', (req, res) => {
const name = req.body.name
const email = req.body.email
const age = req.body.age
})
你可以用这个包来验证它。
const express = require('express')
const app = express()
app.use(express.json())
app.post('/form', [
check('name').isLength({ min: 3 }),
check('email').isEmail(),
check('age').isNumeric()
], (req, res) => {
const name = req.body.name
const email = req.body.email
const age = req.body.age
})
你可以通过在验证方法后加入消毒方法来增加消毒的内容。
app.post('/form', [
check('name').isLength({ min: 3 }).trim().escape(),
check('email').isEmail().normalizeEmail(),
check('age').isNumeric().trim().escape()
], (req, res) => {
//...
})
这里我使用了这些方法。
trim()修剪字符串开头和结尾的字符(默认为空白)。escape()用相应的HTML实体替换 , , , , 和<>&'"/normalizeEmail()对电子邮件地址进行规范化处理。接受几个选项来小写电子邮件地址或子地址(例如: )。flavio+newsletters@gmail.com
其他消毒方法。
blacklist()删除出现在黑名单中的字符whitelist()删除不出现在白名单中的字符unescape()用 , , , , 替换HTML编码的实体。<>&'"/ltrim()像trim()一样,但只修剪字符串开头的字符rtrim()像trim()一样,但只修剪字符串末端的字符stripLow()删除ASCII控制字符,这些字符通常是不可见的。
强制转换为一种格式。
toBoolean()将输入的字符串转换为布尔值。除了'0'、'false'和''以外的所有东西都返回真。在严格模式下,只有'1'和'true'返回真。toDate()将输入的字符串转换为日期,如果输入的不是日期,则为空toFloat()将输入的字符串转换为浮点数,如果输入的不是浮点数,则为NaNtoInt()将输入的字符串转换为整数,如果输入的不是整数,则转换为NaN。
与自定义验证器一样,你可以创建一个自定义的消毒器。
在回调函数中,你只需返回消毒后的值。
const sanitizeValue = value => {
//sanitize...
}
app.post('/form', [
check('value').customSanitizer(value => {
return sanitizeValue(value)
}),
], (req, res) => {
const value = req.body.value
})