如何防止sql注入
1、检查变量数据类型和格式
如果你的SQL语句是类似where id={$id}这种形式,数据库里所有的id都是数字,那么就应该在SQL被执行前,检查确保变量id是int类型;如果是接受邮箱,那就应该检查并严格确保变量一定是邮箱的格式,其他的类型比如日期、时间等也是一个道理。总结起来:只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击。
比如,我们前面接受username参数例子中,我们的产品设计应该是在用户注册的一开始,就有一个用户名的规则,比如5-20个字符,只能由大小写字母、数字以及一些安全的符号组成,不包含特殊字符。此时我们应该有一个check_username的函数来进行统一的检查。不过,仍然有很多例外情况并不能应用到这一准则,比如文章发布系统,评论系统等必须要允许用户提交任意字符串的场景,这就需要采用过滤等其他方案了。
2、过滤特殊符号
对于无法确定固定格式的变量,一定要进行特殊符号过滤或转义处理。以PHP为例,通常是采用addslashes函数,它会在指定的预定义字符前添加反斜杠转义,这些预定义的字符是:单引号 (') 双引号 (") 反斜杠 (\) NULL。
来看2条SQL语句:
$uid = isset($_GET['uid']) ? $_GET['uid'] : 0;$uid = addslashes(uid);$sql = "SELECT uid,username FROM user WHERE uid='{$uid}'";以及$uid = isset($_GET['uid']) ? $_GET['uid'] : 0;$uid = addslashes(uid);$sql = "SELECT uid,username FROM user WHERE uid={$uid}";

上面两个查询语句都经过了php的addslashes函数过滤转义,但在安全性上却大不相同,在MySQL中,对于int类型字段的条件查询,上面个语句的查询效果完全一样,由于第一句SQL的变量被单引号包含起来,SQL注入的时候,黑客面临的首要问题是必须要先闭合前面的单引号,这样才能使后面的语句作为SQL执行,并且还要注释掉原SQL语句中的后面的单引号,这样才可以成功注入,由于代码里使用了addslashes函数,黑客的攻击会无从下手,但第二句没有用引号包含变量,那黑客也不用考虑去闭合、注释,所以即便同样采用addslashes转义,也还是存在SQL攻击漏洞。
对于PHP程序+MySQL构架的程序,在动态的SQL语句中,使用单引号把变量包含起来配合addslashes函数是应对SQL注入攻击的有效手段,但这做的还不够,像上面的2条SQL语句,根据「检查数据类型」的原则,uid都应该经过intval函数格式为int型,这样不仅能有效避免第二条语句的SQL注入漏洞,还能使得程序看起来更自然,尤其是在NoSQL(如MongoDB)中,变量类型一定要与字段类型相匹配才可以。
从上面可以看出,第二个SQL语句是有漏洞的,不过由于使用了addslashes函数,你会发现黑客的攻击语句也存在不能使用特殊符号的条件限制,类似where username='plhwin'这样的攻击语句是没法执行的,但是黑客可以将字符串转为16进制编码数据或使用char函数进行转化,同样能达到相同的目的,如果对这部分内容感兴趣,可以点击这里查看。而且由于SQL保留关键字,如「HAVING」、「ORDER BY」的存在,即使是基于黑白名单的过滤方法仍然会有或多或少问题,那么是否还有其他方法来防御SQL注入呢?
3、绑定变量,使用预编译语句
MySQL的mysqli驱动提供了预编译语句的支持,不同的程序语言,都分别有使用预编译语句的方法,我们这里仍然以PHP为例,编写userinfo2.php代码:
<?phpheader('Content-type:text/html; charset=UTF-8');$username = isset($_GET['username']) ? $_GET['username'] : '';$userinfo = array();if($username){//使用mysqli驱动连接demo数据库$mysqli = new mysqli("localhost", "root", "root", 'demo');//使用问号替代变量位置$sql = "SELECT uid,username FROM user WHERE username=?";$stmt = $mysqli->prepare($sql);//绑定变量$stmt->bind_param("s", $username);$stmt->execute();$stmt->bind_result($uid, $username);while ($stmt->fetch()) {$row = array();$row['uid'] = $uid;$row['username'] = $username;$userinfo[] = $row;}}echo '<pre>',print_r($userinfo, 1),'</pre>';
?>

从上面的代码可以看到,我们程序里并没有使用addslashes函数,但是浏览器里运行 http://localhost/test/userinfo2.php?username=plhwin' AND 1=1-- hack 里得不到任何结果,说明SQL漏洞在这个程序里并不存在。
实际上,绑定变量使用预编译语句是预防SQL注入的最佳方式,使用预编译的SQL语句语义不会发生改变,在SQL语句中,变量用问号?表示,黑客即使本事再大,也无法改变SQL语句的结构,像上面例子中,username变量传递的 plhwin' AND 1=1-- hack 参数,也只会当作username字符串来解释查询,从根本上杜绝了SQL注入攻击的发生。
  这种方式能防范SQL注入的原理是在SQL参数未注入之前,提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。也就是说其后注入进来的参数系统将不会认为它会是一条SQL语句,而默认其是一条一个参数。
数据库信息加密安全
相信大家都还对2011年爆出的CSDN拖库事件记忆犹新,这件事情导致CSDN处在风口浪尖被大家痛骂的原因就在于他们竟然明文存储用户的密码,这引发了科技界对用户信息安全尤其是密码安全的强烈关注,我们在防范SQL注入的发生的同时,也应该未雨绸缪,说不定下一个被拖库的就是你,谁知道呢。
在Web开发中,传统的加解密大致可以分为三种:
1、对称加密:
即加密方和解密方都使用相同的加密算法和密钥,这种方案的密钥的保存非常关键,因为算法是公开的,而密钥是保密的,一旦密匙泄露,黑客仍然可以轻易解密。常见的对称加密算法有:AES、DES等。
2、非对称加密:
即使用不同的密钥来进行加解密,密钥被分为公钥和私钥,用私钥加密的数据必须使用公钥来解密,同样用公钥加密的数据必须用对应的私钥来解密,常见的非对称加密算法有:RSA等。
3、不可逆加密:
利用哈希算法使数据加密之后无法解密回原数据,这样的哈希算法常用的有:md5、SHA-1等。
在我们上面登录系统的示例代码中,$md5password = md5($password); 从这句代码可以看到采用了md5的不可逆加密算法来存储密码,这也是多年来业界常用的密码加密算法,但是这仍然不安全。为什么呢?
这是因为md5加密有一个特点:同样的字符串经过md5哈希计算之后生成的加密字符串也是相同的,由于业界采用这种加密的方式由来已久,黑客们也准备了自己强大的md5彩虹表来逆向匹配加密前的字符串,这种用于逆向反推MD5加密的彩虹表在互联网上随处可见,在Google里使用md5 解密作为关键词搜索,一下就能找到md5在线破解网站,把我们插入用户数据时候的MD5加密字符串e10adc3949ba59abbe56e057f20f883e填入进去,瞬间就能得到加密前的密码:123456。当然也并不是每一个都能成功,但可以肯定的是,这个彩虹表会越来越完善。
所以,我们有迫切的需求采用更好的方法对密码数据进行不可逆加密,通常的做法是为每个用户确定不同的密码加盐(salt)后,再混合用户的真实密码进行md5加密,如以下代码:
<?php//用户注册时候设置的password$password = $_POST['password'];//md5加密,传统做法直接将加密后的字符串存入数据库,但这不够,我们继续改良$passwordmd5 = md5($password);//为用户生成不同的密码盐,算法可以根据自己业务的需要而不同$salt = substr(uniqid(rand()), -6);//新的加密字符串包含了密码盐$passwordmd5 = md5($passwordmd5.$salt);
小结
1、不要随意开启生产环境中Webserver的错误显示。
2、永远不要信任来自用户端的变量输入,有固定格式的变量一定要严格检查对应的格式,没有固定格式的变量需要对引号等特殊字符进行必要的过滤转义。
3、使用预编译绑定变量的SQL语句。
4、做好数据库帐号权限管理。
5、严格加密处理用户的机密信息。

转载于:https://www.cnblogs.com/bmjoker/p/8798680.html

1.4 如何防止sql注入相关推荐

  1. php mysql 防 sql注入_php 防sql注入方法

    php防sql注入的方法:1.使用mysql_real_escape_string方法转义SQL语句中使用的字符串中的特殊字符:2.打开magic_quotes_gpc来防止SQL注入:3.通过自定义 ...

  2. resultset mysql_MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)...

    [声明] 欢迎转载,但请保留文章原始出处→_→ [正文] 一.ResultSet接口的介绍: 对数据库的查询操作,一般需要返回查询结果,在程序中,JDBC为我们提供了ResultSet接口来专门处理查 ...

  3. mybaits的模糊查询_mybatis模糊查询防止SQL注入(很详细)

    SQL注入,大家都不陌生,是一种常见的攻击方式.攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如"or '1'='1'"这样的语句),有可能入侵参数检验不足的应用程序 ...

  4. SQL注入漏洞全接触--入门篇

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进 ...

  5. Sql注入和Html注入

    举例说,有一间公司的网页服务器上有一个留言板的代码,用来让用户发表简短的口信,例如: hello word!!!! 不过,这个代码原来有漏洞.一个意图入侵者得悉这间公司采用了有问题的代码,于是试图通过 ...

  6. mysql注入实例获取答案_本文实例讲述了MySQL解决SQL注入的另类方法。分享给大家供大家参考,具体如下:问题解读我觉得,这个问题每年带来的成本可以高达数十亿美元了。本文就来谈谈,...

    本文实例讲述了MySQL解决SQL注入的另类方法.分享给大家供大家参考,具体如下: 问题解读 我觉得,这个问题每年带来的成本可以高达数十亿美元了.本文就来谈谈,假定我们有如下 SQL 模板语句: se ...

  7. 【数据库】 兴唐第二十七节课只sql注入

    首先来一个用户登录程序 public static void login(String username, String password) {Connection conn = null;State ...

  8. 雷林鹏分享:MySQL 及 SQL 注入

    MySQL 及 SQL 注入 如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题. 本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入 ...

  9. WEB攻击手段及防御第2篇-SQL注入

    概念 SQL注入即通过WEB表单域插入非法SQL命令,当服务器端构造SQL时采用拼接形式,非法SQL与正常SQL一并构造并在数据库中执行. 简单的SQL注入的例子: 例1:test123456 or ...

  10. WEB安全,SQL注入漏洞的加固代码汇总

    该修复任务专用于处理以下安全性问题: [1] SQL 盲注 [2] SQL 注入 [3] XPath 注入 [4] 发现数据库错误模式 [5] 跨站点脚本编制 [6] 使用 SQL 注入的认证旁路 [ ...

最新文章

  1. (转)ZeroMQ的模式-Requset-Reply
  2. mysql int 默认值 为ull_mysql的 约束 数据库设计 数据库 存储 触发器 mysql 权限问题...
  3. php一些单选、复选框的默认选择方法(示例)
  4. java 的23种设计模式 单例模式
  5. ---------很简单的 一道 堆栈问题-------
  6. mysql从入门到精通之数据库基本概念理解
  7. 内核中架构相关代码简介
  8. dij算法堆优化_BZOJ 3040 最短路(road) 堆优化Dijkstra | 学步园
  9. 周末送新书 | 一文了解预训练语言模型!
  10. java类加载全过程
  11. Android 查看是否支持指定解码器(H265)
  12. 企业微信的好处和功能介绍 | 最新企业微信电脑版下载
  13. 网易云音乐 网络错误 linux,在Linux下网易云音乐打不开的另一种解决方法
  14. vue结合Waterfall做图片瀑布流展示
  15. Leetcode1859:将句子排序
  16. 百度Java二面面经
  17. 二维动态数组空间分配 c语言,科学网—C语言中动态二维数组的使用和分配 - 王一哲的博文...
  18. 北京通州规划图全面汇总
  19. 分享:Vue.js新手入门指南-0518-v1.0张雅慧(续)
  20. jupyter lab 相关

热门文章

  1. 最小生成树的普里姆算法c实现
  2. Richard S. Sutton个人主页翻译
  3. autotools使用总结
  4. mysql建表注意事项,关键字和保留字不能作为表名
  5. java技术学习路线(自用)
  6. codevs 3160 最长公共子串
  7. 总结篇——从零搭建maven多模块springboot+mybatis项目
  8. C#网络编程(异步传输字符串) - Part.3
  9. Bzoj 3831: [Poi2014]Little Bird
  10. git遇到的问题解决方案