Files
2025-03-12 17:06:23 +01:00

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