面试题答案
一键面试防范 SQL 注入
- 使用参数化查询:在 Node.js 中使用数据库驱动(如
mysql2
或pg
等)时,避免直接拼接 SQL 语句。例如使用mysql2
时:
const mysql = require('mysql2');
const connection = mysql.createConnection({ /* 配置 */ });
const username = 'user';
const password = 'pass';
const query = 'SELECT * FROM users WHERE username =? AND password =?';
connection.query(query, [username, password], (err, results) => {
if (err) {
console.error(err);
return;
}
console.log(results);
});
- 输入验证与过滤:对用户输入进行严格验证,确保其符合预期格式。例如使用
joi
库验证用户名只能包含字母和数字:
const Joi = require('joi');
const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required()
});
const { error, value } = schema.validate({ username: 'user123' });
if (error) {
console.error(error.details[0].message);
} else {
console.log(value);
}
- 权限最小化:数据库用户只授予必要的权限,例如只给查询权限,而不给创建、修改、删除表等权限。
防范 XSS 攻击
- 对输出进行转义:在将用户输入输出到 HTML 页面时,使用转义函数。例如在 Express 应用中使用
ejs
模板引擎,ejs
会自动对输出进行转义:
<%- userInput %> <!-- ejs 自动转义 -->
如果手动处理,可使用 DOMPurify
库:
const DOMPurify = require('dompurify');
const clean = DOMPurify.sanitize(userInput);
// 将 clean 输出到页面
- 设置 HTTP 头部:
- Content - Security - Policy(CSP):限制页面可以加载的资源来源,防止恶意脚本注入。例如在 Express 应用中设置:
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.setHeader('Content - Security - Policy', "default - src'self'");
next();
});
- **X - Frame - Options**:防止页面被嵌入到其他框架中,避免点击劫持。设置方式如下:
app.use((req, res, next) => {
res.setHeader('X - Frame - Options', 'DENY');
next();
});
- **X - XSS - Protection**:启用浏览器内置的 XSS 过滤机制:
app.use((req, res, next) => {
res.setHeader('X - XSS - Protection', '1; mode = block');
next();
});
- 输入验证与过滤:同 SQL 注入防范一样,对用户输入进行严格验证,禁止包含 HTML 标签、JavaScript 代码等危险内容。例如使用正则表达式匹配过滤:
const input = '<script>alert("XSS")</script>';
const cleanInput = input.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');