哪里可能存在SQL注入?
-
GET
-
POST
-
HTTP头部注入
-
Cookie注入
即满足传递给后端的参数可以受用户控制且参数内容会直接被带到数据库语句中查询
4、SQL注入的原理
1)恶意拼接SQL语句
当我们在页面输入用户账号时,后台的数据库可能执行形似 select * from 表名 where username=$user_id
的SQL语句,此时如果我们输入的user_id后拼接上;DELETE FROM users;
将会实现将users表中的数据删除,类似地通过拼接其它SQL语句也可以执行相应的功能
2)添加额外条件
当我们在需要账号密码进行登录时,如果在账号密码输入处添加额外的恒成立的条件,即可在没有正确的账号密码时仍让操作请求成功。因为在验证账号密码时,后台的数据库可能执行形似 "select * from 表名 where username='" + username + "'and password='" + password + "'";
的SQL语句,如果在账号和密码后都添加or 1=1
,由于or左右两端的条件只需有一个为真则结果为真,而1=1恒为真,所以在where语句进行判断时账号和密码处都为成真赋值,这将实现绕过账号密码登录
5、SQL注入的分类
1)根据数据类型分类
-
整形注入
-
字符串型注入
判断方法
- and 1=1 / and 1=2 回显页面不同(整形判断)
* 输入and 1=1 和 and 1=2后发现页面变化,判断为整形注入 (因为如果为字符型判断时会变成’id=1 and 1=1‘以及’id=1 and 1=2’显然无法发挥and的作用,故结果都应该为false,页面不变)
- 单引号判断 ‘ 显示数据库错误信息或者页面回显不同(整形,字符串类型判断)
- -1/+1 回显下一个或上一个页面(整型判断)
2)根据注入的语法分类
-
UNION query SQL injection(可联合查询注入):可以使用union的情况下的注入。
-
Error-based SQL injection(报错型注入):即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
-
Boolean-based blind SQL injection(布尔型注入):即可以根据返回页面判断条件真假的注入。
-
Time-based blind SQL injection(基于时间延迟注入):即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
-
Stacked queries SQL injection(可多语句查询注入):可以同时执行多条语句的执行时的注入。
6、防止SQL注入
1)检查变量数据类型和格式
只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击。
2)过滤特殊符号
对于无法确定固定格式的变量,对特殊符号进行过滤或转义处理。
3)绑定变量,使用预编译语句
预防SQL注入的最佳方式,使用预编译的SQL语句语义不会发生改变,在SQL语句中,变量用问号?表示
什么是预编译语句
所谓预编译语句就是将这类语句中的值用占位符替代,可以视为将sql语句模板化或者说参数化(因为一条sql语句可能会反复执行,而只变化部分值),一般称这类语句叫Prepared Statements或者Parameterized Statements.
7、PrepareStatement可以防止sql注入的原因
原理是采用了预编译的方法,先将SQL语句中可被客户端控制的参数集进行编译,生成对应的临时变量集,再使用对应的设置方法,为临时变量集里面的元素进行赋值,赋值函数setString(),会对传入的参数进行强制类型检查和安全检查,所以就避免了SQL注入的产生。
1)为什么Statement会被sql注入
因为Statement没有实现参数化,传入的参数可能会改变SQL语句的结构,如语句
"select * from 表名 where username='" + username + "'and password='" + password + "'";
意为查找出用户名等于username且密码等于password的数据
当用户在username处输入1' or 1=1 #
时,语句将变为
"select * from 表名 where username='1' or 1=1 # and password = '1' or 1=1;
意为无论数据的用户名和密码是什么(因为或语句使得判断为永真式)(#将后面语句注释,解决引号闭合问题,未必需要),都将该条数据输出
这显然改变了原SQL语句的目的
2)为什么PrepareStatement可以防止sql注入
因为PrepareStatement实现参数化,其格式为:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
总结
总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。
如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
学习,当自己能上手再买这些书看又是非常有收获的事了。
[外链图片转存中…(img-FanB6mQT-1713295665498)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!