Home  >  Article  >  Backend Development  >  Solution to the problem of CI automatically filtering out the last two digits of percent sign _PHP tutorial

Solution to the problem of CI automatically filtering out the last two digits of percent sign _PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:34:01895browse

In the website made by CodeIgniter, I want to enter a piece of code:

$var = sprintf("%04d", 2);

But I found that after entering the library, the code changed to

$var = sprintf("d", 2);

I tested it in both online environment and local environment, and it was finally confirmed that it was a problem with the CodeIgniter system. Let’s talk about the problem-solving process and thinking methods:

1. Is it permitted_uri_chars of config.php?

$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';

I found several similar questions on stackoverflow, and some answers said that just change permitted_uri_chars in config.php.

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~%.:_+&-';

I tried it, but it didn’t work, so I looked for the code that applied $config['permitted_uri_chars'].

2. Is it a problem with the _clean_input_keys() function of core/Input.php?

	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;   
	} 

This function uses $config['permitted_uri_chars'] to directly filter the post data. The main reason is the culprit. I separated it and found after testing that post $var = sprintf("%04d", 2);, the result is still $var = sprintf("%04d", 2);, %04 has not been filtered, see You have to look for it carefully.

3. Is it a defense mechanism for xss?

Someone on stackoverflow said that he solved this problem perfectly and it was caused by 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

So I found the xss_clean() function under core/security.php. Comment out all the function body code and find that the input will still filter out %04, which is obviously not a problem with xss.

4. The problem lies in the _clean_input_data() function

Go back to Input.php and find that _clean_input_data is related to _clean_input_keys.

$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);

So I commented out the function body of _clean_input_data(), and the input was not filtered. Continuing to narrow down the scope, I found that this code was causing trouble:

// Remove control characters
// 就是这个会把%0x过滤掉
$str = remove_invisible_characters($str);

5. The culprit found the remove_invisible_characters() function

So what is the remove_invisible_characters() function?

This function is in core/Common.php, I pulled it out:

	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;
	}

Look at these lines of code:

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
}

Let’s be clear, it will filter out the three characters starting with %0 and %1. Just comment this out and the problem will be solved.

Record the entire thinking process of solving this problem.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/752355.htmlTechArticleIn the website made by CodeIgniter, I want to enter a piece of code: $var = sprintf("%04d", 2) ; But I found that after entering the library, the code became $var = sprintf("d", 2); In both the online environment and the local environment...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn