跨站点脚本 (XSS)”攻击是一种注入问题,其中恶意脚本被注入到原本良性和受信任的网站上。 当攻击者使用 Web 应用程序发送恶意代码(通常以浏览器端脚本的形式)时,就会发生 XSS 攻击, 给其他最终用户。允许这些攻击成功的缺陷非常普遍,并且发生在使用输出中用户输入的Web应用程序的任何地方, 无需验证或编码。
攻击者可以使用 XSS 向毫无戒心的用户发送恶意脚本。最终用户的浏览器无法知道脚本不应该被信任, 并将执行 JavaScript。由于恶意脚本认为脚本来自受信任的来源,因此可以访问任何 Cookie、会话令牌或其他 您的浏览器保留并与该网站一起使用的敏感信息。这些脚本甚至可以重写 HTML 页面的内容。
XSS 存储在数据库中。XSS 是永久性的,直到重置数据库或手动删除有效负载。
目的
将每个人重定向到您选择的网页。
低水平
在将请求的输入包含在输出文本中之前,低级别不会检查该输入。
Spoiler: Either name or message field: <script>alert("XSS");</script>.
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
这是一个用于将用户输入数据插入到数据库中的 PHP 脚本。脚本首先将用户输入数据中的空格和换行符删除,并使用 `stripslashes()` 函数删除可能存在的反斜杠字符。
随后脚本使用 `mysql_real_escape_string()` 函数对用户输入数据进行净化,并将其放入 `$query` 变量中,然后通过 `mysqli_query()` 函数将数据插入到数据库中。
在本脚本中,存在使用 `mysql_real_escape_string()` 函数进行净化,避免SQL注入攻击的风险。但是,它仍然存在一些漏洞,如可能的XSS攻击等。
因此,在处理用户输入数据时,应该采取更多种类的净化方法,并使用适当的权限和限制验证来确保Web应用程序的安全性和可靠性。同时,拒绝对使用过时且易受攻击的 `mysql` 扩展方法,这样可以更安全的使用 PHP 语言。
输入js,点击sign,显示了alert,攻击成功
中级
开发人员添加了一些保护,但是并没有以相同的方式完成每个字段。
Spoiler: name field: <sCriPt>alert("XSS");</sCriPt>.
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
这是一个将用户输入数据插入到数据库中的 PHP 脚本,并采用多种净化方法来增强安全性。
与之前的脚本不同,这个脚本使用 `strip_tags()` 函数从用户输入的消息中删除任何HTML标记,避免XSS攻击。同时,将特殊字符添加反斜杠,并使用 `mysqli_real_escape_string()` 函数进行SQL注入攻击的防御。同时,使用 `htmlspecialchars()` 函数转义用户消息中的特殊字符。
对于用户名,脚本使用 `str_replace()` 函数将 `<script>` 标签全部替换为空,从而避免了脚本注入攻击。接着同样采用反斜杠进行转义和`mysqli_real_escape_string()` 函数设置防御。
这种净化方案极大地增强了应用程序的安全性和可靠性,同时,还可以通过权限和限制验证来进一步保护Web应用程序免受恶意攻击。
输入如上脚本,显示了alert,攻击成功
高水平
开发人员认为他们已经通过删除模式“<s*c*r*i*p*t”来禁用所有脚本使用。
Spoiler: HTML events.
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
不可能的水平
使用内置的PHP函数(如“htmlspecialchars()”), 可以转义任何会改变输入行为的值。
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = stripslashes( $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$name = htmlspecialchars( $name );
// Update database
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
不可能水平,
这是一个将用户输入数据插入到数据库中的 PHP 脚本,并增加了防范CSRF攻击的安全措施。
脚本首先使用 `checkToken()` 函数验证用户提交的token是否与当前session中的token相同,以避免CSRF攻击的风险。
随后,脚本使用多种净化方法来加强安全性,包括:
- 使用 `strip_slashes()` 函数删除用户输入消息和用户名中可能存在的反斜杠字符。
- 使用 `mysqli_real_escape_string()` 函数对用户输入数据进行SQL注入攻击的防御。
- 使用 `htmlspecialchars()` 函数转义用户输入消息和用户名中的特殊字符。此外,脚本还使用了PDO数据库抽象层来执行对数据库的操作,避免了使用原生SQL语句时,出现的SQL注入漏洞。
最后,脚本调用 `generateSessionToken()` 函数生成新的Session token。
使用这些净化方法和安全措施可以大大增强Web应用程序的安全性和可靠性,并避免恶意攻击。