Project

General

Profile

Bug #80888 ยป removexssdatauri.patch

patch for data attributes against 6.2 - Jigal van Hemert, 2017-08-01 11:42

View differences:

typo3/sysext/core/Tests/Legacy/typo3/contrib/class.removexssTest.php (revision )
public function checkAttackMetaWithUrl()
{
$testString = '<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">';
$expectedString = '<me<x>ta HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">';
$expectedString = '<me<x>ta HTTP-EQUIV="refresh" CONTENT="0;url=<sc<x>ript>alert(\'XSS\')</script>
">';
$actualString = RemoveXSS::process($testString);
$this->assertEquals($expectedString, $actualString);
......
RemoveXSS::process($input)
);
}
/**
* @return array<array> input strings and expected output strings to test
*
* @see dataUrlWithDataProvider
*/
public function dataUrlDataProvider()
{
return array(
'attackWithUrlEncodedData' => array(
'<a href="data:,%3Cscript%3Ealert%28%27XSS%21%27%29%3B%3C%2Fscript%3E">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithUrlEncodedDataAndMimeType' => array(
'<a href="data:text/javascript,%3Cscript%3Ealert%28%27XSS%21%27%29%3B%3C%2Fscript%3E">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithUrlEncodedDataAndCharset' => array(
'<a href="data:charset=utf-8,%3Cscript%3Ealert%28%27XSS%21%27%29%3B%3C%2Fscript%3E">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithUrlEncodedDataAndMimeTypeAndCharset' => array(
'<a href="data:text/javascript;utf-8,%3Cscript%3Ealert%28%27XSS%21%27%29%3B%3C%2Fscript%3E">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithBase64Data' => array(
'<a href="data:base64,PHNjcmlwdD5hbGVydCgnWFNTIScpOzwvc2NyaXB0Pg">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithBase64DataAndMimeType' => array(
'<a href="data:text/javascript;base64,PHNjcmlwdD5hbGVydCgnWFNTIScpOzwvc2NyaXB0Pg">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithBase64DataAndCharset' => array(
'<a href="data:charset=utf-8;base64,PHNjcmlwdD5hbGVydCgnWFNTIScpOzwvc2NyaXB0Pg">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
'attackWithBase64DataAndMimeTypeAndCharset' => array(
'<a href="data:text/javascript;chareset=utf-8;base64,PHNjcmlwdD5hbGVydCgnWFNTIScpOzwvc2NyaXB0Pg">click</a>',
'<a href="<sc<x>ript>alert(\'XSS!\');</script>">click</a>',
),
);
}
/**
* @test
*
* @param string $input input value to test
* @param string $expected expected output value
*
* @dataProvider dataUrlDataProvider
*/
public function dataUrlWithDataProvider($input, $expected)
{
$this->assertEquals(
$expected,
RemoveXSS::process($input)
);
}
}
typo3/sysext/core/Resources/PHP/RemoveXSS.php (revision )
// Note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
$value = preg_replace('/([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x19])/', '', $value);
// Replace data URLs as they can obfuscate the payload
if (stripos($value, 'data:') !== false) {
$searchDataUris = '/data:((?<!base64|charset|,).*?)?(;?charset=.+?)?(;?base64)?(\,(?:[A-Za-z0-9+\/\._~%-]+)?)/m';
$value = preg_replace_callback(
$searchDataUris,
function($matches) {
$entireDataUri = array_shift($matches);
$data = '';
$encodingFunction = 'rawurldecode';
$charset = 'US-ASCII';
$mimeType = 'text';
foreach ($matches as $match) {
if (substr($match, 0, 1) === ',') {
// check for data block
$data = substr($match, 1);
} elseif (substr($match, 0, 7) === ';base64' || substr($match, 0, 6) === 'base64') {
// check for base64 notation
$encodingFunction = 'base64_decode';
} elseif (substr($match, 0, 9) === ';charset=' || substr($match, 0, 8) === 'charset=') {
// check for charset
$charset = substr(ltrim($match, ';'), 8);
} elseif (strpos($match, '/') !== false) {
// check for mime-type
$mimeTypeParts = explode('/', $match, 2);
$mimeType = $mimeTypeParts[0];
}
}
if ($mimeType !== 'text') {
// Anything else than text does not need handling
return $entireDataUri;
}
// charset handling needed?
return $encodingFunction($data);
},
$value);
}
// Straight replacements, the user should never need these since they're normal characters.
// This prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
$searchHexEncodings = '/&#[xX]0{0,8}(21|22|23|24|25|26|27|28|29|2a|2b|2d|2f|30|31|32|33|34|35|36|37|38|39|3a|3b|3d|3f|40|41|42|43|44|45|46|47|48|49|4a|4b|4c|4d|4e|4f|50|51|52|53|54|55|56|57|58|59|5a|5b|5c|5d|5e|5f|60|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|78|79|7a|7b|7c|7d|7e);?/i';
    (1-1/1)