[eluser]darkhouse[/eluser]
Before I get into the fix, let me explain the situation. A client's site was hacked. We're not sure how, or when. The hack seems to seek out </body> tags and insert some bogus javascript that loads an iframe which could load another site, or even a virus download. So, while the client is dealing with their server techs to obliterate the culprit (or decide to change servers altogether) I added a mod to CI to at least keep these hacks away from their users.
The hack seems to always put its bogus javascript in some odd tags such as <ad>, <b1>, <bb2>, etc. I've added a new config item, and then extended the Loader class and added a new method into it.
Here's the config item:
Code:
/*
|--------------------------------------------------------------------------
| Deny Tags
|--------------------------------------------------------------------------
|
| If your site gets hacked or hijacked, this will remove commonly injected
| tags from your output. Ideally you'll want to remove the malicious tags
| from your code, change your ftp passwords, and possibly change servers
| if it's the server that's infected. But at least this will keep your
| users safe.
|
*/
$config['deny_tags'] = array('ad', 'b1', 'b2', 'bb1', 'bb2');
The new method I added into the MY_Loader class is this:
Code:
function clean_output($buffer){
if(config_item('deny_tags')){
foreach(config_item('deny_tags') as $tag){
$buffer = preg_replace('/<'.$tag.'>.+<\/'.$tag.'>/is', '', $buffer);
}
}
return $buffer;
}
And then finally I copied the _ci_load method from the Loader class and modified a couple lines near the end. I'll just paste the last couple blocks of code where I made my changes here:
Code:
// Return the file data if requested
if ($_ci_return === TRUE)
{
$buffer = $this->clean_output(ob_get_contents()); //added clean_output method
@ob_end_clean();
return $buffer;
}
/*
* Flush the buffer... or buff the flusher?
*
* In order to permit views to be nested within
* other views, we need to flush the content back out whenever
* we are beyond the first level of output buffering so that
* it can be seen and included properly by the first included
* template and any subsequent ones. Oy!
*
*/
if (ob_get_level() > $this->_ci_ob_level + 1)
{
ob_end_flush();
}
else
{
// PHP 4 requires that we use a global
global $OUT;
$OUT->append_output($this->clean_output(ob_get_contents())); //added clean_output method
@ob_end_clean();
}
Be advised, this is a band-aid solution. It's just to keep the display clean so your users aren't violated while the real problem is flushed out.