• 最新SQL注入漏洞修复建议


    点击星标,即时接收最新推文

    82eff4e07b8de5dcddd63dd694d79fe2.png

    本文选自《web安全攻防渗透测试实战指南(第2版)》

    点击图片五折购书

    b87472e56ffa55de99b139bbea892a18.gif

    SQL注入漏洞修复建议

    常用的SQL注入漏洞的修复方法有两种。

    1.过滤危险字符

    多数CMS都采用过滤危险字符的方式,例如,用正则表达式匹配union、sleep、load_file等关键字。如果匹配到,则退出程序。例如,80sec的防注入代码如下:

    1. functionCheckSql($db_string,$querytype='select')
    2. {
    3. global$cfg_cookie_encode;
    4. $clean='';
    5. $error='';
    6. $old_pos= 0;
    7. $pos= -1;
    8. $log_file= DEDEINC.'/../data/'.md5($cfg_cookie_encode).'_safe.txt';
    9. $userIP= GetIP();
    10. $getUrl= GetCurUrl();
    11. //如果是普通查询语句,则直接过滤一些特殊语法
    12. if($querytype=='select')
    13. {
    14. $notallow1="[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}";
    15. //$notallow2 = "--|/\*";
    16. if(preg_match("/".$notallow1."/i",$db_string))
    17. {
    18. fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");
    19. exit("Safe Alert: Request Error step 1 !");
    20. }
    21. }
    22. //完整的SQL检查
    23. while(TRUE)
    24. {
    25. $pos=strpos($db_string,'\'',$pos+ 1);
    26. if($pos=== FALSE)
    27. {
    28. break;
    29. }
    30. $clean.=substr($db_string,$old_pos,$pos-$old_pos);
    31. while(TRUE)
    32. {
    33. $pos1=strpos($db_string,'\'',$pos+ 1);
    34. $pos2=strpos($db_string,'\\',$pos+ 1);
    35. if($pos1=== FALSE)
    36. {
    37. break;
    38. }
    39. elseif($pos2== FALSE ||$pos2>$pos1)
    40. {
    41. $pos=$pos1;
    42. break;
    43. }
    44. $pos=$pos2+ 1;
    45. }
    46. $clean.='$s$';
    47. $old_pos=$pos+ 1;
    48. }
    49. $clean.=substr($db_string,$old_pos);
    50. $clean= trim(strtolower(preg_replace(array('~\s+~s'),array(' '),$clean)));
    51. //老版本的MySQL不支持Union,常用的程序里也不使用Union,但是一些黑客使用它,所以要检查它
    52. if(strpos($clean,'union') !== FALSE && preg_match('~(^|[^a-z])union($|[^[a-z])~s',$clean) != 0)
    53. {
    54. $fail= TRUE;
    55. $error="union detect";
    56. }
    57. //发布版本的程序可能不包括“--”“#”这样的注释,但是黑客经常使用它们
    58. elseif(strpos($clean,'/*') > 2 ||strpos($clean,'--') !== FALSE ||strpos($clean,'#') !== FALSE)
    59. {
    60. $fail= TRUE;
    61. $error="comment detect";
    62. }
    63. //这些函数不会被使用,但是黑客会用它来操作文件
    64. elseif(strpos($clean,'sleep') !== FALSE && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s',$clean) != 0)
    65. {
    66. $fail= TRUE;
    67. $error="slown down detect";
    68. }
    69. elseif(strpos($clean,'benchmark') !== FALSE && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s',$clean) != 0)
    70. {
    71. $fail= TRUE;
    72. $error="slown down detect";
    73. }
    74. elseif(strpos($clean,'load_file') !== FALSE && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s',$clean) != 0)
    75. {
    76. $fail= TRUE;
    77. $error="file fun detect";
    78. }
    79. elseif(strpos($clean,'into outfile') !== FALSE && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s',$clean) != 0)
    80. {
    81. $fail= TRUE;
    82. $error="file fun detect";
    83. }
    84. //老版本的MySQL不支持子查询,程序里可能也用得少,但是黑客可以使用它查询数据库敏感信息
    85. elseif(preg_match('~\([^)]*?select~s',$clean) != 0)
    86. {
    87. $fail= TRUE;
    88. $error="sub select detect";
    89. }
    90. if(!empty($fail))
    91. {
    92. fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||$error\r\n");
    93. exit("Safe Alert: Request Error step 2!");
    94. }
    95. else
    96. {
    97. return$db_string;
    98. }
    99. }

    使用过滤的方式,可以在一定程度上防止出现SQL注入漏洞,但仍然存在被绕过的可能。

    2.使用预编译语句

    使用PDO预编译语句时需要注意的是,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库中数据的增加、删除、修改、查询。示例代码如下:

    1. $pdo=new PDO('mysql:host=127.0.0.1;dbname=test','root','root');
    2. $stmt=$pdo->prepare('select * from user where id=:id');
    3. $stmt->bindParam(':id',$_GET['id']);
    4. $stmt->execute();
    5. $result=$stmt->fetchAll(PDO::FETCH_ASSOC);
    6. var_dump($result);
    7. ?>

    43f13424f9322d07b696d29c6cc0c50e.gif

    MS08067安全实验室视频号已上线

    欢迎各位同学关注转发~

    —  实验室旗下直播培训课程  —

    5b056c36b6b6b7c101aa54131dc1afe9.png

    d45f7516249b5cf8b3ea116cf3d19ec0.jpeg

    2bf3d02ff59ed89cfcd57874fe97ae85.jpegd94cdb04328094f25666f64db6ad9b51.png

    aa5793a229bcf438d8b5e5cb8e42a2b2.jpeg

    4b529fc0b09d8424c5a9c703b99de4ae.jpeg

    3ab2323e8c1fa8a1be4941473375efc5.jpeg

    729c5320fc81076d79e1559440086b99.jpeg

    35a15a1ad891410a8158464783540897.jpeg


    和20000+位同学加入MS08067一起学习

    9531962698d113bdc37a3baa8f605308.gif

  • 相关阅读:
    C语言---指针
    XSS攻击理解与预防
    系列八、Redis的事务
    【c++刷题Day2】专题2线性DP
    WebRTC
    Java调用Azure证书错误javax.net.ssl.SSLHandshakeException
    jenkins pipline发布至docker集群
    Redis 7.x 系列【14】数据类型之流(Stream)
    Python 实现动态动画心形图
    centos 安装 docker
  • 原文地址:https://blog.csdn.net/shuteer_xu/article/details/134025269