0%

注入攻击防御

注入攻击防御详解

注入攻击是一类常见且危害极大的网络攻击方式,其核心原理是攻击者将恶意代码注入到应用程序的输入中,从而干扰程序的正常执行流程,达到窃取数据、篡改系统或获取权限等目的。常见的注入攻击主要包括SQL 注入OS 注入,以下是对这两种攻击的详细解析及防御措施。

SQL 注入

什么是 SQL 注入?

SQL 注入是攻击者通过在 Web 应用的输入参数中插入恶意 SQL 语句,欺骗数据库服务器执行非预期操作的攻击方式。由于应用程序未对用户输入进行严格过滤,恶意 SQL 语句会被当作合法指令执行,从而导致数据库信息泄露、数据篡改、权限提升等严重后果。

示例
假设一个登录功能的 SQL 查询语句为:

1
SELECT * FROM users WHERE username = '用户输入的用户名' AND password = '用户输入的密码';

若攻击者输入用户名为zhangsan,密码为' or '1'='1,则拼接后的 SQL 语句变为:

1
SELECT * FROM users WHERE username = 'zhangsan' AND password = '' or '1'='1';

由于'1'='1'恒为真,该语句会返回所有用户信息,导致攻击者无需正确密码即可登录。

SQL 注入的防御措施

(1)使用预编译语句(参数化查询)

预编译语句(如 Java 中的PreparedStatement)是防御 SQL 注入的最有效手段。其原理是:

  • 先将 SQL 语句的结构(不含参数)发送给数据库编译,生成执行计划;
  • 执行时仅传入参数值,数据库会将参数视为纯数据,而非 SQL 指令的一部分,从而避免攻击者篡改 SQL 结构。

示例(Java)

1
2
3
4
5
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); // 传入用户名参数
pstmt.setString(2, password); // 传入密码参数
ResultSet rs = pstmt.executeQuery();
(2)使用 ORM 框架

ORM(对象关系映射)框架(如 MyBatis、Hibernate)内置了参数过滤机制,能自动对输入参数进行转义,降低 SQL 注入风险。

  • MyBatis:使用#{}占位符接收参数时,会自动对参数进行转义;若使用${}(字符串拼接)则存在风险,需避免。
    安全示例

    1
    2
    3
    <select id="getUser" parameterType="String" resultType="User">
    SELECT * FROM users WHERE username = #{username}
    </select>
  • Hibernate:通过 HQL(Hibernate 查询语言)的参数绑定机制(如setParameter方法),自动处理参数转义。

(3)对用户输入进行严格过滤与验证
  • 输入验证:限制输入的长度、格式(如邮箱、手机号等使用正则表达式校验),拒绝不符合规则的输入。
  • 特殊字符过滤:对输入中的 SQL 关键字(如SELECTINSERTOR';等)进行转义或过滤(例如将'替换为'')。
(4)避免明文存储敏感信息
  • 密码等敏感数据需通过加密算法(如 SHA-256、BCrypt)进行单向哈希处理后存储,而非明文。即使数据库被入侵,攻击者也无法直接获取原始密码。

  • 示例:使用 BCrypt 加密密码:

    1
    String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
(5)限制数据库权限
  • 为应用程序的数据库账号分配最小权限(如仅授予SELECTINSERT等必要操作权限,禁止DROPALTER等高危操作),即使发生 SQL 注入,攻击者的破坏范围也会被限制。
(6)妥善处理异常信息
  • 避免将数据库错误信息(如表结构、字段名、服务器版本等)直接返回给用户,防止攻击者通过异常信息分析系统结构。应自定义错误页面,仅返回模糊的错误提示(如 “操作失败,请稍后重试”)。

OS 注入

什么是 OS 注入?

OS 注入(操作系统命令注入)是攻击者通过输入恶意指令,让应用程序执行非预期的操作系统命令的攻击方式。常见于应用程序调用系统命令(如pingls等)且未对输入进行过滤的场景。

示例
假设一个应用程序提供 “ping 某个 IP” 的功能,其后台代码为:

1
2
3
import os
ip = input("请输入IP地址:")
os.system(f"ping {ip}") # 直接拼接用户输入执行系统命令

若攻击者输入8.8.8.8 && rm -rf /,则拼接后的命令变为:

1
ping 8.8.8.8 && rm -rf /

这会导致先执行ping,再执行删除系统文件的恶意操作。

OS 注入的防御措施

(1)避免直接拼接用户输入到系统命令中
  • 尽量使用编程语言内置的 API 替代系统命令(如 Java 中用InetAddress类实现 ping 功能,而非调用ping命令)。
  • 若必须执行系统命令,使用参数化调用(如 Java 的ProcessBuilder),避免直接拼接用户输入。

安全示例(Java)

1
2
3
4
5
List<String> command = new ArrayList<>();
command.add("ping");
command.add(ip); // 直接传入参数,而非拼接字符串
ProcessBuilder pb = new ProcessBuilder(command);
Process process = pb.start();
(2)严格过滤用户输入
  • 限制输入的字符范围(如仅允许数字、.等合法字符,禁止&|;等命令分隔符)。
  • 使用白名单机制,仅允许预设的合法输入(如仅允许特定 IP 段)。
(3)限制应用程序权限
  • 运行应用程序的账号应使用最低权限(如普通用户权限),避免使用root或管理员权限,降低攻击成功后的破坏范围

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10