前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >软件安全性测试(连载8)

软件安全性测试(连载8)

作者头像
顾翔
发布2019-12-23 17:17:18
6880
发布2019-12-23 17:17:18
举报
文章被收录于专栏:啄木鸟软件测试

2.4 HTML5的安全

1. <audio><video>标签

对于<audio>和<video>这两个标签安全性而言,在于它同<img>一样支持跨域请求,比如。

<audioscr="http://www.mydomain.com/del_paper.jsp?id=5">

<video src="#"onerror="http://www.mydomain.com/hello.js">

2.iframe安全性

对于iframe一直是个前端的安全隐患,比如点击挟持,支持跨域等。维持HTML在iframe的sandbox中加入了几个安全属性。

lallow-same-origin:允许同源访问。

lallow-top-navigation:允许访问顶层窗口。

lallow-forms:允许提交表单。

lallow-scripts:允许执行脚本。

1)allow-scripts

如下HTML语句。

sandbox="allow-scripts"<br>

<iframesrc="frame1.html" sandbox="allow-scripts">

<p>你的浏览器不支持iframes.</p>

</iframe>

<br>sandbox=""<br>

<iframesrc="frame1.html" sandbox="">

<p>你的浏览器不支持iframes.</p>

</iframe>

第一个iframe可以执行src中的脚本,而第二个iframe则不可以执行src中的脚本,因为它没有sandbox="allow-scripts"选项。frame1.html HTML脚本如下。

<!doctype html>

<html>

<head>

<metacharset="gb2312">

<title>iframe1</title>

</head>

<body>

<buttononclick="getDateTime()">获得日期和时间</button>

<divid="dt"></div>

<script>

function getDateTime()

{

var d=new Date();

document.getElementById("dt").innerHTML=d;

}

</script>

</body>

</html>

18为sandbox中有allow-scripts和没有allow-scripts的情形。

18 sandbox是否具有allow-scripts值

2)allow-forms

如下HTML语句。

sandbox="allow-forms"<br>

<iframesrc="frame2.html" sandbox="allow-forms">

<p>你的浏览器不支持iframes.</p>

</iframe>

<br>sandbox=""<br>

<iframesrc="frame2.html" sandbox="">

<p>你的浏览器不支持iframes.</p>

</iframe>

第一个iframe可以提交src内的form表单,而第二个iframe则不可以提交src内的form表单,因为它没有sandbox=" allow-forms"选项。frame2.html HTML脚本如下。

<!doctype html>

<html>

<head>

<metacharset="gb2312">

<title>iframe2</title>

</head>

<body>

<formaction="demo_form.jsp">

姓: <input type="text" name="fname"value="Gu"><br><br>

名: <input type="text" name="lname"value="Xiang"><br><br>

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

</form>

</body>

</html>

demo_form.jsp脚本如下。

<!doctype html>

<html>

<head>

<metacharset="gb2312">

<title>ifrme2</title>

</head>

<body>

<%

Stringfname=request.getParameter("fname");

Stringlname=request.getParameter("lname");

%>

fname:<%=fname%><br>

lname:<%=lname%>

</body>

</html>

19为sandbox中有allow-forms和没有allow-forms的情形。

19 sandbox是否具有allow-forms值

3)allow-same-origin

如下HTML语句。

sandbox="allow-same-originallow-scripts"<br>

<iframesrc="frame3.html" sandbox="allow-same-origin allow-scripts">

<p>你的浏览器不支持iframes.</p>

</iframe>

<br>sandbox=""<br>

<iframesrc="frame3.html" sandbox="">

<p>你的浏览器不支持iframes.</p>

</iframe>

第一个iframe可以执行src内的Javascript脚本,而第二个iframe则不可以执行src内的Javascript脚本,因为它没有sandbox="allow-same-origin"和"allow-scripts"选项。frame3.html HTML脚本如下。

<!doctype html>

<html>

<head>

<metacharset="gb2312">

<title>ifrme3</title>

</head>

<body>

<p>图书列表(来自通过 JavaScript 取回的 XML 文件):</p>

<script>

if (window.XMLHttpRequest)

{

xhttp=new XMLHttpRequest();

}

else // for IE 5/6

{

xhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

xhttp.open("GET","book.xml",false);

xhttp.send();

xmlDoc=xhttp.responseXML;

x=xmlDoc.getElementsByTagName('title');

for (i=0;i<x.length;i++)

{

document.write(x[i].childNodes[0].nodeValue);

document.write("<br>");

}

</script>

</body>

</html>

book.xml如下。

<?xml version="1.0"encoding="ISO-8859-1"?>

<bookstore>

<bookcategory="children">

<titlelang="en">Harry Potter</title>

<author>J K.Rowling</author>

<year>2005</year>

<price>29.99</price>

</book>

<bookcategory="cooking">

<titlelang="en">Everyday Italian</title>

<author>Giada DeLaurentiis</author>

<year>2005</year>

<price>30.00</price>

</book>

<bookcategory="web" cover="paperback">

<titlelang="en">Learning XML</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>

<bookcategory="web">

<titlelang="en">XQuery Kick Start</title>

<author>JamesMcGovern</author>

<author>PerBothner</author>

<author>KurtCagle</author>

<author>JamesLinn</author>

<author>VaidyanathanNagarajan</author>

<year>2003</year>

<price>49.99</price>

</book>

</bookstore>

20为sandbox中有allow-same-origin和没有allow-same-origin的情形。

20 sandbox是否具有allow-same-origin值

3. a标签的rel="noopener noreferrer" 属性

a标签的rel="noopenernoreferrer" 属性主要目的是不把父窗口中的信息传给子窗口,从而实现隐私的保密性。主窗口代码如下。

<html>

<body>

<scripttype="text/javascript">

function de(n){

document.getElementById('a').value= n;

}

</script>

<input type="text"name="a" id="a">

<br><ahref="b.html" target="_blank">不带noopener noreferrer属性</a>

</body>

</html>

子窗口b.html代码如下。

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

<scripttype="text/javascript">

function demo(){

window.opener.de("JerryGu");

window.close();

}

</script>

</head>

<body>

</script>

把JerryGu传给父窗口<br>

<inputtype="submit" name="submit" value="submit2"onclick="demo()">

</body>

</html>

在父窗口中存在一个javascript函数function de(n),当通过点击<a href="b.html"target="_blank">不带noopener noreferrer属性</a>超链进入到b.html中后,子窗口可以通过window.opener.de("JerryGu");方法调用父窗口的函数从而达到父子窗口通信的功能。但是有时为了保持父节点的隐私性,特别是打开一个异源网站。只需要在主窗口代码<a href="b.html" target="_blank">不带noopener noreferrer属性</a>中加入rel="noopenernoreferrer" 属性即可:<br><ahref="b.html" target="_blank" rel="noopenernoreferrer">带noopener noreferrer属性</a>。这样通过点击标签a进入b.html后,子窗口将无法与父窗口进行通信。实质上加入了rel="noopenernoreferrer" 属性,在页面传输过程中不含有referrer头信息。

4. Canvas

Canvas中文名字为“画布”,是HTML5的一个重要功能,但是利用它可以破解一些简单的验证码。这里以一个为0-9数字的验证码为例进行介绍。其原理为。

1.获取0-9数字的验证码灰度化后的特征数值。

2.将验证码按数字等宽度拆分。

3.灰度化拆分后的每一个图片。

4.与特征数值进行比较。

5.得到验证码。

其原理见21。

21 通过画布破解验证码步骤

其代码如下。

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8">

<title>演示十七:验证码的破解</title>

<scriptlanguage="javascript" type="text/javascript">

function login(){

varimage=document.querySelector(".myimage"); //获取到验证码图片

varcanvas=document.createElement('canvas'); //新建一个canvas

varctx=canvas.getContext("2d");//获取2D上下文

var numbers=[];//存储数字模板的数组

canvas.width = image.width; //设置canvas的宽度

canvas.height = image.height; //设置canvas的高度

document.body.appendChild(canvas);//将canvas添加进文档

ctx.drawImage(image,0,0);//将验证码绘制到canvas上

for (var i=0;i<4;i++) { //循环四次,识别四个数字

varpixels=ctx.getImageData(13*i+7,3,9,16).data; //按照公式获取到每个数字上的像素点

var ldString = "a";//用来存储明暗值的字符串

for (varj=0,length=pixels.length;j<length;j+=4) {//每次循环取四个值,分别是一个像素点的r,g,b,a值

ldString=ldString+(+(pixels[j]*0.3+pixels[j+1]*0.59+pixels[j+2]*0.11>=128)); //灰度化+二值化,但我们并没有真正的处理图像

}

console.log(ldString); //输出存储着明暗值的字符串

}

}

function display(){

var image =document.querySelector(".myimage");//如果要用在greasemonkey脚本里,可以把下面的代码放在image的onload事件里

var canvas =document.createElement('canvas');

var ctx =canvas.getContext("2d");

var numbers = [//模板,依次是0-9十个数字对应的明暗值字符串

"111000111100000001100111001001111100001111100001111100001111100001111100001111100001111100100111001100000001111000111111111111111111111111111111",

"111000111100000111100000111111100111111100111111100111111100111111100111111100111111100111111100111100000000100000000111111111111111111111111111",

"100000111000000011011111001111111001111111001111110011111100111111001111110011111100111111001111111000000001000000001111111111111111111111111111",

"000011111110011111110011111110111111000111111000111111110011111111011111111011111100011111000111111001111111111111111111111111111111111000000000",

"001110000001110000001110000001110000001110000001110000001110000000010000000010000001110000001110000001110000111110000111110000111110000000000000",

"000011111111111111111111111111111111011111111000111111100011111110011111110011110100011111000111111001111111111111111111111111111111111000000000",

"000001111111101111111111111111111111000111111000001111111001111111100111111100111111000111000001111000011111111111111111111111111111111000000000",

"100000000100000000111111100111111101111111001111110011111110111111100111111101111111001111111001111110011111110011111111111111111111111111111111",

"110000011100000001100111001100111001100011011110000011110000011100110001001111100001111100000111000100000001110000011111111111111111111111111111",

"110000111100000001000111001001111100001111100000111000100000000110000100111111100111111001101111001100000011110000111111111111111111111111111111"];

var captcha = "";//存放识别后的验证码

canvas.width = image.width;

canvas.height = image.height;

document.body.appendChild(canvas);

ctx.drawImage(image, 0, 0);

for (var i = 0; i < 4; i++) {

var pixels = ctx.getImageData(13 * i + 7,3, 9, 16).data;

var ldString = "";

for (var j = 0,length = pixels.length; j< length; j += 4) {

ldString = ldString + (+(pixels[j] *0.3 + pixels[j + 1] * 0.59 + pixels[j + 2] * 0.11 >= 140));

}

var comms = numbers.map(function (value){//为了100%识别率,这里不能直接判断是否和模板字符串相等,因为可能有个别0被计算成1,或者相反

returnldString.split("").filter(function (v, index) {

return value[index] === v

}).length

});

captcha +=comms.indexOf(Math.max.apply(null, comms)); //添加到识别好的验证码中

}

//document.querySelector("input[name=validateCode]").value= captcha; //写入目标文本框

alert(captcha);

}

</script>

</head>

<bodyonload="display()">

<img src="1.bmp"class="myimage">

</body>

</html>

5. 获取地理坐标

对于在线地图软件而言,获取本地经纬度值是非常重要的功能,在HTNL5中实现了这个功能。效果如22所示。

22 获取当前的经纬度

类似本地经纬度信息属于个人隐私的范畴,软件如果要获取这些信息,应该在使用之前得到用户的许可,特别是在APP端。现在Chrome、FireFox都支持了预先通知的机制,见23所示。

23 预先通知获取用户隐私机制

6. 本地存储

HTML5本地存储的前身就是cookie,但是cookie每个域尽可存储4K信息,而作为本地存储,每个域竟可存储高达5M信息。关于本地存储需要注意以下几个问题。

l从安全性角度而言不可替代cookie。

l不要存储敏感信息。

l防止XSS注入,严格过滤输入输出。

l容易遭受跨目录攻击。

l容易遭受DNS欺骗攻击。

l是恶意代码栖息的温床。

l具体细节本书不详细解开,有兴趣的读者可以查阅相关资料。

前面所述的均为前端的安全性,在这里特别需要指出,用户可以通过截包工具,自己写接口代码等方式绕过前端访问后端,所以类似于XSS注入的防御不仅要在前端做好把关,更重要的是在后端进行二次控制。下面从后端的角度来进行讲解WEB的安全性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档