9、预防常见注入类问题的安全设计
字数 1292 2025-08-19 12:42:14
预防常见注入类问题的安全设计
1. 常见注入问题
1.1 SQL注入
SQL注入是发生于应用程序与数据库层的安全漏洞,攻击者在输入字符串中注入SQL指令。当程序忽略字符检查时,这些恶意指令会被数据库服务器误认为是正常SQL指令而执行。
1.2 NoSQL注入
NoSQL注入是针对非关系数据库(如MongoDB、Cassandra DB等)的网络攻击。由于NoSQL数据库支持JavaScript等语言,攻击者可通过注入恶意代码获取或篡改数据。
1.3 XSS(跨站脚本攻击)
XSS攻击发生在web应用程序未能清理包含脚本代码(通常是JavaScript)的用户输入时。攻击者提供包含恶意代码的文本字符串,由受害者的浏览器执行而非作为常规参数处理。
1.4 命令注入
当web应用程序需要在底层操作系统中执行系统命令时,如果存在漏洞,攻击者可在用户输入中提供自己的操作系统命令,可能导致系统完全被破坏。
1.5 XXE注入(XML外部实体注入)
当应用程序接受XML输入并配置为支持具有弱XML解析器安全性的遗留DTD时,攻击者可发送特制XML文档执行路径遍历、SSRF甚至远程代码执行。
2. 安全设计解决方案
2.1 预编译解决SQL注入
预编译通过两次交互完成查询:
- 第一次发送查询语句模板,由SQL引擎解析为AST或Opcode
- 第二次发送数据,代入AST或Opcode中执行
关键点:
- 使用占位符替代字段值
- 表名和列名不能被占位符替代,若可控则可能引入漏洞
- MyBatis中应使用
#{}而非${}
MySQL实现:
- 普通PreparedStatement是假预编译,仅自动转义
- 需在驱动url开启
useServerPrepStmts配置实现真正预编译
2.2 XSS防护工具
HTML过滤工具:
- 使用白名单/黑名单过滤用户输入的HTML
- 如DOMPurify工具
响应头设置:
-
X-Frame-Options可选值:- DENY:页面不能被嵌入任何iframe/frame
- SAMEORIGIN:只能被本站页面嵌入
- ALLOW-FROM:允许frame加载
-
X-XSS-Protection可选值:- 0:关闭XSS防护
- 1:删除检测到的恶意代码(默认)
- 1; mode=block:检测到恶意代码时不渲染
2.3 命令注入防护
- 不使用时禁用相应函数
- 尽量避免执行外部应用程序或命令
- 转义命令中的所有shell元字符(#&等)
2.4 XXE防御
Java XXE防护:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
过滤关键词:
<!DOCTYPE<!ENTITY SYSTEMPUBLIC
3. 实现示例
3.1 MyBatis预编译示例
select user_id,user_name from t_user where user_id = #{user_id}
MyBatis会将其转换为:
select id, user_name from t_user where id = ?
并在执行时替换为实际值,自动添加单引号。
3.2 XSS过滤示例
<script type="text/javascript" src="dist/purify.min.js"></script>
<script>
const clean = DOMPurify.sanitize(dirty);
</script>
3.3 命令执行示例(Java)
// 不推荐使用
ProcessBuilder builder = new ProcessBuilder(cmdList);
builder.redirectErrorStream(true);
Process process = builder.start();
// 或
Runtime.getRuntime().exec(cmdList);
4. 总结
防护注入攻击的关键在于:
- 对所有用户输入进行严格验证和清理
- 使用参数化查询而非字符串拼接
- 禁用不必要的功能和协议
- 实施最小权限原则
- 使用安全框架和库处理潜在危险操作
通过多层次防御策略,可有效降低各类注入攻击的风险。