web前端黑客技术揭秘(2)

前端基础

基础第一,我们觉得有必要将町能涉及的语言基础部分在本章进行系统介绍,大家将 会发现许多有意思的知识。不过,对于己经非常熟悉该领域的人来说,可以跳过本章或仅 仅是粗略地过一遍。

我们绝不会像教科书那样介绍一些过于基础的内容,比如,语法、函数等,这些知识 可以査阅官方手册。本章的介绍始终会围绕前端安全,这些基础知识点会贯穿本书。

首先,看看这个松散的HTML世界,脚本、样式、图片、多媒体等这些资源如何运作; 然后,看看号称跨站之魂的JavaScript脚本如何打破这个世界的逻辑,CSS样式如何让这个 世界充满伪装;最后,看看另一只躲藏在Flash里的“幽灵",它又是如何辅佐JavaScript的。

2.1 W3C的世界法则

W3C即万维网联盟(http://www.w3.org/),它制定了很多推荐标准,比如:HTML、

XMLJavaScriptCSS等,是这些标准让这个Web世界变得标准和兼容。浏览器遵循这

些标准去实现自己的各种解析引擎,Web厂商同样遵循这些标准去展示自己的Web服务。 如果没有W3C,那么这个Web世界将一片混乱。

由于W3C制定的是推荐标准,很多时候网站并没严格按照这些标准执行,但是却能比 较好地呈现出来。而浏览器的实现也不一定完全遵循标准,甚至可能冒出一个自己的方案, 这个现象可以在微软的IE浏览器与MozillaFirefox浏览器中随处发现,这也是前端设计 师们经常苦恼的“不兼容”问题,导致出现了各种“Hack”技术,这些Hacks就是为了解 决这些不兼容问题而出现的。

比如,为了解决CSS兼容性而发展的CSS Reset技术,该技术会重置一些样式(这 些样式在不同的浏览器中有不同的呈现),后续的CSS将在这个基础E重新开始定义自己 的样式。

再如,为了解决JavaScript兼容性,诞生了许多优秀的JavaScript框架,如jQuetyYUI 等,使用这些框架提供的API,就可以很好地在各个主流浏览器上得到一致的效果。

Web世界在进步,标准化也越来越被重视。相比前端工程师来说,我们更关注安全问 题,W3C的标准设计就安全了吗?浏览器遵循W3C标准的实现就完美了吗?浏览器之间 的这些差异可能导致多少安全风险的出现?在深入了解这些知识之前,我们还需要明白一 点,导致Web安全事件的角色都有哪些,而解决方案参与者又有哪些?

Web安全事件的角色如下:

  • W3C

浏览器厂商:

  • Web厂商;

攻击者(或黑客):

被攻击者(或用户)。

解决方案的参与者除了攻击者以外,其他都需要参与,这是一个因果循环,如果W3C 的标准制定具有安全缺陷,那么遵循标准去实现的浏览器厂商与Web厂商都将带进这些安 全缺陷,或者W3C标准没安全缺陷,而浏览器厂商或者Web厂商实现上存在缺陷,那么 安全事件照样发生,而如果被攻击者能有比较好的安全意识或防御方案,那么安全事件也 很难发生。这些通用型的防御方案将在最后一章介绍,本章以W3C标准为起点开始我们的 前端基础介绍。

2.2 URL

URL是垃联网最伟大的创意之一,也就是我们经常提的链接,通过URL请求可以査 找到唯一的资源,格式如下:

scheme〉://<netloc>/<path>?<query>#<fragment>

比如,下面是一个最普通的URL

http://www.foo.com/pa th/f.php ? id=1& type=cool# new

对应关系是:

<scheme> - http

<netloc> - www.foo.com

<path> - /path/f.php

<query> - id=l&type=cool»包括〈参数名=参数值>对

<fragment> - new

对于需要HTTP Basic认证的URL请求,甚至可以将用户名与密码直接放入URL中,

<netoc>之前,格式如:

http://username:password@www.foo.com/

我们接触最多的是HTTP/HTTPS协议的URL,这是Web安全的入口点,各种安全威 胁都是伴随着URL的请求而进行的,如果客户端到服务端各层的解析没做好,就可能出现 安全问题。

URL 有个重点就是编码方式,有三类:escape, encodeURIencodeURIComponent, 对应的解码函数是:unescapedecodeURIdecodeURIComponent»这三个编码函数是有差 异的,甚至浏览器在自动URL编码中也存在差异。

2.3 HTTP 协议

URL的请求协议几乎都是HTTP,它是一种无状态的请求响应,即每次的请求响应之 后,连接会立即断开或延时断开(保持一定的连接有效期),断开后,下一次请求再重新 建立。这里举一个简单的例子,对http://www.foo.com/发起一个GET请求:

GET Foo.com HTTP/1.1

Host: www.foo.com

Connection: keep-alive

Cache-Control: max-age=O

User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML. like Gecko) Chrome/18.0.1025.3 Safari/535.19

Referer: 百度一下,你就知道

Accept: text/html,application/xhtml+xml,application/xml;q=0.9r */*;q=0.8

Accept-Encoding: gzip/deflate,sdch

Accept-Language: zh-CN,zh;q=0  8

Accept-Charset: GBK,utf-8;q=0.7,*;q=0  3

Cookie: SESSIONID=58AB42OB1D8B800526ACCCAA83A827A3:FG=1

响应如下:

HTTP/1.1 200 OK

Date: Sun, 04 Mar 2012 22:48:31 GMT

Server: Apache/2.2.8 (Win32) PHP/5.2.6

Set-Cookie: PTOKEN=; expires=Monz 01 Jan 1970 00:00:00 GMT; path=/; domain=.foo.com; HttpOnly

Set-Cookie: USERID=c7888882e039b32fd7b4d3; expires=Tuer 01 Jan 2030 00:00:00 GMT; path=/; domain=.foo.com

X-Powered-By: PHP/5.2.6

Content-Length: 3635

Keep-Alive: timeout=5r max=100

Connection: Keep-Alive

Content-Type: text/html;charset=gbk

</html>

请求与响应一般都分为头部与体部(它们之间以空行分隔)。对于请求体来说,一般 出现在POST方法中,比如表单•的键值对。响应体就是在浏览器中看到的内容,比如, HTML/JSON/JavaScript/XML等。这里的車点在这个头部,头部的每一行都有自己的含义, keyvalue之间以冒号分隔,下面看看几个关键点。

请求头中的几个关键点如下。

GET Foo.com HTTP/1.1

这一行必不可少,常见的请求方法有GET/POST.最后的“HTTP/1.1”表示1.1版本 的HTTP协议,更早的版本有1.00.9

Host:.www.foo.com

.这一行也必不可少,表明请求的主机是什么。

User-Agent:Mozilla/5.0 (Windows NT 6.l)-AppleWebKit/535.19 (KHTML, like '

: . . 一. - - •.

— Gecko) Chrome/18\0.1025.37Safari/535119 ■/

User-Agent很重要,用亍表明身份(我是谁)。从这里可以看到操作系统、浏览器、

-二-浏览器内核及对应的版本号等信息。Referer: -http:/./www. baidu.com/ . < -

Content-Length: 3635

响应体的长度。

Content-Type: text/html; charset»gbk

响应资源的类型与字符集。针对不同的资源类型会有不同的解析方式,这个会影响浏 览器对响应体里的资源解析方式,可能因此带来安全问题。字符集也会影响浏览器的解码 方式,同样可能带来安全问题。

Set-Cookie: PTOKEN=; expires=Monr 01 Jan 1970 00:00:00 GMT; path«/; domain=.foo.com; HttpOnly; Secure

Set-Cookie: USERID=c7888882e039b32fd7b4d3; expires=Tue, 01 Jan 2030 00:00:00 GMT; path=/; domain=.foo.com

每个Set-Cookie都设置一个Cookie (key=value这样)随后是如下内容。

expires过期时间,如果过期时间是过去,那就表明这个Cookie要被删。

path相对路径,只有这个路径下的资源可以访问这个Cookieo

domain域名,有权限设置为更高一级的域名。

HttpOnly标志(默认无,如果有的话,表明Cookie存在于HTTP层面,不能被客户 端脚本读取)。

Secure标志(默认无,如果有的话,表明Cookie仅通过HTTPS协议进行安全传输)。

请求响应头部常见的一些字段都有必要了解,这是我们在研究Web安全时对各种 HTTP数据包分析的必备知识。

2.4松散的HTML世界

HTML里可以有脚本、样式等内容的嵌入,以及图片、多媒体等资源的引用。我们看 到的网页就是一个HTML文档,比如下面这段就是HTML

<html>

<head>

<title>HTML</title>

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

/*这里是样式*/

body{font-size:14px;}

</style>

<script>

a=l; //这里是脚本

</script>

</head>

<body>

<div>

<hl>这些都是 HTML</hl><br />

<img src=Mhttp: //www. foo.com/logo, jpg" title="这里是图片引用”/>

</div>

</body>

</html>

为什么说HTML的世界是松散的?我们知道,HTML是由众多标签组成的,标签内还 有对应的各种属性。这些标签可以不区分大小写,有的可以不需要闭合。属性的值可以用 单引号、双引号、反单引号包围住,甚至不需要引号。多余的空格与Tab臺不影响HTML 的解析。HTML里可以内嵌CSSJavaScript等内容,而不强调分离,等等。

松散有松散的好处,但这样却培养出了--种惰性,很多前端安全问题就是因为松散导致的。

  1. DOM

DOM树对T Web前端安全来说非常重要,我们的很多数据都存在于DOM树中,通过

DOM树的操作可以非常容易地获取到我们的隐私数据。其实HTML文档就是一个DOM树。

如上面那段HTML,如果用树形结构描述,语句如下。

<html>

- head

-<title>

-HTML

-<meta>

-@http-equiv

Content-Type

-@content

- text/html

-@charset

-utf-8

-<style>

-/★这里是样式"'rAnbody] font-size : 14px;}

- <script>

-a=l //这里是脚本

-<body>

-<div>

-<hl>

-这些都是HTML

-<br />

-<img>

-@src

-http://www.foo.com/logo.jpg

-@title

-这里是图片引用

这个树很简单,<html>是树根,其他都是树的每个节点。这里约定标签节点以<xxx> 表示,属性节点以@XXX表示,而文本节点以XXX表示。

我们的隐私数据可能存储在以下位置:

  • HTML内容中:

浏览器本地存储中,如Cookies等;

  • URL地址中。

这些通过DOM树的査找都可以获取到,仅仅是JavaScriptDOM的操作。如果想了 解更多的细节,可以跳到2.5.】节査看。

2.4.2 iframe内嵌出一个开放的世界

ifi-ame标签是HTML中一个非常重要的标签,也是Web安全中出镜频率最高的标签之 一,很多网站都通过i&ame嵌入第三方内容,比如,嵌入广告页面,语句如下:

<!——AdForward Begin:-->

<if rame marginheight=wOM marginwidth=l,O11 f r amebo r de r=M 0 M width®M820w height»M90w scrolling=Hnow src=whttp://msn.allyescom/main/adfshow?user=MSNI Home_PageI Homepage^2nd_banner_820x90&db=msn&border»0&local=yesH> </iframe>

<!--AdForward End-->

还有Web 2.0网站中嵌入的许多第三方Web游戏与应用,都有使用到iframeo iframe 标签带来了很多便利,同时也带来了很多风险,比如,攻击者入侵一个网站后,可以通过 iframe嵌入自己的网马页面,用户访问该网站后,被嵌入的网马页面就会执行,这种信任 关系导致的安全问题在第1章已介绍过。

iframe标签还有一些有趣的安全话题,当网站页面使用iframe方式嵌入一个页面时,

我们约定网站页面是父页,而被嵌入的这个页面是子页,如图所示。那么父页与子页

之间如何跨文档读写数据?

2-1 iframe父页与子页资源访问

如果父页和子页之间是同域,那就很容易,父页可以通过调用子页的contentwindow 来操作子页的DOM树,同理,子页可以调用父页的contentwindow来操作父页的DOM树。 如果它们不同域,则必须遵守同源策略,但子页还是可以对父页的location值进行写操作, 这样可以让父页重定向到其他网页,不过对location的操作仅仅只有写权限,而没有读权 限,这样就不能获取到父页location URL的内容,否则有可能会造成隐私数据泄漏,比如, 有的网站将身份认证token存在于URL中。

2.4.3 HTML内嵌脚本执行

JavaScript脚本除了出现在JS格式文件里,被嵌入而执行外,还可以出现在HTML<scriptx/script>标签内、HTML的标签on事件中,以及一些标签的hrefsrc等属性的伪 协议(javascript:等)中。

如下几个例子:

<script>alert(1)</scipt>

<img src=# οnerrοr=walert(1)w />

<input type=wtextM value="x,f οnmοuseοver=walert (1)n />

<iframe src=Hjavascript:alert (1) wx/iframe>

<a href=Mjavascript:alert(1)w>x</a>

这样导致防御XSS变得有些棘手,出现在DOM树的不同位置,面对的防御方案都不 太一样。这也为攻击者提供了很大便利,能够执行JavaScript的位置越多,意味着XSS发 生的面也越广,XSS漏洞出现的可能性也越大。

2.5 跨站之魂 JavaScript

Web前端安全中,JavaScript控制了整个前端的逻辑,通过JavaScript可以完成 许多操作。举个例子,用户在网站上都有哪些操作?首先提交内容,然后可以编辑与删 除,那么这些JavaScript几乎都可以完成,为什么是“几乎” ?因为碰到提交表单需要 验证码的情况,JavaScript就不行了,虽然有HTML5canvas来辅助,不过效果并不 会好。

对跨站师来说,大多数情况下,有了 XSS漏洞,就意味着可以注入任意的JavaScript, 有了 JavaScript,就意味着被攻击者的任何操作都可以模拟,任何隐私信息都可以获取到。 可以说,JavaScript就是跨站之魂。

  1. DOM树操作

2.4.1节我们知道了 DOM树,并且提到通过DOM操作能够获取到各种隐私信息。

现在来看看都怎么获取。

1.获取HTML内容中的隐私数据

比如,要获取的隐私数据是用:户的私信内容,内容在DOM.的位置如下'

</head>

<body>

<div id="pr*ivatemsg”>
隐私数据在这••…一

</div>

</body>

在这个DOM树中,id=Wite_msg"的标签也点包含工用户的私信内容,通过JavaScript 可以非常简单地获取:

document  getElementById('private_msg1) innerHTML;

document对象代表整个DOM, getElementByld函数M以获取指定id号的标签对象, 这些标签对象都有一个属性innerHTML,表示标签对象内的HTML数据内容。如果没这个 id号怎么办?是稍微麻烦点,可还是非常简单,可假设包含隐私数据的div标签是DOM树 从上到下的第3个。那么可以用下列语句获取:

document.getElementsByTagName('div')[2].innerHTML;

这时用到的函数是getElementsByTagName.接收的参数就是标签名,返回一个数组, 数组下标从0开始,于是第3个表示为[2]

方法有很多,,大家可以自巳思考。

.2.获取浏览器的Cookies数据 ...

Cookies中保存了用户的会话信息,通过document.cookie W以获取到,不过并不是所 有的Cookies都可以获取,具体内容在2.5.4肯详细介绍。

3.获取URL地址中的数据

window.locationlocation处可以获取URL地址屮的数据。

除了获取数据,还冇通过DOM操作生成新的DOM对象或移除DOM对象。这些都非 常有用,在此推荐査阅JavaScript DOM编程艺术》一书以了解更多的内容。

  1. AJAX 风险

AJAX简直就是廊端黑客攻击中必用的技术模式,全称为Asynchronous JavaScript And XML,即异步的JavaScriptXML这里有切个点:异步、JavaScriptXML

异步和同步对应,异步可以理解为单独开启了一个线程,独立于浏览器主线程去做自 己的事,这样浏览器就不会等待(阻塞),这个异步在后台悄悄进行,所以利用AJAX的攻 击显得很诡异,无卢无息。AJAX木身就是由JavaScript构成的,只是XML并不是必需的, XML在这里是想指数据传输格式是XML,比如,AJAX发出去的■HTTP请求,响应回的 数据是XML格式,然后JavaScript去解析这个XML DOM树得到相应甘点的内容。其实 响应回的数据格式还可以是JSON (已经是主流)、文本、HTML等。AJAX中特别提到XML 是因为历史原因。

AJAX的核心对象是XMLHttpRequest (一般简称为xhr),不过IE 7之前的浏览器不支

Web前端黑客技术掲秘

xhr对象,而是通过ActiveXObject来实现的

•- if (window. XMLHttpRe.qust)「二;

xmlhttp = new. XMLHttpRequst (.}; -// IE7+\ . Firefoxr Chrome,. Opera,-Safari ..

.3mihEpfriew. ActiveXObj6ctC”Mier:ciso£"XMLHTTP”);:7iEN7lEf5 浏览囂的方if ”心*

•X ..y

—卖例化后就是设置好回调二然后发送HTTP请求需要的关部与参数键值广待响应成功"厅

后会触发宓发调,•回调函数就可以处理响应回亲的.•数据了 6忌里需要注意•、不是任何请求"二 .

头都口j以通过JavaScript 14行设置的,否则前端的逻辑隹界就乱T,-W3C给出了二份头部三丄

黑名单:

h "Accept-Charset

.•Accept-Encoding

• ' • : A c c e s s t C o h t r o.l - R e q u e s t - H e a d e r s'. •-'.

Access-Control-Request-Method'

Connection

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莎萌玩家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值