设为首页收藏本站

Discuz! 官方站

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 7201|回复: 4

[已解决] 发现了一个重大问题,Discuz!x3.2跟Ucenter1.6.0的BUG

[复制链接]
发表于 2014-11-14 09:50:56 | 显示全部楼层 |阅读模式
本帖最后由 jshnr006 于 2014-11-14 09:51 编辑

最近搭建Discuz!x3.2和Ucenter1.6.0的时候,发现经常报通知失败,跟踪发现Discuz!x2.5是不存在该问题的,原因是 source/class/discuz/discuz_application.php
该文件有一个校验函数叫 _xss_check

下面是源码
Discuz!x2.5
  1. private function _xss_check() {
  2.                 $temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));
  3.                 if(strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false) {
  4.                         system_error('request_tainting');
  5.                 }
  6.                 return true;
  7.         }
复制代码
Discuz!x3.2
  1. private function _xss_check() {

  2.                 static $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');

  3.                 if(isset($_GET['formhash']) && $_GET['formhash'] !== formhash()) {
  4.                         system_error('request_tainting');
  5.                 }

  6.                 if($_SERVER['REQUEST_METHOD'] == 'GET' ) {
  7.                         $temp = $_SERVER['REQUEST_URI'];
  8.                 } elseif(empty ($_GET['formhash'])) {
  9.                         $temp = $_SERVER['REQUEST_URI'].file_get_contents('php://input');
  10.                 } else {
  11.                         $temp = '';
  12.                 }

  13.                 if(!empty($temp)) {
  14.                         $temp = strtoupper(urldecode(urldecode($temp)));
  15.                         foreach ($check as $str) {
  16.                                 if(strpos($temp, $str) !== false) {
  17.                                         system_error('request_tainting');
  18.                                 }
  19.                         }
  20.                 }

  21.                 return true;
  22.         }
复制代码
对比发现,新版代码的问题在 $temp = $_SERVER['REQUEST_URI'].file_get_contents('php://input'); ,如果是Ucenter下发的通知
$temp拿到的数据是 get的数据和post的数据
因为ucenter 发的post数据是xml格式, 所以下面的检测是肯定会走到 system_error('request_tainting');的
  1. foreach ($check as $str) {
  2. if(strpos($temp, $str) !== false) {
  3. system_error('request_tainting');
  4. }
复制代码
因为$check包含了 '<'  '>' 这些符号
  1. static $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');
复制代码



发表于 2014-11-14 09:54:12 | 显示全部楼层
是跨站检测脚本哦
回复

使用道具 举报

 楼主| 发表于 2014-11-14 09:55:55 | 显示全部楼层
crx349 发表于 2014-11-14 09:54
是跨站检测脚本哦

关键是他检测post数据 不可以有 < >符号,而ucenter发送的通知是xml 肯定有 < >符号的,所以ucenter一直都通知失败 懂吗
回复

使用道具 举报

发表于 2014-11-14 10:12:55 | 显示全部楼层
那问题来了,咋解决?
回复

使用道具 举报

 楼主| 发表于 2014-11-14 10:26:10 | 显示全部楼层
wengongling 发表于 2014-11-14 10:12
那问题来了,咋解决?

我的办法是 既然这个函数是用来检测跨网站的 那忽略 post的数据也是没问题的

$temp = $_SERVER['REQUEST_URI'].file_get_contents('php://input');
改为
$temp = $_SERVER['REQUEST_URI'];
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2018-8-19 13:16

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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