面试题答案
一键面试1. SQL 注入漏洞
- 产生原因:当使用模板引擎渲染动态页面时,如果用户输入的数据直接拼接到 SQL 查询语句中,而未进行适当的转义或参数化处理,恶意用户就可以通过构造特殊的输入来改变 SQL 语句的逻辑,从而执行非预期的 SQL 操作,如获取敏感数据、修改数据库等。
- 防范措施:
- 使用参数化查询:在数据库操作中,避免直接拼接用户输入到 SQL 语句,而是使用参数化的方式传递数据。
- 对输入数据进行严格校验:确保输入的数据符合预期的格式和类型。
- 代码示例:
假设使用
mysql
模块与数据库交互,在 Express 项目中:
const express = require('express');
const mysql = require('mysql');
const app = express();
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
app.get('/user', (req, res) => {
const username = req.query.username;
const sql = 'SELECT * FROM users WHERE username =?';
connection.query(sql, [username], (error, results, fields) => {
if (error) throw error;
res.render('user', { users: results });
});
});
connection.connect();
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
2. Cross - Site Scripting (XSS) 漏洞
- 产生原因:如果从用户输入中获取的数据直接在模板中渲染,而未对特殊字符进行转义,恶意用户可以注入恶意的 JavaScript 代码。当其他用户访问包含这些恶意代码的页面时,恶意代码就会在用户浏览器中执行,从而可以窃取用户的 cookie、会话信息等敏感数据。
- 防范措施:
- 对用户输入进行转义:在渲染到页面之前,使用专门的库对特殊字符进行转义,如
DOMPurify
。 - 启用 Content - Security - Policy(CSP):通过设置 HTTP 头来限制页面可以加载的资源来源,防止恶意脚本的注入。
- 对用户输入进行转义:在渲染到页面之前,使用专门的库对特殊字符进行转义,如
- 代码示例:
使用
DOMPurify
防范 XSS:
const express = require('express');
const DOMPurify = require('dompurify');
const app = express();
app.get('/message', (req, res) => {
const message = req.query.message;
const cleanMessage = DOMPurify.sanitize(message);
res.render('message', { message: cleanMessage });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
设置 CSP 头:
app.use((req, res, next) => {
res.setHeader('Content - Security - Policy', "default - src'self'");
next();
});
3. 文件包含漏洞
- 产生原因:如果模板引擎配置不当,允许通过用户输入来指定要包含的文件路径,恶意用户可能会利用这个漏洞包含服务器上的敏感文件(如配置文件、密码文件等),从而获取敏感信息。
- 防范措施:
- 严格限制文件包含的路径:只允许包含特定目录下的文件,避免使用用户输入直接作为文件路径。
- 对文件路径进行校验:确保输入的路径是合法且预期的。
- 代码示例: 假设使用 EJS 模板引擎,在 Express 中限制文件包含:
const express = require('express');
const ejs = require('ejs');
const app = express();
app.set('views', './views');
app.set('view engine', 'ejs');
app.get('/page', (req, res) => {
const page = req.query.page;
const allowedPages = ['home', 'about'];
if (!allowedPages.includes(page)) {
return res.status(400).send('Invalid page');
}
res.render(page);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});