/** * This function takes a string with an html tag and strips out any unallowed * protocols e.g. javascript: * * It calls ancillary functions in kses which are prefixed by kses * * @global object * @global string * @param array $htmlArray An array from {@link cleanAttributes()}, containing in its 1st * element the html to be cleared * @return string */ function cleanAttributes2($htmlArray) { global $CFG, $ALLOWED_PROTOCOLS; require_once $CFG->libdir . '/kses.php'; $htmlTag = $htmlArray[1]; if (substr($htmlTag, 0, 1) != '<') { return '>'; //a single character ">" detected } if (!preg_match('%^<\\s*(/\\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $htmlTag, $matches)) { return ''; // It's seriously malformed } $slash = trim($matches[1]); //trailing xhtml slash $elem = $matches[2]; //the element name $attrlist = $matches[3]; // the list of attributes as a string $attrArray = kses_hair($attrlist, $ALLOWED_PROTOCOLS); $attStr = ''; foreach ($attrArray as $arreach) { $arreach['name'] = strtolower($arreach['name']); if ($arreach['name'] == 'style') { $value = $arreach['value']; while (true) { $prevvalue = $value; $value = kses_no_null($value); $value = preg_replace("/\\/\\*.*\\*\\//Us", '', $value); $value = kses_decode_entities($value); $value = preg_replace('/(&#[0-9]+)(;?)/', "\\1;", $value); $value = preg_replace('/(&#x[0-9a-fA-F]+)(;?)/', "\\1;", $value); if ($value === $prevvalue) { $arreach['value'] = $value; break; } } $arreach['value'] = preg_replace("/j\\s*a\\s*v\\s*a\\s*s\\s*c\\s*r\\s*i\\s*p\\s*t/i", "Xjavascript", $arreach['value']); $arreach['value'] = preg_replace("/v\\s*b\\s*s\\s*c\\s*r\\s*i\\s*p\\s*t/i", "Xvbscript", $arreach['value']); $arreach['value'] = preg_replace("/e\\s*x\\s*p\\s*r\\s*e\\s*s\\s*s\\s*i\\s*o\\s*n/i", "Xexpression", $arreach['value']); $arreach['value'] = preg_replace("/b\\s*i\\s*n\\s*d\\s*i\\s*n\\s*g/i", "Xbinding", $arreach['value']); } else { if ($arreach['name'] == 'href') { //Adobe Acrobat Reader XSS protection $arreach['value'] = preg_replace('/(\\.(pdf|fdf|xfdf|xdp|xfd)[^#]*)#.*$/i', '$1', $arreach['value']); } } $attStr .= ' ' . $arreach['name'] . '="' . $arreach['value'] . '"'; } $xhtml_slash = ''; if (preg_match('%/\\s*$%', $attrlist)) { $xhtml_slash = ' /'; } return '<' . $slash . $elem . $attStr . $xhtml_slash . '>'; }
function kses_attr($element, $attr, $allowed_html, $allowed_protocols) { # Is there a closing XHTML slash at the end of the attributes? $xhtml_slash = ''; if (preg_match('%\\s/\\s*$%', $attr)) { $xhtml_slash = ' /'; } # Are any attributes allowed at all for this element? if (@count($allowed_html[strtolower($element)]) == 0) { return "<{$element}{$xhtml_slash}>"; } # Split it $attrarr = kses_hair($attr, $allowed_protocols); # Go through $attrarr, and save the allowed attributes for this element # in $attr2 $attr2 = ''; foreach ($attrarr as $arreach) { if (!@isset($allowed_html[strtolower($element)][strtolower($arreach['name'])])) { continue; } # the attribute is not allowed $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; if (!is_array($current)) { $attr2 .= ' ' . $arreach['whole']; } else { # there are some checks $ok = true; foreach ($current as $currkey => $currval) { if (!kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { $ok = false; break; } } if ($ok) { $attr2 .= ' ' . $arreach['whole']; } # it passed them } # if !is_array($current) } # foreach # Remove any "<" or ">" characters $attr2 = preg_replace('/[<>]/', '', $attr2); return "<{$element}{$attr2}{$xhtml_slash}>"; }
/** * This function removes all attributes, if none are allowed for this element. * * If some are allowed it calls kses_hair() to split them further, and then * it builds up new HTML code from the data that kses_hair() returns. It also * removes "<" and ">" characters, if there are any left. One more thing it does * is to check if the tag has a closing XHTML slash, and if it does, it puts one * in the returned code as well. * * @param string $element HTML element/tag * @param string $attr HTML attributes from HTML element to closing HTML element tag * @param array $allowed_html Allowed HTML elements * @param array $allowed_protocols Allowed protocols to keep * @return string Sanitized HTML element */ function kses_attr($element, $attr, $allowed_html, $allowed_protocols) { // Is there a closing XHTML slash at the end of the attributes? $xhtml_slash = ''; if (preg_match('%\\s*/\\s*$%', $attr)) { $xhtml_slash = ' /'; } // Are any attributes allowed at all for this element? if (@count($allowed_html[strtolower($element)]) == 0) { return "<{$element}{$xhtml_slash}>"; } // Split it $attrarr = kses_hair($attr, $allowed_protocols); // Go through $attrarr, and save the allowed attributes for this element // in $attr2 $attr2 = ''; foreach ($attrarr as $arreach) { if (!@isset($allowed_html[strtolower($element)][strtolower($arreach['name'])])) { continue; } // the attribute is not allowed $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; if ($current == '') { continue; } // the attribute is not allowed if (!is_array($current)) { $attr2 .= ' ' . $arreach['whole']; } else { // there are some checks $ok = true; foreach ($current as $currkey => $currval) { if (!kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { $ok = false; break; } } if (strtolower($arreach['name']) == 'style') { $orig_value = $arreach['value']; $value = kses_safecss_filter_attr($orig_value); if (empty($value)) { continue; } $arreach['value'] = $value; $arreach['whole'] = str_replace($orig_value, $value, $arreach['whole']); } if ($ok) { $attr2 .= ' ' . $arreach['whole']; } // it passed them } // if !is_array($current) } // foreach // Remove any "<" or ">" characters $attr2 = preg_replace('/[<>]/', '', $attr2); return "<{$element}{$attr2}{$xhtml_slash}>"; }
/** * This function takes a string with an html tag and strips out any unallowed * protocols e.g. javascript: * It calls ancillary functions in kses which are prefixed by kses * 17/08/2004 :: Eamon DOT Costello AT dcu DOT ie * * @param array $htmlArray An array from {@link cleanAttributes()}, containing in its 1st * element the html to be cleared * @return string */ function cleanAttributes2($htmlArray) { global $CFG, $ALLOWED_PROTOCOLS; require_once $CFG->libdir . '/kses.php'; $htmlTag = $htmlArray[1]; if (substr($htmlTag, 0, 1) != '<') { return '>'; //a single character ">" detected } if (!preg_match('%^<\\s*(/\\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $htmlTag, $matches)) { return ''; // It's seriously malformed } $slash = trim($matches[1]); //trailing xhtml slash $elem = $matches[2]; //the element name $attrlist = $matches[3]; // the list of attributes as a string $attrArray = kses_hair($attrlist, $ALLOWED_PROTOCOLS); $attStr = ''; foreach ($attrArray as $arreach) { $attStr .= ' ' . strtolower($arreach['name']) . '="' . $arreach['value'] . '" '; } // Remove last space from attribute list $attStr = rtrim($attStr); $xhtml_slash = ''; if (preg_match('%/\\s*$%', $attrlist)) { $xhtml_slash = ' /'; } return '<' . $slash . $elem . $attStr . $xhtml_slash . '>'; }
function kses_attr($element, $attr, $allowed_html, $allowed_protocols) { ############################################################################### # This function removes all attributes, if none are allowed for this element. # If some are allowed it calls kses_hair() to split them further, and then it # builds up new HTML code from the data that kses_hair() returns. It also # removes "<" and ">" characters, if there are any left. One more thing it # does is to check if the tag has a closing XHTML slash, and if it does, # it puts one in the returned code as well. ############################################################################### # Is there a closing XHTML slash at the end of the attributes? $xhtml_slash = ''; if (preg_match('%\\s/\\s*$%', $attr)) { $xhtml_slash = ' /'; } # Are any attributes allowed at all for this element? if (@count($allowed_html[strtolower($element)]) == 0) { return "<{$element}{$xhtml_slash}>"; } # Split it $attrarr = kses_hair($attr, $allowed_protocols); # Go through $attrarr, and save the allowed attributes for this element # in $attr2 $attr2 = ''; foreach ($attrarr as $arreach) { if (!@isset($allowed_html[strtolower($element)][strtolower($arreach['name'])])) { continue; } # the attribute is not allowed $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; if (!is_array($current)) { $attr2 .= ' ' . $arreach['whole']; } else { # there are some checks $ok = true; foreach ($current as $currkey => $currval) { if (!kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { $ok = false; break; } } if ($ok) { $attr2 .= ' ' . $arreach['whole']; } # it passed them } # if !is_array($current) } # foreach # Remove any "<" or ">" characters $attr2 = preg_replace('/[<>]/', '', $attr2); return "<{$element}{$attr2}{$xhtml_slash}>"; }