1.什么是SQL注入
一种注入攻击,可以执行恶意SQL语句。
通过将任意SQL代码插入数据库查询,使攻击者能够完全控制Web应用程序后面的数据库服务器。
犯罪分子可能会利用它来未经授权访问用户的敏感数据:客户信息,个人数据,商业机密,知识产权等。SQL注入攻击是最古老,最流行,最危险的Web应用程序漏洞之一。
2.SQL注入攻击的类型
SQL注入分为多种类型
1.带内注入
2.盲注入
3.带外注入
3.带内注入
1. 基于错误的SQL注入:从显示的错误消息中获取有关数据库的信息
2.基于联合的SQL注入:依赖于攻击者能够将UNION ALL被盗信息的结果与合法结果连接起来。
这两种技术都 依赖于 攻击者修改应用程序发送的SQL,以及浏览器中显示的错误和返回的信息。
如果应用程序开发人员或数据库开发人员无法正确地参数化他们在查询中使用的值,那么它会成功。
4.例子
举一个 简单的例子
在我们没有使用任何安全框架的情况下,
比如在一个登陆界面,要求用户输入用户名和密码,
以mybatis为例 ,登陆页面的sql写成了这样
如果 list的size不为0 就放行~
数据库里的user 表中有两条记录
username password
a 1
b 2
尝试输入 正确的用户名密码
显示我们登陆成功
尝试输入 错误的密码
我们登录失败
这个时候,如果我们在用户名密码中输入以下文本(密码和用户名一致)
结果是 我们登陆成功
为什么呢? 看一下控制台的打印:
Time:979 ms - ID:com.b505.indoor.path.mapper.MapMapper.selectUser
Execute SQL:select * from user where username ='1' or '1'='1' and password = '1' or '1'='1'
[User(username=a, password=1), User(username=b, password=2)]
我们输入了
1' or '1'='1 这样的用户名和密码却成功登陆了,这就是一个最简单的sql注入
当然,我们没有使用任何的安全框架,我们登录的逻辑也是非常的简单,才导致他能够成功的登陆
这里,他能够登录的最关键的地方在于,我们使用了动态SQL
select * from user where username ='${username}' and password = '${password}'
所以才造成了,他能够用拼接sql的方式。
java程序中如何防范SQL注入
-
无论是直接使用数据库还是使用如mybatis组件,使用sql的预编译,不要用拼接字符串。如${param}就是拼接字符串,而#{param}是预编译,使用Prepared Statements是防止SQL注入的最佳方法之一。与动态SQL查询相比,它更易于编写且更易于理解。
2.后台过滤检测:使用正则表达式过滤传入的参数**;**.字符串过滤
3.前端检测sql常见关键字,如or and drop之类的
4.加密数据库中的关键字段
5.使用存储过程
存储过程还为数据库增加了一个额外的安全层。它执行所需的转义,以便应用程序将输入视为要操作的数据,而不是要执行的SQL代码。
准备好的语句和存储过程之间的区别在于,存储过程的SQL代码是写入并存储在数据库服务器中,然后从Web应用程序中调用的。
如果仅通过存储过程允许用户访问数据库,则无需在任何数据库表上显式授予用户直接访问数据的权限。这样,您的数据库仍然是安全的。
6.限制特权
除非有必要,否则请不要使用具有root用户访问权限的帐户连接到数据库,因为攻击者可能会访问整个系统。因此,最好在SQL注入的情况下使用具有有限特权的帐户来限制损害的范围。
7..隐藏错误消息中的信息
错误消息对于攻击者了解您的数据库体系结构很有用,因此请确保仅显示必要的信息。最好显示一条一般性错误消息,告诉您出了什么问题,并鼓励用户与技术支持团队联系,以防问题仍然存在。
8.更新系统
SQL注入漏洞是一个经常发生的编程错误,并且会定期发现,因此,至关重要的是应用修补程序并将系统更新到最新版本。
来源:CSDN
作者:wang720813
链接:https://blog.csdn.net/wang720813/article/details/103570387