在 POST 期间编码的一些字符,而另一些则不是

Posted

技术标签:

【中文标题】在 POST 期间编码的一些字符,而另一些则不是【英文标题】:Some chars encoded during POST while others are not 【发布时间】:2013-12-03 13:45:49 【问题描述】:

TL;DR

CodeIgniters 的 Security 类直接操纵您的全局变量,例如 $_POST,它发现 file()file () 是一种威胁,因此它会对其进行 html 编码。

// config.php from my apps folder is the culprit
$config['global_xss_filtering'] = TRUE;

自己动手(少数,勇敢)

在 CodeIgniter 2.1.4 中转到 system/core/security.php 和第 #430-442 行:

/*
* Sanitize naughty scripting elements
*
* Similar to above, only instead of looking for
* tags it looks for PHP and javascript commands
* that are disallowed.  Rather than removing the
* code, it simply converts the parenthesis to entities
* rendering the code un-executable.
*
* For example:  eval('some code')
* Becomes:      eval('some code')
*/

$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str);

观察/问题

基本上,似乎 PHP 或 Apache 都将 file ()file() 视为威胁。

以前有没有人经历过这种情况或有文档资源来说明为什么会发生这种情况?

任何人都可以在他们的服务器上对此进行测试,看看他们是否遇到相同的行为吗?我已经在我的开发和测试机器上对此进行了测试。我没有机会在生产机器上进行测试,因为我们的客户连接到它。

代码

HTML

<input name="q1" type="text" value="Profile (61) (D)">
<input name="q2" type="text" value="(61) (D)">
<input name="q3" type="text" value="file (61)">
<input name="q4" type="text" value="fil (61)">
<input name="q5" type="text" value="file ()">
<input name="q6" type="text" value="file()">

JS - 可能无关

$.ajax(
    url: '/test_post'
    ,async: true
    ,cache: false
    ,type: 'POST'
    ,data: 
        q1: $('input[name="q1"]').val(),
        q2: $('input[name="q2"]').val(),
        q3: $('input[name="q3"]').val(),
        q4: $('input[name="q4"]').val(),
        q5: $('input[name="q5"]').val(),
        q6: $('input[name="q6"]').val()
    
    ,dataType: 'json'
    ,success: function(data)
        console.log('irrelevant');
    
);

网络 - Chrome 中的标题标签 - 表单数据部分

q1: Profile (61) (D)
q2: (61) (D)
q3: file (61)
q4: fil (61)
q5: file ()
q6: file()

PHP - CodeIgniter 2.1.4 框架

echo '<pre>'.$_POST['q1'].'</pre>'; // produces: Profile &#40;61&#41; (D)
echo '<pre>'.$_POST['q2'].'</pre>'; // produces: (61) (D)
echo '<pre>'.$_POST['q3'].'</pre>'; // produces: file &#40;61&#41;
echo '<pre>'.$_POST['q4'].'</pre>'; // produces: fil (61)
echo '<pre>'.$_POST['q5'].'</pre>'; // produces: file &#40;&#41;
echo '<pre>'.$_POST['q6'].'</pre>'; // produces: file&#40;&#41;

echo '<pre>'.html_entity_decode($_POST['q1']).'</pre>'; // produces: Profile (61) (D)
echo '<pre>'.html_entity_decode($_POST['q2']).'</pre>'; // produces: (61) (D)
echo '<pre>'.html_entity_decode($_POST['q3']).'</pre>'; // produces: file (61)
echo '<pre>'.html_entity_decode($_POST['q4']).'</pre>'; // produces: fil (61)
echo '<pre>'.html_entity_decode($_POST['q5']).'</pre>'; // produces: file ()
echo '<pre>'.html_entity_decode($_POST['q6']).'</pre>'; // produces: file()

// Both of these produce same exact result
echo '<pre>'.print_r($_POST, true).'</pre>';
echo '<pre>'.print_r($this->input->post(), true).'</pre>';

经过测试的浏览器

铬 31.0.1650.57 m IE 8 FF 25.0

服务器信息

开发

Widnows 7 x64 Apache 2.2.17 PHP 5.3.5

测试

Windows Server 2008 R2 x64 Apache 2.2.21 PHP 5.3.8

【问题讨论】:

q1q3 很有可能被视为潜在的恶意函数调用:Profile (61) 理论上可能是这样。所以这是我能想到的一个原因,为什么会发生这种情况。 @EduardLuca 感谢您的建议。我正在使用 q1 q2q3 对正在发布的各种文本组合进行视觉分离。无论哪个文本字段收到具有匹配 field () 模式的字符串,都会产生症状。 我会说(至少离开你的例子)模式是anystring ()。这(继续我之前的想法)是因为Profile (61)file (61)(这就是q1q3 被编码的原因)理论上可以是函数调用,而单独的(61) 不能(这就是为什么q2 没有被编码)。同样,不确定这是否是它这样做的原因,但它肯定是有道理的。 @EduardLuca 我在我的服务器上做了更多测试,请查看q4 q5q6。如果您想看其他内容,请告诉我。 你有全局启用 CodeIgniters Security 模块吗? 【参考方案1】:

根据user guide,可以通过设置去掉这个

$config['global_xss_filtering'] = FALSE;

或者只是删除这一行。

恕我直言,修改 $_POST 数组是设计上的失败,但你去吧。

【讨论】:

以上是关于在 POST 期间编码的一些字符,而另一些则不是的主要内容,如果未能解决你的问题,请参考以下文章

将 NSManagedObject 变成部分错误,其中一些字段为 nil,而另一些则不是

Python ASCII 编解码器在写入 CSV 期间无法编码字符错误

Reportviewer,一些报告打印,而另一些则不会

一些 CSV 单元格包含在“引号”中,而另一些则没有

实际项目中前后端传输字符串URL编解码过程中遇到的一些问题

Python,Docker - “ascii”编解码器无法编码字符