[eluser]Unknown[/eluser]
Nice one Jerry, works for me. For clarification of the process...
Create a file named MY_Controller.php in your [codeigniter]/application/core folder,
then place the following content into it...
Code:
<?php
/**
* MY_Security Class - extends CI standard Security controller
*
* This update removes the adding of semi-colons to submitted POST
* data if the data contains an ampersand & and the word after the
* ampersand doesn't match a known HTML entity
*
* @package CodeIgniter
*/
class MY_Security extends CI_Security {
public function __construct()
{
parent::__construct();
}
/**
* Validate URL entities
*
* Called by xss_clean()
*
* @param string
* @return string
*/
protected function _validate_entities($str)
{
/*
* Protect GET variables in URLs
*/
// 901119URL5918AMP18930PROTECT8198
$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
/*
* Validate standard character entities
*
* Add a semicolon if missing. We do this to enable
* the conversion of entities to ASCII later.
*
*/
// $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
// hArpanet.com: new bit coming up (in place of above line)...
// this code prevents a ; being added to string after an & unless that string matches a known HTML entity
// code taken from: http://ellislab.com/forums/viewreply/954778/
$matched = preg_match_all('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', $str, $matches, PREG_OFFSET_CAPTURE);
if ($matched > 0)
{
foreach($matches[0] as $match)
{
$test_str = strtolower($match[0].';');
foreach (get_html_translation_table(HTML_ENTITIES) as $entity)
{
if ($test_str == strtolower($entity))
$str = substr_replace($str, $entity, $match[1], strlen($match[0]));
}
}
}
// hArpanet.com: end of new bit
/*
* Validate UTF16 two byte encoding (x00)
*
* Just as above, adds a semicolon if missing.
*
*/
$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
/*
* Un-Protect GET variables in URLs
*/
$str = str_replace($this->xss_hash(), '&', $str);
return $str;
}
}
NOTE: As you can see, this only updates the checks on non-UTF16 values. If you want to disable ; addition on UTF16 values then apply Jerry's code to that string also.