*/
$content = preg_replace("|body(\s*\{.*?\})|si", ".bodyclass\\1", $content);
$secremoveimg = "../images/" . _("sec_remove_eng.png");
/**
* Fix url('blah') declarations.
*/
$content = preg_replace("|url\(([\'\"])\s*\S+script\s*:.*?([\'\"])\)|si",
"url(\\1$secremoveimg\\2)", $content);
/**
* Fix url('https*://.*) declarations but only if $view_unsafe_images
* is false.
*/
if (!$view_unsafe_images){
$content = preg_replace("|url\(([\'\"])\s*https*:.*?([\'\"])\)|si",
"url(\\1$secremoveimg\\2)", $content);
}
/**
* Fix urls that refer to cid:
*/
while (preg_match("|url\(([\'\"]\s*cid:.*?[\'\"])\)|si", $content,
$matches)){
$cidurl = $matches{1};
$httpurl = sq_cid2http($message, $id, $cidurl);
$content = preg_replace("|url\($cidurl\)|si",
"url($httpurl)", $content);
}
/**
* Fix stupid css declarations which lead to vulnerabilities
* in IE.
*/
$match = Array('/expression/si',
'/behaviou*r/si',
'/binding/si');
$replace = Array('idiocy', 'idiocy', 'idiocy');
$content = preg_replace($match, $replace, $content);
return $content;
}
/**
* This function converts cid: url's into the ones that can be viewed in
* the browser.
*
* @param $message the message object
* @param $id the message id
* @param $cidurl the cid: url.
* @return a string with a http-friendly url
*/
function sq_cid2http($message, $id, $cidurl, $mailbox){
/**
* Get rid of quotes.
*/
$quotchar = substr($cidurl, 0, 1);
$cidurl = str_replace($quotchar, "", $cidurl);
$cidurl = substr(trim($cidurl), 4);
$httpurl = $quotchar . "../src/download.php?absolute_dl=true&" .
"passed_id=$id&mailbox=" . urlencode($mailbox) .
"&passed_ent_id=" . find_ent_id($cidurl, $message) . $quotchar;
return $httpurl;
}
/**
* This function changes the tag into a
tag since we
* can't really have a body-within-body.
*
* @param $attary an array of attributes and values of
* @return a modified array of attributes to be set for
*/
function sq_body2div($attary){
$me = "sq_body2div";
$divattary = Array("class"=>"'bodyclass'");
$bgcolor="#ffffff";
$text="#000000";
$styledef="";
if (is_array($attary) && sizeof($attary) > 0){
foreach ($attary as $attname=>$attvalue){
$quotchar = substr($attvalue, 0, 1);
$attvalue = str_replace($quotchar, "", $attvalue);
switch ($attname){
case "background":
$styledef .= "background-image: url('$attvalue'); ";
break;
case "bgcolor":
$styledef .= "background-color: $attvalue; ";
break;
case "text":
$styledef .= "color: $attvalue; ";
}
}
if (strlen($styledef) > 0){
$divattary{"style"} = "\"$styledef\"";
}
}
return $divattary;
}
/**
* This is the main function and the one you should actually be calling.
* There are several variables you should be aware of an which need
* special description.
*
* Since the description is quite lengthy, see it here:
* http://www.mricon.com/html/phpfilter.html
*
* @param $body the string with HTML you wish to filter
* @param $tag_list see description above
* @param $rm_tags_with_content see description above
* @param $self_closing_tags see description above
* @param $force_tag_closing see description above
* @param $rm_attnames see description above
* @param $bad_attvals see description above
* @param $add_attr_to_tag see description above
* @param $message message object
* @param $id message id
* @return sanitized html safe to show on your pages.
*/
function sq_sanitize($body,
$tag_list,
$rm_tags_with_content,
$self_closing_tags,
$force_tag_closing,
$rm_attnames,
$bad_attvals,
$add_attr_to_tag,
$message,
$id,
$mailbox
){
$me = "sq_sanitize";
/**
* Normalize rm_tags and rm_tags_with_content.
*/
@array_walk($rm_tags, 'sq_casenormalize');
@array_walk($rm_tags_with_content, 'sq_casenormalize');
@array_walk($self_closing_tags, 'sq_casenormalize');
/**
* See if tag_list is of tags to remove or tags to allow.
* false means remove these tags
* true means allow these tags
*/
$rm_tags = array_shift($tag_list);
$curpos = 0;
$open_tags = Array();
$trusted = "\n";
$skip_content = false;
/**
* Take care of netscape's stupid javascript entities like
* &{alert('boo')};
*/
$body = preg_replace("/&(\{.*?\};)/si", "&\\1", $body);
while (($curtag=sq_getnxtag($body, $curpos)) != FALSE){
list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;
$free_content = substr($body, $curpos, $lt-$curpos);
/**
* Take care of . Edit the
* content before we apply it.
*/
$free_content = sq_fixstyle($message, $id, $free_content);
}
if ($skip_content == false){
$trusted .= $free_content;
} else {
}
if ($tagname != FALSE){
if ($tagtype == 2){
if ($skip_content == $tagname){
/**
* Got to the end of tag we needed to remove.
*/
$tagname = false;
$skip_content = false;
} else {
if ($skip_content == false){
if ($tagname == "body"){
$tagname = "div";
} else {
if (isset($open_tags{$tagname}) &&
$open_tags{$tagname} > 0){
$open_tags{$tagname}--;
} else {
$tagname = false;
}
}
} else {
}
}
} else {
/**
* $rm_tags_with_content
*/
if ($skip_content == false){
/**
* See if this is a self-closing type and change
* tagtype appropriately.
*/
if ($tagtype == 1
&& in_array($tagname, $self_closing_tags)){
$tagtype=3;
}
/**
* See if we should skip this tag and any content
* inside it.
*/
if ($tagtype == 1 &&
in_array($tagname, $rm_tags_with_content)){
$skip_content = $tagname;
} else {
if (($rm_tags == false
&& in_array($tagname, $tag_list)) ||
($rm_tags == true &&
!in_array($tagname, $tag_list))){
$tagname = false;
} else {
if ($tagtype == 1){
if (isset($open_tags{$tagname})){
$open_tags{$tagname}++;
} else {
$open_tags{$tagname}=1;
}
}
/**
* This is where we run other checks.
*/
if (is_array($attary) && sizeof($attary) > 0){
$attary = sq_fixatts($tagname,
$attary,
$rm_attnames,
$bad_attvals,
$add_attr_to_tag,
$message,
$id,
$mailbox
);
}
/**
* Convert body into div.
*/
if ($tagname == "body"){
$tagname = "div";
$attary = sq_body2div($attary, $message, $id);
}
}
}
} else {
}
}
if ($tagname != false && $skip_content == false){
$trusted .= sq_tagprint($tagname, $attary, $tagtype);
}
} else {
}
$curpos = $gt+1;
}
$trusted .= substr($body, $curpos, strlen($body)-$curpos);
if ($force_tag_closing == true){
foreach ($open_tags as $tagname=>$opentimes){
while ($opentimes > 0){
$trusted .= '' . $tagname . '>';
$opentimes--;
}
}
$trusted .= "\n";
}
$trusted .= "\n";
return $trusted;
}
/**
* This is a wrapper function to call html sanitizing routines.
*
* @param $body the body of the message
* @param $id the id of the message
* @return a string with html safe to display in the browser.
*/
function magicHTML($body, $id, $message, $mailbox = 'INBOX'){
global $attachment_common_show_images, $view_unsafe_images,
$has_unsafe_images;
/**
* Don't display attached images in HTML mode.
*/
$attachment_common_show_images = false;
$tag_list = Array(
false,
"object",
"meta",
"html",
"head",
"base",
"link"
);
$rm_tags_with_content = Array(
"script",
"applet",
"embed",
"title"
);
$self_closing_tags = Array(
"img",
"br",
"hr",
"input"
);
$force_tag_closing = false;
$rm_attnames = Array(
"/.*/" =>
Array(
"/target/si",
"/^on.*/si",
"/^dynsrc/si",
"/^data.*/si"
)
);
$secremoveimg = "../images/" . _("sec_remove_eng.png");
$bad_attvals = Array(
"/.*/" =>
Array(
"/^src|background/i" =>
Array(
Array(
"|^([\'\"])\s*\.\./.*([\'\"])|si",
"/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
"/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
"/^([\'\"])\s*about\s*:.*([\'\"])/si"
),
Array(
"\\1$secremoveimg\\2",
"\\1$secremoveimg\\2",
"\\1$secremoveimg\\2",
"\\1$secremoveimg\\2"
)
),
"/^href|action/i" =>
Array(
Array(
"|^([\'\"])\s*\.\./.*([\'\"])|si",
"/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
"/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
"/^([\'\"])\s*about\s*:.*([\'\"])/si"
),
Array(
"\\1#\\2",
"\\1#\\2",
"\\1#\\2",
"\\1#\\2"
)
),
"/^style/si" =>
Array(
Array(
"/expression/si",
"/binding/si",
"/behaviou*r/si",
"|url\(([\'\"])\s*\.\./.*([\'\"])\)|si",
"/url\(([\'\"])\s*\S+script\s*:.*([\'\"])\)/si",
"/url\(([\'\"])\s*mocha\s*:.*([\'\"])\)/si",
"/url\(([\'\"])\s*about\s*:.*([\'\"])\)/si"
),
Array(
"idiocy",
"idiocy",
"idiocy",
"url(\\1#\\2)",
"url(\\1#\\2)",
"url(\\1#\\2)",
"url(\\1#\\2)"
)
)
)
);
if (!$view_unsafe_images){
/**
* Remove any references to http/https if view_unsafe_images set
* to false.
*/
array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[0],
'/^([\'\"])\s*https*:.*([\'\"])/si');
array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1],
"\\1$secremoveimg\\2");
array_push($bad_attvals{'/.*/'}{'/^style/si'}[0],
'/url\(([\'\"])\s*https*:.*([\'\"])\)/si');
array_push($bad_attvals{'/.*/'}{'/^style/si'}[1],
"url(\\1$secremoveimg\\2)");
}
$add_attr_to_tag = Array(
"/^a$/si" => Array('target'=>'"_new"')
);
$trusted = sq_sanitize($body,
$tag_list,
$rm_tags_with_content,
$self_closing_tags,
$force_tag_closing,
$rm_attnames,
$bad_attvals,
$add_attr_to_tag,
$message,
$id,
$mailbox
);
if (preg_match("|$secremoveimg|si", $trusted)){
$has_unsafe_images = true;
}
return $trusted;
}
?>