2.4 松散的 HTML 世界
HTML里可以有脚本、样式等内容的嵌入,以及图片、多媒体等资源的引用。我们看到的网页就是一个HTML文档,比如下面这段就是HTML。
<html> <head> <title>HTML</title> <metahttp-equiv="Content-Type" content="text/html; charset=utf-8" /> <style> /*这里是样式*/ body{font-size:14px;} </style> <script> a=1; // 这里是脚本 </script> </head> <body> <div> <h1>这些都是HTML</h1><br /> <img src="http://www.foo.com/ logo.jpg" title="这里是图片引用" /> </div> </body> </html>
为什么说HTML的世界是松散的?我们知道,HTML是由众多标签组成的,标签内还有对应的各种属性。这些标签可以不区分大小写,有的可以不需要闭合。属性的值可以用单引号、双引号、反单引号包围住,甚至不需要引号。多余的空格与Tab毫不影响HTML的解析。HTML里可以内嵌CSS、JavaScript等内容,而不强调分离,等等。
松散有松散的好处,但这样却培养出了一种惰性,很多前端安全问题就是因为松散导致的。
2.4.1 DOM树
DOM树对于Web前端安全来说非常重要,我们的很多数据都存在于DOM树中,通过DOM树的操作可以非常容易地获取到我们的隐私数据。其实HTML文档就是一个DOM树。
如上面那段HTML,如果用树形结构描述,语句如下。
<html> - <head> - <title> - HTML - <meta> - @http-equiv - Content-Type - @content - text/html - @charset - utf-8 - <style> - /*这里是样式*/\r\nbody{font-size:14px;} - <script> - a=1; // 这里是脚本 - <body> - <div> - <h1> - 这些都是HTML - <br /> - <img> - @src - http://www.foo.com/logo.jpg - @title - 这里是图片引用
这个树很简单,<html>是树根,其他都是树的每个节点。这里约定标签节点以<xxx>表示,属性节点以@xxx表示,而文本节点以xxx表示。
我们的隐私数据可能存储在以下位置:
· HTML内容中;
· 浏览器本地存储中,如Cookies等;
· URL地址中。
这些通过DOM树的查找都可以获取到,仅仅是JavaScript对DOM的操作。如果想了解更多的细节,可以跳到2.5.1节查看。
2.4.2 iframe内嵌出一个开放的世界
iframe标签是HTML中一个非常重要的标签,也是Web安全中出镜频率最高的标签之一,很多网站都通过iframe嵌入第三方内容,比如,嵌入广告页面,语句如下:
<!--AdForward Begin:--> <iframe marginheight="0" marginwidth="0" frameborder="0" width="820" height="90" scrolling="no" src="http://msn.allyes.com/main/adfshow? user=MSN|Home_Page|Homepage_2nd_banner_820x90 &db=msn&border=0&local=yes"> </iframe> <!--AdForward End-->
还有Web 2.0网站中嵌入的许多第三方Web游戏与应用,都有使用到iframe。iframe标签带来了很多便利,同时也带来了很多风险,比如,攻击者入侵一个网站后,可以通过iframe嵌入自己的网马页面,用户访问该网站后,被嵌入的网马页面就会执行,这种信任关系导致的安全问题在第1章已介绍过。
iframe标签还有一些有趣的安全话题,当网站页面使用iframe方式嵌入一个页面时,我们约定网站页面是父页,而被嵌入的这个页面是子页,如图2-1所示。那么父页与子页之间如何跨文档读写数据?
图2-1 iframe父页与子页资源访问
如果父页和子页之间是同域,那就很容易,父页可以通过调用子页的contentWindow来操作子页的DOM树,同理,子页可以调用父页的con-tentWindow来操作父页的DOM树。如果它们不同域,则必须遵守同源策略,但子页还是可以对父页的location值进行写操作,这样可以让父页重定向到其他网页,不过对location的操作仅仅只有写权限,而没有读权限,这样就不能获取到父页loca-tion URL的内容,否则有可能会造成隐私数据泄漏,比如,有的网站将身份认证token存在于URL中。
2.4.3 HTML内嵌脚本执行
JavaScript脚本除了出现在JS格式文件里,被嵌入而执行外,还可以出现在HTML的<script></script>标签内、HTML的标签on事件中,以及一些标签的href、src等属性的伪协议(javascript:等)中。
如下几个例子:
<script>alert(1)</scipt> <img src=# onerror="alert(1)" /> <input type="text" value="x" onmouseover="alert(1)" /> <iframe src="javascript:alert(1)"></iframe> <a href="javascript:alert(1)">x</a> …
这样导致防御XSS变得有些棘手,出现在DOM树的不同位置,面对的防御方案都不太一样。这也为攻击者提供了很大便利,能够执行JavaScript的位置越多,意味着XSS发生的面也越广,XSS漏洞出现的可能性也越大。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论