设为首页 收藏本站
查看: 575|回复: 0

[经验分享] php中防止SQL注入的方法

[复制链接]

尚未签到

发表于 2018-10-19 13:04:40 | 显示全部楼层 |阅读模式
  此文转载自网络,对内容有作删减。 旨在提供几点思路。
  原文:http://www.cnblogs.com/jianqingwang/p/6067967.html
  什么是SQL注入?
  SQL注入大部分情况下都是由于并没有对用户提交的数据、URL参数等进行过滤,而恰恰在这些未被过滤的参数或数据中存在了sql执行语句,最终导致数据库的数据被篡改、被导出等风险。
  怎样防止?
  【一、在服务器端配置】
  安全,PHP代码编写是一方面,PHP的配置更是非常关键。
  修改配置文件php.ini
  (1) 打开php的安全模式
  php的安全模式是个非常重要的内嵌的安全机制,能够控制一些php中的函数,比如system(),
  但是默认的php.ini是没有打开安全模式的,我们把它打开:
  safe_mode = on
  (2) 安全模式下执行程序主目录
  如果安全模式打开了,但是却是要执行某些程序的时候,可以指定要执行程序的主目录:
  safe_mode_exec_dir = D:/usr/bin
  一般情况下是不需要执行什么程序的,所以推荐不要执行系统程序目录,可以指向一个目录,
  然后把需要执行的程序拷贝过去,比如:
  safe_mode_exec_dir = D:/tmp/cmd
  但是,我更推荐不要执行任何程序,那么就可以指向我们网页目录:
  safe_mode_exec_dir = D:/usr/www
  (3) 安全模式下包含文件
  如果要在安全模式下包含某些公共文件,那么就修改一下选项:
  safe_mode_include_dir = D:/usr/www/include/
  其实一般php脚本中包含文件都是在程序自己已经写好了,这个可以根据具体需要设置。
  (4) 控制php脚本能访问的目录
  使用open_basedir选项能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问
  不应该访问的文件,一定程度上限制了phpshell的危害,我们一般可以设置为只能访问网站目录:
  open_basedir = D:/usr/www
  (5) 关闭危险函数
  如果打开了安全模式,那么函数禁止是可以不需要的,但是我们为了安全还是考虑进去。比如,
  我们觉得不希望执行包括system()等在那的能够执行命令的php函数,或者能够查看php信息的
  phpinfo()等函数,那么我们就可以禁止它们:
  disable_functions = system,passthru,exec,shell_exec,popen,phpinfo
  如果你要禁止任何文件和目录的操作,那么可以关闭很多文件操作
  disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir, rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown
  以上只是列了部分不叫常用的文件处理函数,你也可以把上面执行命令函数和这个函数结合,
  就能够抵制大部分的phpshell了。
  (6) 关闭PHP版本信息在http头中的泄漏
  我们为了防止***获取服务器中php版本的信息,可以关闭该信息斜路在http头中:
  expose_php = Off
  比如***在 telnet www.12345.com 80 的时候,那么将无法看到PHP的信息。
  (7) 关闭注册全局变量
  在PHP中提交的变量,包括使用POST或者GET提交的变量,都将自动注册为全局变量,能够直接访问,
  这是对服务器非常不安全的,所以我们不能让它注册为全局变量,就把注册全局变量选项关闭:
  register_globals = Off
  当然,如果这样设置了,那么获取对应变量的时候就要采用合理方式,比如获取GET提交的变量var,
  那么就要用$_GET['var']来进行获取,这个php程序员要注意。
  (8) 打开magic_quotes_gpc来防止SQL注入
  SQL注入是非常危险的问题,小则网站后台被***,重则整个服务器沦陷,
  所以一定要小心。php.ini中有一个设置:
  magic_quotes_gpc = Off
  这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,
  比如把 ' 转为 \'等,这对防止sql注射有重大作用。所以我们推荐设置为:
  magic_quotes_gpc = On
  (9) 错误信息控制
  一般php在没有连接到数据库或者其他情况下会有提示错误,一般错误信息中会包含php脚本当
  前的路径信息或者查询的SQL语句等信息,这类信息提供给***后,是不安全的,所以一般服务器建议禁止错误提示:
  display_errors = Off
  如果你却是是要显示错误信息,一定要设置显示错误的级别,比如只显示警告以上的信息:
  error_reporting = E_WARNING & E_ERROR
  当然,我还是建议关闭错误提示。
  【二、在PHP代码编写】
  虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于***可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截。
  当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。
  另外对于php手册中get_magic_quotes_gpc的举例:
  

    if (!get_magic_quotes_gpc()) {  $username = addslashes($_POST['username']);
  } else {
  $username = $_POST['username'];
  }
  

  最好对magic_quotes_gpc已经开放的情况下,还是对$_POST['username']进行检查一下。
  再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:
  mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的
  当前字符集,而mysql_escape_string 不考虑。
  总结一下:


  • addslashes() 是强行加\;
  • mysql_real_escape_string()  会判断字符集,但是对PHP版本有要求;
  • mysql_escape_string不考虑连接的当前字符集。
  在PHP编码的时候,如果考虑到一些比较基本的安全问题,首先一点:


  •   初始化你的变量
      我们改写如下:
      PHP代码
      


      


  • 防止SQL Injection (sql注射)  SQL 注射应该是目前程序危害最大的了,包括最早从asp到php,基本上都是国内这两年流行的技术,基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些sql查询语句,导致重要数据被窃取、数据丢失或者损坏,或者被***到后台管理。
      那么我们既然了解了基本的注射***的方式,那么我们如何去防范呢?这个就应该我们从代码去入手了。
      我们知道Web上提交数据有两种方式,一种是get、一种是post,那么很多常见的sql注射就是从get方式入手的,而且注射的语句里面一定是包含一些sql语句的,因为没有sql语句,那么如何进行,sql语句有四大句:select 、update、delete、insert,那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?
      于是我们使用正则就构建如下函数:
      PHP代码进行校验了,于是我们上面的程序代码就变成了下面的:
      PHP代码
      


      

      好,问题到这里似乎都解决了,但是我们有没有考虑过post提交的数据,大批量的数据呢?
      比如一些字符可能会对数据库造成危害,比如 ' _ ', ' %',这些字符都有特殊意义,那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的magic_quotes_gpc = off的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加' '的,那么我们要控制这些问题,于是构建如下函数:
      PHP代码

  

   
  

  

  我们又一次的避免了服务器被沦陷的危险。
  最后,再考虑提交一些大批量数据的情况,比如发贴,或者写文章、新闻,我们需要一些函数来帮我们过滤和进行转换,再上面函数的基础上,我们构建如下函数:
  PHP代码
  

   
  

  最后在告诉你上面表达的:1. 初始化你的变量 2. 一定记得要过滤你的变量
  thinkphp5中。
  在Thinkphp框架中,不要使用类似$_GET或者$_POST等PHP原生的数据获取方式,可以使用框架提供一个函数来获取这些数据及参数。
  

input('get.'); //相当于获取全部$_GET的数据。  
input('get.name'); //相当于获取$_GET['name']的数据。
  
input('post.'); //相当于获取全部的$_POST的数据。
  
input('post.id'); //相当于获取$_POST['id']的数据。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-623683-1-1.html 上篇帖子: 开发:异常收集之 sql查询 表或视图不存在 下篇帖子: SQL日期时间函数总结(MSSQL)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表