xss攻击及防御

前端这点事 199 0

什么是XSS

XSS全称:跨站脚本(Cross Site Scripting,为了不和层叠样式表(Cascading Style Sheets)的缩写CSS混合,所以改名为XSS;攻击者会向web页面(input表单、URL、留言版等位置)插入恶意JavaScript代码,导致管理员/用户访问时触发,从而达到攻击者的目的。

XSS的危害:

窃取管理员/用户的cookie非法登录,导致网站被挂马、服务器沦陷被控制等等……

XSS类型:

1、反射型

2、存储型

3DOM

XSS反射型:

攻击者通过input表单或URLweb页面中插入恶意的JavaScript代码,当web接收到攻击者恶意的JavaScript代码即会执行JavaScript代码。

<html>

<head>

<title>xss</title>

</head>

<body bgcolor="black">

<center>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

<input type="text" name="xss">

<input type="submit">

</form>

<hr>

<?php

$xss = $_POST['xss'];

echo $xss;

?>

</center>

</body>

</html>


从上面这段代码我们来分析一下,首先值得一提的是不管是GET还是POST,这里都是反射,从上面的代码中可以看到$xssPOST方式接收用户输入在input里面的数据,然后输出。

当攻击者提交<script>alert(/xss/)</script>时,$xss变量就会接收回来,并输出,这时客户端(网页)接收到JS代码时就会执行JS代码。

此时网页源代码就变成了:

<html>

<head>

<title>xss</title>

</head>

<body bgcolor="black">

<center>

<form method="post">

<input type="text" name="xss">

<input type="submit">

</form>

<hr>

<script>alert(/XSS/)</script>

</center>

</body>

</html>

从上面我们可以看到攻击者已经把JavaScript代码插入到web页面中。

对于这种反射型即非持久型XSS,实际危害影响较小,并只触发一次,只要针对于客户端层面,那么我们接下来看一下存储型即持久型XSS

XSS存储型:

攻击者通过网站重要操作【增】向数据库中插入恶意JavaScript代码并让网站再从数据库中读取出来,而这样的一项操作都指向了网站的留言版,留言版这个功能包含了三个重要操作【对于管理员,写、读、删】,对于普通用户最多两个【写、读】,也就是说用户在提交留言时执行了增加操作,当访问留言版时执行了查询操作。

有如下三个文件:

index.php

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<font size="30" color="white" face="楷体">留言版</font><br />

<form name="form1" method="post" action="./submit.php">

<textarea cols="50" rows="10" name="contents"></textarea><br /><br />

<input type="submit" name="submit" value="提交">

</form>
</body>

</html>

submit.php

<?php 
define('host', 'localhost');
define('user', 'testtest');
define('pass', 'testtest');
define('dbname', 'testtest');
$link = mysqli_connect(host, user, pass);
mysqli_select_db($link, dbname);
mysqli_set_charset($link, 'utf-8');
$contents = $_POST['contents'];
$sql = "insert into test (id, content) values (1, '".$contents."')";
$res = mysqli_query($link, $sql);
?>

上面注入数据库成功后,用户访问留言板就会触发攻击:

<?php 
define('host', 'localhost');
define('user', 'testtest');
define('pass', 'testtest');
define('dbname', 'testtest');
$link = mysqli_connect(host, user, pass);
mysqli_select_db($link, dbname);
mysqli_set_charset($link, 'utf-8');
$sql = "SELECT * FROM test order by id desc";

$result= mysqli_query($link, $sql);
if (mysqli_num_rows($result) > 0) {
// 输出数据
while($row = mysqli_fetch_assoc($result)) {
echo "id: " . $row["id"]. " - content: " . $row["content"]. "<br>";
}
} else {
echo "0 结果";
}
?>

模拟攻击者入侵:

当攻击者在留言版界面【index.php】插入恶意的JavaScript代码并提交,那么index.php里的内容就会提交到submit.php文件,并执一项重要操作【增加】,向数据库里面增加一条留言,当管理员登录网站去查看留言时【ly.php】,就会触发攻击者插入的恶意JavaScript,因为ly.php里有一条重要操作【查询】,把数据库中所有留言内容查询出来并显示在页面上,那么攻击者的恶意代码同样也会被查询出来显示在页面上,因为JavaScript会被当做脚本执行,所以这就构成了XSS跨站攻击。

XSS DOM型:

对于这个DOM型来说,有点类似于反射型但又不那么像,因为它主要针对于DOM对象,那么什么是DOM对象?例如:document.getElementByIdinnerHTML等等……就不一一列举了,因为我们今天用到的例子主要就是document.getElementByIdinnerHTML,首先我们简单说一下这两个DOM对象是什么意思

document.getElementById:通过元素的ID特性来获取元素。

innerHTML:设置返回开始与结束标签之间的HTML,简单点的来说就是把内容传到一个标签元素的开始与结束中间。

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>dom xss</title>
</head>

<body>
    <div id="app">
        <textarea name="" id="" cols="30" rows="10" v-model="html"></textarea>
        <div v-html="html"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var instance = new Vue({
            el: '#app',
            data: {
                html: ''
            },
            watch: {
                html() {
                    localStorage.setItem('html', instance.html)
                }
            }
        })
        window.onload = function () {
            instance.html = localStorage.getItem('html')
        }
    </script>
</body>

</html>

当用户输入<script>alert('xss')</script>,我们可以看到审查元素就有了script标签,但是google可能安全性比较好,不会弹出,

但是火狐浏览器就会弹出这个提示了。

到这里三种类型的XSS说完了,从这三种类型我们可以这样比较

反射型<DOM<存储型

最后附上源码地址:https://github.com/zzxiexin/xss-try

总之不管是哪一种XSS,都是过于相信用户的输入,没有有效的采取防御措施,应当采用HttpOnly防止劫取Cookie、在客户端和服务端对程序接收到的数据进行全面过滤,对特殊字符进行过滤等等……


标签: XSS

发表评论 (已有0条评论)

还木有评论哦,快来抢沙发吧~