程序员

sql注入与防止

2020-04-30  本文已影响0人  caoxingyu

SQL注入,也称SQL注入或SQL注码,是发生于应用程序与数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了字符检查,那么这些注入进去的恶意指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏或是入侵。

举例说明:

  1. 正常输入用户名和密码(admin、password)情况下,执行sql语句为:select * from users where id ='admin' and pwd = 'password',如果用户名和密码都正确,会登录成功;
  2. 假设攻击者在不知道密码的情况下输入以下' or 'a'='a密码,此时执行的sql语句为:select * from users where id ='admin' and pwd = ' ' or 'a'='a',SQL 语句的末尾被添加了 or 'a' = 'a',因此 WHERE 语句始终保持成立状态,也会登录成功。

对策:产生 SQL 注入漏洞的根本原因为,被指定为参数的字符串的一部分被排除出字面量,导致 SQL 语句发生了变化。因此,要防范 SQL 注入漏洞,就必须防止 SQL 语句在拼接过程中被更改。最有效的方式就是预处理语句(Prepared Statement),使用占位符'?'拼接SQL 语句,而不是直接把变量值拼接到sql语句中。
举例说明:
使用占位符拼接后,上面登录的sql语句就变成了:SELECT * FROM users WHERE id =? and pwd = ?,SQL 语句中的问号就是占位符,表示将变量或表达式等可变参数填到此处。下面我们就来演示一下在java中如何使用占位符完成上面的登录操作:

String sql = "SELECT * FROM users WHERE id =? and pwd = ?";  
PreparedStatement ps = conn.preparedStatement(sql);  
ps.setString(1, "jack");   //占位符顺序从1开始  
ps.setString(2, "123456"); //也可以使用setObject
ps.executeQuery();

为什么预处理语句(Prepared Statement)能够安全地调用 SQL 语句?

占位符的绑定变量操作在数据库引擎中执行。含有占位符的 SQL 语句被直接发送至数据库引擎,数据库引擎执行编译等准备工作后确定 SQL 语句。随后绑定值也被发送至数据库引擎,数据库引擎将收到的值填充进 SQL 语句后将其执行(绑定值时特殊字符会被转义),过程如下图:


预处理语句执行过程.png

关于mysql的预处理可以参考这里

上一篇下一篇

猜你喜欢

热点阅读