面试题答案
一键面试跨域请求安全风险
- CSRF(Cross - Site Request Forgery,跨站请求伪造)攻击:
- 原理:攻击者诱导用户访问一个恶意链接或页面,在用户不知情的情况下,利用用户在目标网站已登录的身份,向目标网站发送恶意请求,执行非用户本意的操作,如转账、修改密码等。例如,用户登录了银行网站 A,未退出登录,此时访问了恶意网站 B,B 可以构造一个隐藏的表单,表单的 action 指向银行网站 A 的转账接口,当用户访问 B 时,表单自动提交,利用用户在 A 的登录状态完成转账。
- XSS(Cross - Site Scripting,跨站脚本攻击):
- 原理:攻击者在网页中注入恶意脚本,当用户访问该网页时,恶意脚本会在用户浏览器中执行,可窃取用户的 cookie 等敏感信息,然后攻击者可利用这些信息进行进一步攻击。例如,攻击者在一个评论区注入一段 JavaScript 脚本,当其他用户查看该评论时,脚本就会在他们的浏览器中执行。
防范风险的底层原理及实现
- 防范 CSRF 攻击:
- 底层原理:通过在用户请求中添加一个只有服务器和用户浏览器知道的随机令牌(CSRF Token),服务器验证请求中的令牌是否合法来判断请求是否来自合法用户。
- 后端(Node.js 示例):
- 安装
csurf
中间件:npm install csurf
- 使用示例:
const express = require('express'); const csrf = require('csurf'); const bodyParser = require('body - parser'); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); const csrfProtection = csrf({ cookie: true }); // 获取 CSRF Token 的路由 app.get('/csrf - token', csrfProtection, (req, res) => { res.json({ csrfToken: req.csrfToken() }); }); // 处理 POST 请求的路由 app.post('/submit - form', csrfProtection, (req, res) => { // 这里处理表单数据 res.send('Form submitted successfully'); }); const port = 3000; app.listen(port, () => { console.log(`Server running on port ${port}`); });
- 安装
- 前端(使用 Axios 示例):
- 首先获取 CSRF Token:
import axios from 'axios'; async function getCsrfToken() { const response = await axios.get('/csrf - token'); return response.data.csrfToken; } async function submitForm() { const csrfToken = await getCsrfToken(); const formData = { // 表单数据 username: 'testuser', password: 'testpassword' }; const response = await axios.post('/submit - form', formData, { headers: { 'X - CSRF - Token': csrfToken } }); console.log(response.data); } submitForm();
- 首先获取 CSRF Token:
- 防范 XSS 攻击:
- 底层原理:对用户输入的数据进行严格的过滤和转义,防止恶意脚本注入。
- 后端:
- 使用
DOMPurify
库对输入数据进行净化。 - 安装:
npm install dompurify
- 使用示例:
const express = require('express'); const bodyParser = require('body - parser'); const DOMPurify = require('dompurify'); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.post('/submit - comment', (req, res) => { const comment = req.body.comment; const cleanComment = DOMPurify.sanitize(comment); // 处理净化后的评论数据 res.send('Comment submitted successfully'); }); const port = 3000; app.listen(port, () => { console.log(`Server running on port ${port}`); });
- 使用
- 前端:
- 对用户输入进行实时验证,限制输入内容。例如,使用正则表达式限制输入只能是字母、数字和特定符号。
- 示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF - 8"> <title>XSS Prevention</title> </head> <body> <form id="commentForm"> <label for="comment">Comment:</label><br> <input type="text" id="comment" name="comment"><br> <input type="submit" value="Submit"> </form> <script> const form = document.getElementById('commentForm'); form.addEventListener('submit', function (e) { const commentInput = document.getElementById('comment'); const comment = commentInput.value; const regex = /^[a - zA - Z0 - 9\s.,!?]*$/; if (!regex.test(comment)) { alert('Only alphanumeric characters, spaces, and basic punctuation are allowed'); e.preventDefault(); } }); </script> </body> </html>
处理跨域 POST 请求及表单数据解析
- 处理跨域:
- 使用
cors
中间件在 Node.js 中处理跨域。 - 安装:
npm install cors
- 使用示例:
const express = require('express'); const cors = require('cors'); const bodyParser = require('body - parser'); const app = express(); app.use(cors()); app.use(bodyParser.urlencoded({ extended: false })); app.post('/post - data', (req, res) => { const formData = req.body; // 处理表单数据 res.send('Data received successfully'); }); const port = 3000; app.listen(port, () => { console.log(`Server running on port ${port}`); });
- 使用
- 解析表单数据:
- 在上述代码中,使用
body - parser
中间件的urlencoded
方法来解析 URL 编码格式的表单数据。extended: false
表示使用简单的解析方式,适合处理简单的键值对表单数据。如果表单数据可能包含嵌套对象等复杂结构,可设置extended: true
。
- 在上述代码中,使用
通过上述方法,可以在 Node.js 应用中安全地处理跨域 POST 请求并解析表单数据,同时有效防范 CSRF 和 XSS 等安全风险。