XSS 留言板实现-笔记
预备知识
XSS漏洞
- XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
- XSS最重要的两个关键词是“跨站”与“脚本”,由于现在网页上最主流的脚本语言是Javascript,所以这里的脚本主要是Javascript
- 一般,通过XSS攻击,可以获取被攻击者的COOKIE等信息,严重情况,网站管理员受到XSS攻击则攻击者甚至可能获取到管理员权限
- XSS的类型:
- 反射型XSS:又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。
- 存储型XSS:又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。谷歌的orkut曾经就遭受到XSS。
- DOM型XSS:基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。
留言板的简单实现
<?php
$servername = "localhost";
$username = "username";
$password = "password";
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "连接成功";
?>
SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );
毫无防护的留言板代码
<!DOCTYPE HTML>
<?php
//留言处理
if(isset($_GET['message']))
$getMessage = $_GET['message'];
else {
$getMessage = "";
}
//全局配置
//数据库配置
$dbhost = 'localhost:3306'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = 'dbpass'; // mysql用户名密码
$dbname = 'dbname';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysqli_error());
}
mysqli_select_db($conn,$dbname);
if($getMessage != ""){
$sql = "INSERT INTO `bulleting`.`lyb` (`date` ,`content`)VALUES (UTC_TIMESTAMP() , '".$getMessage."');";
$retval = mysqli_query( $conn, $sql );
}
?>
<html>
<head>
<meta charset="utf-8" />
<title>XSS留言板</title>
</head>
<body>
<table border=1 width = 100%>
<tr>
<td>日期</td>
<td>内容</td>
</tr>
<?php
// 获取任务
$sql = "SELECT * FROM `lyb` ";
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "<tr><td> {$row['date']}</td> ".
"<td>{$row['content']} </td> ".
"</tr>";
}
?>
<?php
mysqli_close($conn);
?>
</table>
<form action="index.php" method="get">
内容:
<textarea id="message" name="message"></textarea>
<br />
<input type="submit"></input>
</form>
</body>
</html>
- 测试截图:
![测试截图](https://img-blog.csdnimg.cn/20190221120527350.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3kzMjAyODQ=,size_16,color_FFFFFF,t_70)
![测试截图](https://img-blog.csdnimg.cn/20190221120553794.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3kzMjAyODQ=,size_16,color_FFFFFF,t_70)
- 存储型XSS检测代码:
<script>alert('/xss/');</script>
<img src="xxx" onerror=alert("/xss/");>
- 反射型XSS效果与存储型XSS和DOM型XSS差不多,唯一的差别是反射型XSS直接把GET中的参数显示在网页上,没有经过数据库,而存储型XSS是先存储到服务器上,再回显到网页的。
对XSS的初步防御
- 过滤标签符号,由于留言板并不需要html标签的输入,所以,我们可以放心地把所有HTML标签全部过滤。
- 代码:
$getMessage = addslashes($getMessage);
$getMessage = str_replace("<", "<",$getMessage);
$getMessage = str_replace(">", ">",$getMessage);