面试题答案
一键面试前端安全措施
- CSRF(跨站请求伪造)
- 措施:在前端,每次请求时带上 CSRF Token。在 Vue 项目中,可以在创建 Axios 实例时全局设置,将 Token 放在请求头中。例如:
import axios from 'axios'; const csrfToken = document.head.querySelector('meta[name="csrf-token"]').content; const instance = axios.create({ headers: { 'X - CSRF - Token': csrfToken } }); export default instance;
- XSS(跨站脚本攻击)
- 措施:
- 输入过滤:对用户输入的数据进行严格的过滤,去除可能包含恶意脚本的字符。在 Vue 组件中,可以使用 computed 属性对输入数据进行过滤处理。例如:
<template> <div> <input v - model="inputValue"> <p>{{filteredValue}}</p> </div> </template> <script> export default { data() { return { inputValue: '' }; }, computed: { filteredValue() { // 简单过滤示例,去除 <script> 标签 return this.inputValue.replace(/<script.*?>.*?<\/script>/gi, ''); } } }; </script>
- 输出编码:使用 Vue 的内置指令如
v - html
时要谨慎,对需要动态插入 HTML 的内容进行编码。例如:
<template> <div v - html="encodedContent"></div> </template> <script> import { DOMPurify } from 'dompurify'; export default { data() { return { originalContent: '<script>alert("XSS")</script>', encodedContent: '' }; }, created() { this.encodedContent = DOMPurify.sanitize(this.originalContent); } }; </script>
- 措施:
后端安全措施
- CSRF
- 措施:后端验证前端传来的 CSRF Token。以 Node.js 为例,使用 Express 框架,在中间件中验证 Token:
const express = require('express'); const app = express(); app.use((req, res, next) => { const csrfToken = req.headers['x - csrf - token']; // 验证逻辑,假设从 session 中获取正确的 Token const expectedToken = req.session.csrfToken; if (csrfToken === expectedToken) { next(); } else { res.status(403).send('Forbidden'); } });
- XSS
- 措施:后端同样要对接收的数据进行过滤和验证,防止恶意脚本存入数据库。例如在 Python 的 Django 框架中,可以使用内置的
clean
方法对表单数据进行清理:
from django import forms class MyForm(forms.Form): content = forms.CharField() def clean_content(self): data = self.cleaned_data['content'] # 简单过滤示例,去除 <script> 标签 import re return re.sub(r'<script.*?>.*?<\/script>', '', data)
- 措施:后端同样要对接收的数据进行过滤和验证,防止恶意脚本存入数据库。例如在 Python 的 Django 框架中,可以使用内置的
- SQL 注入
- 措施:使用参数化查询或 ORM(对象关系映射)。以 Java 为例,使用 JDBC 时采用参数化查询:
若使用 ORM,如 Hibernate,它会自动处理 SQL 注入问题,开发者无需手动编写复杂的 SQL 语句,而是通过对象操作数据库。例如:import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class UserDao { public User findUserByName(String name) { String sql = "SELECT * FROM users WHERE name =?"; try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password"); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, name); try (ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { // 创建 User 对象并返回 } } } catch (SQLException e) { e.printStackTrace(); } return null; } }
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class UserService { public User findUserByName(String name) { SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user = session.createQuery("FROM User WHERE name = :name", User.class) .setParameter("name", name) .uniqueResult(); tx.commit(); session.close(); return user; } }