大约
“跨站点脚本 (XSS)”攻击是一种注入问题,其中恶意脚本被注入到原本良性和受信任的网站上。 当攻击者使用 Web 应用程序发送恶意代码(通常以浏览器端脚本的形式)时,就会发生 XSS 攻击, 给其他最终用户。允许这些攻击成功的缺陷非常普遍,并且发生在使用输出中用户输入的Web应用程序的任何地方, 无需验证或编码。
攻击者可以使用 XSS 向毫无戒心的用户发送恶意脚本。最终用户的浏览器无法知道脚本不应该被信任, 并将执行 JavaScript。由于恶意脚本认为脚本来自受信任的来源,因此可以访问任何 Cookie、会话令牌或其他 您的浏览器保留并与该网站一起使用的敏感信息。这些脚本甚至可以重写 HTML 页面的内容。
因为它是反射式 XSS,恶意代码不会存储在远程 Web 应用程序中,因此需要一些社交工程(例如通过电子邮件/聊天的链接)。
目的
以一种或另一种方式,窃取登录用户的cookie。
低水平
在将请求的输入包含在输出文本中之前,低级别不会检查该输入。
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
这是一个处理用户从URL中传递的数据的PHP脚本,它输出一个欢迎消息。相较于之前的代码,这个脚本已经改进了安全性。
使用 `array_key_exists()` 函数来验证 “name” 是否在 `$_GET` 中,并且 `$_GET[ 'name' ]` 不等于 `NULL`。通过这样的验证,可以确保 `$_GET[ 'name' ]` 中实际上有数据,避免了在尝试访问未定义的变量时出错的情况。
可见这个脚本是用户输入什么,就会显示什么。
Spoiler: ?name=<script>alert("XSS");</script>.
在输入框输入<script>alert("XSS");</script> 点击submit,显示了alert
中级
开发人员尝试添加一个简单的模式匹配来删除对“<script>”的任何引用,以禁用任何JavaScript。
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello {$name}</pre>";
}
?>
这是一个PHP脚本,用于获取用户从URL中传递的数据,并输出带有一个欢迎消息的HTML代码。
然而,这个脚本存在一个非常严重的安全漏洞,即它没有对输入数据进行任何过滤或净化,这导致了潜在的XSS攻击。攻击者可以在URL参数中注入恶意的JavaScript代码,从而在用户访问该页面时在用户的浏览器中执行任意脚本。这将使攻击者能够窃取用户的授权Cookie、获取用户的输入、重定向到其他恶意站点等等。
使用 `str_replace()` 函数来清除 `<script>` 标记是不足以解决XSS漏洞的。应该使用适当的净化方法和输出编码方法,如 `htmlspecialchars()` 函数或使用模板引擎来生成JavaScript。
因此,建议对用户的输入数据进行彻底的验证和净化,包括过滤特殊字符、将HTML标签转义为它们的HTML实体等。此外,推荐使用先进的Web应用程序防火墙(WAF)和安全性别扫描程序来保护您的Web应用程序免受此类攻击。
由中级的脚本可见,该程序只把<script>替换成了空字符串。
Spoiler: Its cAse sENSiTiVE.
输入低水平攻击,显示了alert("XSS")
高水平
开发人员现在认为他们可以通过删除模式“<s*c*r*i*p*t”来禁用所有JavaScript。
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello {$name}</pre>";
}
?>
这是一个处理用户从URL中传递的数据的PHP脚本,它尝试使用正则表达式从用户输入的数据中删除所有的 `<script>` 标记。相较之前的代码,它更具有安全性。
使用 `array_key_exists()` 函数来验证 “name” 是否在 `$_GET` 中,并且 `$_GET[ 'name' ]` 不等于 `NULL`。通过这样的验证,可以确保 `$_GET[ 'name' ]` 中实际上有数据,避免了在尝试访问未定义的变量时出错的情况。
与之前不同的是,这个脚本使用了正则表达式 `preg_replace()` 函数,它可以删除用户输入数据中的所有 `<script>` 标记。通过这种方式净化输入数据,可以缓解XSS攻击的风险,因为攻击者无法在用户的浏览器中注入任意的JavaScript代码。
然而,这种方法并不是完全可靠的,因为攻击者可以使用各种技术来绕过此类过滤器。在实际应用中,应该使用更多净化手段来确保Web应用程序的安全性。
因此,建议在处理用户输入数据时要进行适当的验证和净化,并使用可以确保您的Web应用程序免受XSS攻击的安全措施。例如,使用HTML Purifier这样的库,它可以清除输入数据中的HTML标记并将其转义为安全的HTML实体。
Spoiler: HTML events.
输入低水平脚本,只显示了一个Hello >
不可能的水平
使用内置的PHP函数(如“htmlspecialchars()”), 可以转义任何会改变输入行为的值。
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello {$name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
这是一个处理用户从URL中传递的数据的PHP脚本,它首先验证Anti-CSRF token的有效性,然后使用 `htmlspecialchars()` 函数将用户输入数据转义为HTML实体,以防止XSS攻击。
使用 `array_key_exists()` 函数来验证 “name” 是否在 `$_GET` 中,并且 `$_GET[ 'name' ]` 不等于 `NULL`。通过这样的验证,可以确保 `$_GET[ 'name' ]` 中实际上有数据,避免了在尝试访问未定义的变量时出错的情况。
此外,这个脚本还包含了Anti-CSRF token的相关代码。 `checkToken()` 函数用于验证用户提交的token与存储在Session中的token是否相同,以防止CSRF攻击。如果两个token不同,则重定向到指定的URL `index.php`。 `generateSessionToken()` 函数用于生成并存储新的Session token。
这种方式能够一定程度地保护Web应用程序和用户免受XSS和CSRF攻击,但并不是完全可靠的。建议在处理用户输入数据时,采用更多安全措施和净化方法,以确保应用程序的安全性。同时,也建议进行安全漏洞测试和评估,以检测并解决任何可能存在的安全漏洞。