Lines 847-852
Link Here
|
847 |
/** |
847 |
/** |
848 |
** HTMLFILTER ROUTINES |
848 |
** HTMLFILTER ROUTINES |
849 |
*/ |
849 |
*/ |
|
|
850 |
function sq_unbackslash($attvalue){ |
851 |
/** |
852 |
* Remove any backslashes. See if there are any first. |
853 |
*/ |
854 |
|
855 |
if (strstr($attvalue, '\\') !== false){ |
856 |
$attvalue = stripslashes($attvalue); |
857 |
} |
858 |
return $attvalue; |
859 |
} |
850 |
|
860 |
|
851 |
/** |
861 |
/** |
852 |
* This function checks attribute values for entity-encoded values |
862 |
* This function checks attribute values for entity-encoded values |
Lines 1301-1325
Link Here
|
1301 |
* @param $hex whether the entites are hexadecimal. |
1311 |
* @param $hex whether the entites are hexadecimal. |
1302 |
* @return True or False depending on whether there were matches. |
1312 |
* @return True or False depending on whether there were matches. |
1303 |
*/ |
1313 |
*/ |
1304 |
function sq_deent(&$attvalue, $regex, $hex=false){ |
1314 |
function sq_deent($attvalue){ |
1305 |
$me = 'sq_deent'; |
1315 |
$me = 'sq_deent'; |
1306 |
$ret_match = false; |
1316 |
/** |
1307 |
preg_match_all($regex, $attvalue, $matches); |
1317 |
* See if we have to run the checks first. All entities must start |
1308 |
if (is_array($matches) && sizeof($matches[0]) > 0){ |
1318 |
* with "&". |
1309 |
$repl = Array(); |
1319 |
*/ |
1310 |
for ($i = 0; $i < sizeof($matches[0]); $i++){ |
1320 |
if (strpos($attvalue, '&') === false){ |
1311 |
$numval = $matches[1][$i]; |
1321 |
return $attvalue; |
1312 |
if ($hex){ |
|
|
1313 |
$numval = hexdec($numval); |
1314 |
} |
1322 |
} |
1315 |
$repl{$matches[0][$i]} = chr($numval); |
1323 |
/** |
|
|
1324 |
* Check named entities first. |
1325 |
*/ |
1326 |
$trans = get_html_translation_table(HTML_ENTITIES); |
1327 |
/** |
1328 |
* Leave " in, as it can mess us up. |
1329 |
*/ |
1330 |
$trans = array_flip($trans); |
1331 |
unset($trans{'"'}); |
1332 |
while (list($ent, $val) = each($trans)){ |
1333 |
$attvalue = preg_replace('/' . $ent . '*/si', $val, $attvalue); |
1316 |
} |
1334 |
} |
1317 |
$attvalue = strtr($attvalue, $repl); |
1335 |
/** |
1318 |
return true; |
1336 |
* Now translate numbered entities from 1 to 255 if needed. |
1319 |
} else { |
1337 |
*/ |
1320 |
return false; |
1338 |
if (strpos($attvalue, '#') !== false){ |
|
|
1339 |
$omit = Array(34, 39); |
1340 |
for ($asc = 256; $asc >= 0; $asc--){ |
1341 |
if (!in_array($asc, $omit)){ |
1342 |
$chr = chr($asc); |
1343 |
$octrule = '/\�*' . $asc . ';*/si'; |
1344 |
$hexrule = '/\�*' . dechex($asc) . ';*/si'; |
1345 |
$attvalue = preg_replace($octrule, $chr, $attvalue); |
1346 |
$attvalue = preg_replace($hexrule, $chr, $attvalue); |
1321 |
} |
1347 |
} |
1322 |
} |
1348 |
} |
|
|
1349 |
} |
1350 |
return $attvalue; |
1351 |
} |
1323 |
|
1352 |
|
1324 |
/** |
1353 |
/** |
1325 |
* This function runs various checks against the attributes. |
1354 |
* This function runs various checks against the attributes. |
Lines 1436-1462
Link Here
|
1436 |
/** |
1465 |
/** |
1437 |
* Fix url('blah') declarations. |
1466 |
* Fix url('blah') declarations. |
1438 |
*/ |
1467 |
*/ |
1439 |
$content = preg_replace("|url\s*\(\s*([\'\"])\s*\S+script\s*:.*?([\'\"])\s*\)|si", |
1468 |
// remove NUL |
1440 |
"url(\\1$secremoveimg\\2)", $content); |
1469 |
$content = str_replace("\0", "", $content); |
|
|
1470 |
// NB I insert NUL characters to keep to avoid an infinite loop. They are removed after the loop. |
1471 |
while (preg_match("/url\s*\(\s*[\'\"]?([^:]+):(.*)?[\'\"]?\s*\)/si", $content, $matches)) { |
1472 |
$sProto = strtolower($matches[1]); |
1473 |
switch ($sProto) { |
1441 |
/** |
1474 |
/** |
1442 |
* Fix url('https*://.*) declarations but only if $view_unsafe_images |
1475 |
* Fix url('https*://.*) declarations but only if $view_unsafe_images |
1443 |
* is false. |
1476 |
* is false. |
1444 |
*/ |
1477 |
*/ |
|
|
1478 |
case 'https': |
1479 |
case 'http': |
1445 |
if (!$view_unsafe_images){ |
1480 |
if (!$view_unsafe_images){ |
1446 |
$content = preg_replace("|url\s*\(\s*([\'\"])\s*https*:.*?([\'\"])\s*\)|si", |
1481 |
$content = preg_replace("|url\s*\(\s*([\'\"])\s*https*:.*?([\'\"])\s*\)|si", |
1447 |
"url(\\1$secremoveimg\\2)", $content); |
1482 |
"u\0r\0l(\\1$secremoveimg\\2)", $content); |
1448 |
} |
1483 |
} |
1449 |
|
1484 |
break; |
1450 |
/** |
1485 |
/** |
1451 |
* Fix urls that refer to cid: |
1486 |
* Fix urls that refer to cid: |
1452 |
*/ |
1487 |
*/ |
1453 |
while (preg_match("|url\s*\(\s*([\'\"]\s*cid:.*?[\'\"])\s*\)|si", |
1488 |
case 'cid': |
1454 |
$content, $matches)){ |
1489 |
$cidurl = 'cid:'. $matches[2]; |
1455 |
$cidurl = $matches{1}; |
|
|
1456 |
$httpurl = sq_cid2http($message, $id, $cidurl, $mailbox); |
1490 |
$httpurl = sq_cid2http($message, $id, $cidurl, $mailbox); |
1457 |
$content = preg_replace("|url\s*\(\s*$cidurl\s*\)|si", |
1491 |
$content = preg_replace("|url\s*\(\s*$cidurl\s*\)|si", |
1458 |
"url($httpurl)", $content); |
1492 |
"u\0r\0l($httpurl)", $content); |
|
|
1493 |
break; |
1494 |
default: |
1495 |
/** |
1496 |
* replace url with protocol other then the white list |
1497 |
* http,https and cid by an empty string. |
1498 |
*/ |
1499 |
$content = preg_replace("/url\s*\(\s*[\'\"]?([^:]+):(.*)?[\'\"]?\s*\)/si", |
1500 |
"", $content); |
1501 |
break; |
1502 |
} |
1503 |
break; |
1459 |
} |
1504 |
} |
|
|
1505 |
// remove NUL |
1506 |
$content = str_replace("\0", "", $content); |
1507 |
|
1508 |
/** |
1509 |
* Remove any backslashes, entities, and extraneous whitespace. |
1510 |
*/ |
1511 |
$contentTemp = sq_unbackslash($content); |
1512 |
$contentTemp = sq_deent($contentTemp); |
1513 |
$contentTemp = sq_unspace($contentTemp); |
1460 |
|
1514 |
|
1461 |
/** |
1515 |
/** |
1462 |
* Fix stupid css declarations which lead to vulnerabilities |
1516 |
* Fix stupid css declarations which lead to vulnerabilities |
Lines 1467-1473
Link Here
|
1467 |
'/binding/i', |
1521 |
'/binding/i', |
1468 |
'/include-source/i'); |
1522 |
'/include-source/i'); |
1469 |
$replace = Array('idiocy', 'idiocy', 'idiocy', 'idiocy'); |
1523 |
$replace = Array('idiocy', 'idiocy', 'idiocy', 'idiocy'); |
1470 |
$content = preg_replace($match, $replace, $content); |
1524 |
$contentNew = preg_replace($match, $replace, $contentTemp); |
|
|
1525 |
if ($contentNew !== $contentTemp) { |
1526 |
// insecure css declarations are used. From now on we don't care |
1527 |
// anymore if the css is destroyed by sq_deent, sq_unspace or sq_unbackslash |
1528 |
$content = $contentNew; |
1529 |
} |
1471 |
return array($content, $newpos); |
1530 |
return array($content, $newpos); |
1472 |
} |
1531 |
} |
1473 |
|
1532 |
|
Lines 1754-1760
Link Here
|
1754 |
"embed", |
1813 |
"embed", |
1755 |
"title", |
1814 |
"title", |
1756 |
"frameset", |
1815 |
"frameset", |
1757 |
"xml" |
1816 |
"xml", |
|
|
1817 |
"xmp" |
1758 |
); |
1818 |
); |
1759 |
|
1819 |
|
1760 |
$self_closing_tags = Array( |
1820 |
$self_closing_tags = Array( |