当前位置: 首页 > news >正文

SQL 注入风险与解决方案实战解析

网罗开发(小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 什么是 SQL 注入
    • 真实场景下的危害
    • 常见解决方案
      • 1. 使用 PreparedStatement
      • 2. MyBatis 使用 `#{}` 占位符
      • 3. 使用 ORM 框架封装查询
    • 总结

前言

在日常开发中,数据库操作几乎是绕不开的环节。很多同学写查询语句的时候,习惯直接用字符串拼接,比如:

String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";

乍一看挺正常,但一旦碰上心怀不轨的攻击者,后果就可能非常严重。这就是我们常说的 SQL 注入 问题。

什么是 SQL 注入

SQL 注入的本质就是:
用户的输入被直接拼接到 SQL 语句中,没有做任何防护,导致数据库把攻击者的输入当成真正的 SQL 指令去执行。

举个最经典的例子:

如果登录接口这样写:

String username = "admin";
String password = "' OR '1'='1";  // 攻击者输入的内容
String sql = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'";
System.out.println(sql);

拼接后的 SQL 就变成了:

SELECT * FROM users WHERE username='admin' AND password='' OR '1'='1'

这一句 OR '1'='1' 永远成立,所以攻击者轻轻松松绕过了密码验证,直接登录成功。

真实场景下的危害

别以为这只是理论,现实中因为 SQL 注入出问题的案例太多了。常见危害包括:

  • 绕过身份认证:像上面的例子,用户不用知道密码也能登录。
  • 数据泄露:攻击者可以拼接语句,把整个表的数据都查询出来。
  • 数据篡改或删除:严重的情况下,甚至可以执行 DROP TABLE users; 直接把表删掉。
  • 权限提升:通过复杂的注入方式,攻击者可能拿到数据库更高权限,导致系统全面失控。

所以在企业开发里,SQL 注入算是基础中的基础,必须提前预防。

常见解决方案

那我们该怎么防范呢?有几种常见的方式:

1. 使用 PreparedStatement

PreparedStatement 是 JDBC 提供的预编译语句对象。它会先把 SQL 模板交给数据库编译好,然后再传入参数。这样参数和 SQL 逻辑严格分离,用户输入就不会被当成 SQL 指令执行。

Demo 代码

import java.sql.*;public class SafeLoginDemo {public static void main(String[] args) throws Exception {String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String pass = "123456";String inputUser = "admin";String inputPass = "' OR '1'='1";Connection conn = DriverManager.getConnection(url, user, pass);String sql = "SELECT * FROM users WHERE username = ? AND password = ?";PreparedStatement stmt = conn.prepareStatement(sql);stmt.setString(1, inputUser);stmt.setString(2, inputPass);ResultSet rs = stmt.executeQuery();if (rs.next()) {System.out.println("登录成功: " + rs.getString("username"));} else {System.out.println("用户名或密码错误");}rs.close();stmt.close();conn.close();}
}

这里无论用户输入什么奇怪的密码,数据库都会把它当成一个普通的字符串参数处理,而不是 SQL 逻辑。

2. MyBatis 使用 #{} 占位符

在 MyBatis 中,有两个写法经常被混淆:${}#{}

  • ${}:直接拼接字符串,可能导致 SQL 注入。
  • #{}:安全的参数绑定,底层会帮你用 PreparedStatement。

错误写法(容易被注入):

<select id="getUserByName" resultType="User">SELECT * FROM users WHERE username = '${username}'
</select>

正确写法(推荐使用):

<select id="getUserByName" resultType="User">SELECT * FROM users WHERE username = #{username}
</select>

这样就算有人传了 ' OR '1'='1 这样的输入,也只会作为字符串参数传入,不会破坏 SQL 逻辑。

3. 使用 ORM 框架封装查询

像 Hibernate、JPA 这类 ORM 框架,通常都已经封装了参数绑定逻辑,默认情况下就能避免注入风险。

比如用 Spring Data JPA:

public interface UserRepository extends JpaRepository<User, Long> {User findByUsernameAndPassword(String username, String password);
}

Spring Data JPA 底层会自动生成类似 PreparedStatement 的语句,所以基本不需要担心 SQL 注入问题。

总结

回过头来看,SQL 注入的核心原因是 “把用户输入当成 SQL 语句的一部分”
解决的思路就是 “参数化查询”,让 SQL 和用户输入严格分离。

落地建议:

  1. 在 JDBC 层,统一用 PreparedStatement
  2. 在 MyBatis 中,统一用 #{} 而不是 ${}
  3. 在使用 ORM 框架时,不要为了图省事拼接 JPQL/HQL。
  4. 养成安全开发习惯,做代码审查时重点关注数据库查询部分。
http://www.dtcms.com/a/403992.html

相关文章:

  • 企业如何做网站推广出名的包装设计
  • 【STM32】位带操作
  • 供需网站开发做网站怎么发布
  • 保定网站建设方法水墨画风格网站
  • LINUX嵌入式面经(六)--常见算法篇
  • 网站优化推广方法庐江住房建设局网站
  • C语言基础【24】:组包和解包
  • 网站建设PHP开发是什么意思长沙seo服务
  • BMAD的多代理协同开发工作流指南
  • 沈阳网站建设 景乔科技毕节做网站
  • 网站开发 前端 后端 如何结合他达拉非片和西地那非片的区别
  • 做国际物流需要自己的网站吗win主机 wordpress静态
  • 指令微调数据评估与影响:构建高质量大语言模型的关键
  • 本墨陈黑做网站有版权网站开发维护成本
  • 【自动驾驶】自动驾驶概述 ⑤ ( 自动驾驶硬件概述 | 车载计算单元 IPC | 车辆线控系统 )
  • 静态IP的适用场景
  • 第1章 计算机系统概述
  • 印刷个性化网站建设的意义残疾人无障碍网站怎么做
  • Linux学习笔记(六)--Linux进程概念
  • C语言自学--数据在内存中的存储
  • 石家庄网站制作哪家好wordpress 优化数据库
  • 《基于Qt的车载系统项目》
  • 有哪些免费推广软件网站seo推广排名
  • 41.传输层协议UDP
  • 优良的定制网站建设提供商c2c模式的网站
  • 记力扣2516.每种字符至少取k个 练习理解
  • 广州站电话科创纵横 网站建设
  • 进程与集群:提升性能
  • 北京建设信源官方网站如何让wordpress文本小工具支持php和简码?
  • NLP算法岗位面试题精讲:深入理解LoRA与QLoRA