Some chars encoded during POST while others are not

codeigniter, forms, html-encode, php, xss

Solution

According to the user guide, you can get rid of this by setting

$config['global_xss_filtering'] = FALSE;

Or just remove this line.

IMHO, it's a design failure to modify the `$_POST` array, but there you go.

Problem

TL;DR CodeIgniters' Security Class directly manipulates your Globals such as `$_POST` and it finds `file()` and `file ()` to be a threat so it HTML encodes it. ``` // config.php from my apps folder is the culprit $config['global_xss_filtering'] = TRUE; ``` Do-It-Yourself (the few, the brave) In CodeIgniter 2.1.4 go to `system/core/security.php` and line #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&#40;'some code'&#41; */ $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str); ``` Observation/question Basically, it seems as though either PHP or Apache sees `file ()` or `file()` as a threat. Has anyone experienced this before or have documentation resources as to why this occurs? Can anyone test this on their server to see if they experience the same behavior? I have tested this on both my Development and Testing machines. I have not had a chance to test on the Production machine because our clients connect to it. Code 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 - probably irrelevant ``` $.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'); } }); ``` Network - Headers tab in Chrome - Form Data section ``` q1: Profile (61) (D) q2: (61) (D) q3: file (61) q4: fil (61) q5: file () q6: file() ``` PHP - CodeIgniter 2.1.4 Framework ``` 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>'; ``` Browsers tested - Chrome 31.0.1650.57 m - IE 8 - FF 25.0 Server Information Dev - Widnows 7 x64 - Apache 2.2.17 - PHP 5.3.5 Testing - Windows Server 2008 R2 x64 - Apache 2.2.21 - PHP 5.3.8

Original source