Discuz! 官方站

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 9237|回复: 0

x2 程序 sql 的安全过滤判断分析

[复制链接]
发表于 2011-7-5 11:32:31 | 显示全部楼层 |阅读模式
*************************************************
** 本教程基于版本:Discuz! X 2.0               **
*************************************************

class_core.php 里面 DB 类里 fetch_first、result_first、query 等方法里面首先会调用 checkquery 方法对需要执行的 sql 进行处理过滤判断。

这里说一下 checkquery 方法的处理判断 sql 的过程
  1.         function checkquery($sql) {
  2.                 static $status = null, $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');
  3.                 if($status === null) $status = getglobal('config/security/querysafe/status');
  4.                 if($status) {
  5.                         $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
  6.                         if(in_array($cmd, $checkcmd)) {
  7.                                 $test = DB::_do_query_safe($sql);
  8.                                 if($test < 1) DB::_execute('halt', 'security_error', $sql);
  9.                         }
  10.                 }
  11.                 return true;
  12.         }
复制代码
该方法定义了一个需要进行判断的 sql 语句的命令关键词的数组,并且 需要 config_global.php 里面 开启了安全 sql 过滤设置 即
  1. $_config['security']['querysafe']['status'] = 1;
复制代码
时,方法会调用一个内部的函数 _do_query_safe() (参考 class_core.php 文件中的该方法)对需要执行的 sql 进行安全检查

_do_query_safe 方法所要做的就是去掉一些 mysql 注释掉的字符串,去掉 sql 中被一对引号包含的字符串,去掉空格,然后对剩下的纯的sql 命令和字段等字符进行判断

_do_query_safe 首先过滤去掉被转义掉的 单号号,然后判断去掉转义掉的单号的sql 里面是否含有 mysql 的注释符等特殊符号

如果 sql 语句中不含有 mysql 注释符 则程序去掉一对单引号及其包含的起来的字符串

如果 sql 语句中含有一些 mysql 的注释符等字符串,程序就会对该条 sql 逐个字符的遍历,判断并处理去掉注释掉的内容,单引号中的内容

剩下的 sql 字符串使用
  1. $clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));
复制代码
去掉非常规的一些字符串

在该 _do_query_safe  方法最开始读取了config_global.php 中的 $_config['security']['querysafe'] 数组
  1.                 if(is_array($_CONFIG['dfunction'])) {
  2.                         foreach($_CONFIG['dfunction'] as $fun) {
  3.                                 if(strpos($clean, $fun.'(') !== false) return '-1';
  4.                         }
  5.                 }

  6.                 if(is_array($_CONFIG['daction'])) {
  7.                         foreach($_CONFIG['daction'] as $action) {
  8.                                 if(strpos($clean,$action) !== false) return '-3';
  9.                         }
  10.                 }

  11.                 if($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {
  12.                         return '-2';
  13.                 }

  14.                 if(is_array($_CONFIG['dnote'])) {
  15.                         foreach($_CONFIG['dnote'] as $note) {
  16.                                 if(strpos($clean,$note) !== false) return '-4';
  17.                         }
  18.                 }
复制代码
通过该数组对以上过滤处理后的sql 进行查找,是否存在  $_config['security']['querysafe']  数组中的危险的命令字符串

如果存在,则根据不同的类型的危险字符串,返回一个相应的负值

checkquery  就是根据该负值 来判断对 sql 执行 进行中断

这里需要注意的是 config_global.php 中安全设置必须为1
  1. $_config['security']['querysafe']['status'] = 1;
复制代码
才会判断安全性,所以平常需要检查 该文件是否被非法修改
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|Comsenz ( 粤B2-20090059-165 )star

GMT+8, 2019-10-20 13:52

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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