美文网首页程序员
sql注入与防止

sql注入与防止

作者: caoxingyu | 来源:发表于2020-04-30 14:35 被阅读0次

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

    举例说明:

    • sql注入跳过登录认证
      假设登录语句为 select * from users where id ='id' and pwd = 'pwd'
    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的预处理可以参考这里

    相关文章

      网友评论

        本文标题:sql注入与防止

        本文链接:https://www.haomeiwen.com/subject/lyvzwhtx.html