您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

CI自动过滤掉百分号%后两位的问题解决_PHP教程

2024/2/26 2:43:38发布34次查看
在 codeigniter 做的网站里,想输入一段代码:
$var = sprintf(%04d, 2);
但是发现入库后,代码变成了
$var = sprintf(d, 2);
在网上环境,本地环境都测试过,最终确认是 codeigniter 系统的问题。下面谈一下问题解决的过程与思维方法:
1. 是 config.php 的 permitted_uri_chars 吗?
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
在 stackoverflow 上找到几个差不多的问题,有答案说改 config.php 的 permitted_uri_chars 就行了。
ahem... after looking at your sample string again. here is why you get the uri you submitted has disallowed characters.
short explanation: add the ampersand & to the allowed characters list
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_+&-';
试过了,没效果,于是就查找应用了 $config['permitted_uri_chars'] 的代码。
2. 是 core/input.php 的 _clean_input_keys() 函数问题吗?
function _clean_input_keys($str) { $config = &get_config('config'); if ( ! preg_match(/^[.$config['permitted_uri_chars'].]+$/i, rawurlencode($str))) { exit('disallowed key characters.'); } // clean utf-8 if supported if (utf8_enabled === true) { $str = $this->uni->clean_string($str); } return $str; }
这个函数使用了 $config['permitted_uri_chars'] 直接过滤 post 过来的数据,很大原因就是元凶了。我把它单独出来,经过测试发现,post $var = sprintf(%04d, 2); 过来,结果还是 $var = sprintf(%04d, 2); ,%04并未被过滤,看来还得细细地找。
3. 是 xss 的防御机制吗?
stackoverflow 有个人说他完美解决了这个问题,是 xss clean 的原因。
:) god damn urldecode, i have looked at the code in uri.php but the xss clean is doing the job so i missed it. thank you now everything is perfect. – radum
于是我找到了 core/security.php 下的 xss_clean() 函数。把函数体代码全部注释掉,发现输入还是会把 %04 过滤掉,显然也不是 xss 的问题。
4. 问题出在 _clean_input_data() 函数
重新回到 input.php,发现 _clean_input_data 与 _clean_input_keys 有联系。
$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
于是把 _clean_input_data() 的函数体注释掉,竟然输入没被过滤了。继续缩小范围,发现是这段代码惹得祸:
// remove control characters// 就是这个会把%0x过滤掉$str = remove_invisible_characters($str);
5. 元凶找到了 remove_invisible_characters() 函数
那么 remove_invisible_characters() 这个函数是什么呢?
这个函数在 core/common.php中,我把它揪出来:
function remove_invisible_characters($str, $url_encoded = true) { $non_displayables = array(); // every control character except newline (dec 10) // carriage return (dec 13), and horizontal tab (dec 09) if ($url_encoded) { $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 } $non_displayables[] = '/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]+/s'; // 00-08, 11, 12, 14-31, 127 do { $str = preg_replace($non_displayables, '', $str, -1, $count); } while ($count); return $str; }
看这么几行代码:
if ($url_encoded){ $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31}
明确了吧,他会把%0与%1开头的3个字符过滤掉。直接把这个注释掉,问题解决。
记录这个问题解决的思维全过程。
http://www.bkjia.com/phpjc/752355.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/752355.htmltecharticle在 codeigniter 做的网站里,想输入一段代码: $var = sprintf(%04d, 2); 但是发现入库后,代码变成了 $var = sprintf(d, 2); 在网上环境,本地环境都...
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product