161 lines
4.6 KiB
PHP
161 lines
4.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* XssSafe Helper - Clean cross site scripting exploits from string
|
|
*
|
|
* @package symfony
|
|
* @subpackage plugin
|
|
* @author Alexandre Mogère
|
|
*
|
|
* @uses <a href="http://htmlpurifier.org/">HTML Purifier</a>
|
|
*/
|
|
|
|
require_once(sfConfig::get('sf_plugins_dir') . '/sfXssSafePlugin/lib/vendor/htmlpurifier/HTMLPurifier.auto.php');
|
|
|
|
/**
|
|
* The function runs HTML Purifier as an alternative between
|
|
* escaping raw and escaping entities.
|
|
*
|
|
* @param string $dirty_html the value to clean
|
|
* @return string the escaped value
|
|
*/
|
|
function esc_xsssafe($dirty_html)
|
|
{
|
|
if (!$dirty_html)
|
|
{
|
|
return '';
|
|
}
|
|
|
|
set_error_handler('XssSafeErrorHandler');
|
|
|
|
static $purifier = false;
|
|
|
|
if (!$purifier)
|
|
{
|
|
$hasCustom = false;
|
|
$aElements = array();
|
|
$aAttributes = array();
|
|
|
|
// sets configuration
|
|
$config = HTMLPurifier_Config::createDefault();
|
|
|
|
$definitions = sfConfig::get('app_sfXssSafePlugin_definition');
|
|
if (!empty($definitions))
|
|
{
|
|
foreach ($definitions as $def => $conf)
|
|
{
|
|
if (!empty($conf))
|
|
{
|
|
foreach ($conf as $directive => $values)
|
|
{
|
|
if ($def == 'AutoFormat' && $directive != 'Custom')
|
|
{
|
|
// customizable elements
|
|
if ($directive == 'Element')
|
|
{
|
|
$aElements = $values;
|
|
} // customizable attributes
|
|
elseif ($directive == 'Attribute')
|
|
{
|
|
$aAttributes = $values;
|
|
}
|
|
$hasCustom = true;
|
|
}
|
|
else
|
|
{
|
|
if (($def == 'AutoFormat' && $directive == 'Custom') &&
|
|
!class_exists("HTMLPurifier_Injector_$values"))
|
|
{
|
|
continue;
|
|
}
|
|
$config->set("$def.$directive", $values);
|
|
// $values can be a string or an ArrayList
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SF_ENVIRONMENT == 'dev' || SF_ENVIRONMENT == 'test')
|
|
{
|
|
// turns off cache
|
|
$config->set('Cache.DefinitionImpl', null);
|
|
}
|
|
else
|
|
{
|
|
// sets the cache directory into Symfony cache directory
|
|
$config->set('Cache.SerializerPath', sfConfig::get('sf_cache_dir'));
|
|
}
|
|
|
|
if ($hasCustom)
|
|
{
|
|
$def =& $config->getHTMLDefinition(true);
|
|
|
|
// adds custom elements
|
|
if (!empty($aElements))
|
|
{
|
|
foreach ($aElements as $name => $element)
|
|
{
|
|
$name = strtolower($name);
|
|
${$name} =& $def->addElement(
|
|
$name,
|
|
$element['type'],
|
|
$element['contents'],
|
|
$element['attr_includes'],
|
|
$element['attr']
|
|
);
|
|
$factory = 'HTMLPurifier_AttrTransform_' . ucfirst($name) . 'Validator';
|
|
if (class_exists($factory))
|
|
{
|
|
${$name}->attr_transform_post[] = new $factory();
|
|
}
|
|
}
|
|
}
|
|
|
|
// adds custom attributs
|
|
if (!empty($aAttributes))
|
|
{
|
|
foreach ($aAttributes as $name => $attr)
|
|
{
|
|
$name = strtolower($name);
|
|
${$name} =& $def->addAttribute(
|
|
$name,
|
|
$attr['attr_name'],
|
|
$attr['def']
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
$purifier = new HTMLPurifier($config);
|
|
}
|
|
|
|
$clean_html = $purifier->purify($dirty_html);
|
|
|
|
restore_error_handler();
|
|
return $clean_html;
|
|
}
|
|
|
|
define('ESC_XSSSAFE', 'esc_xsssafe');
|
|
|
|
/**
|
|
* Error handler.
|
|
*
|
|
* @param mixed Error number
|
|
* @param string Error message
|
|
* @param string Error file
|
|
* @param mixed Error line
|
|
*/
|
|
function XssSafeErrorHandler($errno, $errstr, $errfile, $errline)
|
|
{
|
|
if (($errno & error_reporting()) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
throw new sfException(sprintf('{XssSafeHelper} Error at %s line %s (%s)',
|
|
$errfile,
|
|
$errline,
|
|
$errstr)
|
|
);
|
|
} |