标签: html html5 web安全javascript
w3school:html5相关基础知识(w3school.com.cn)html
51CTO的HTML5安全专题html5
FREEBUFF上有关HTML5的安全文章(FREEBUFF搜索关键词:html5)java
相关技术博客和杂文(百度搜索关键词:html5 安全)web
html5相关新技术ajax
跨域资源共享(CORS)安全问题sql
本地数据库注入(Web Sql Injection)数据库
本地存储风险(Local Storage and Session Storage)json
js多线程(Web Worker)风险canvas
Web Socket带来的嗅探风险
新标签风险
新API风险
XMLHttpRequest主要提供了js直接发送请求的接口,在老版本中有如下缺点:
只能支持文本数据传送,其余数据不可
没有即时进度信息,只有完成与否的状态
不能跨域传输,只能同域内进行传输
在新版本的XMLHttpRequest中(level 2),以上都获得了实现,其中最关键的是能够在服务器和浏览器自己的支持下进行跨域传输。
在html5以前,本地存储只有cookie(flash cookie)这么一种选择,可是cookie的容量很小,而且安全性上得不到保障。
在html5中,新增了两种存储方式:local storage
和session storage
,local storage是永久性的存储,大小大概是5MB, session storage时临时的,浏览器关闭即刻清空。其实这两个东西是一个东西,放在内存中是session storage,在文件系统中是local storage。
同时,html5提供了本地数据库支持,默认是sqlite这一轻量级的数据库,能够存储一些临时资料或者缓存。
因为js时单线程执行的,因此在h5以前,执行js是会阻塞UI的,h5实现了web worker这一机制,从而使得js也可使用子线程去执行任务从而不阻塞主UI线程了。
因为http时无状态单链接的协议,因此在过去,只能是客户端发送request,服务器响应response,如今h5实现了websocket这一机制,从而能够保持长连接,服务器能够主动推送信息到客户端了。固然须要服务器支持websocket机制。
具体使用方式
h5新实现了一些比较便捷的标签和api,使得用户对第三方插件的依赖能过有所减小,从而减小不可控安全问题。
好比<video>
,<audio>
,<canvas>
等等。
同时实现了比较多的新的api,好比地理位置api,putstate等等。
具体请查看:w3school.com.cn
ajax在以前是要严格遵照同源策略的,可是在h5中为了提供更好的使用性,诞生了ajax跨域的方式-CORS。跨域资源共享是为了解决跨域请求的问题的。
除了CORS这个方案,还有另外两种跨域请求的方法,一个是使用jsonp的方式,一个是使用flash的跨域方案,经过服务器上的crossdomain.xml来控制跨域。
CORS的跨域方式是经过:Access–Control-Allow-Origin这个头以及其余的头来实现的,客户端跨域访问一个服务器,服务器会肯定这个这个域名是否有权限来获取资源,如有则返回一个带有Access–Control-Allow-Origin头的response以及资源。若无则返回一个权限错误:XMLHttpRequest cant load .....
(1). 对Access–Control-Allow-Origin设置为*,而且没有携带会话认证,这样子意味着信息被公开在全网。
(2). http头能够伪造。http能够伪造意味着http头中的域名(origin)能够是假的,因此跨域是要配合身份验证进行的,因此跨域的时候记得带上session id。
(3). 就算是使用了session id,可是第三方有可能也会被入侵,从而致使源站信息泄露,因此CORS是一个很是危险的东西。
(4). 内部信息泄露,内部成员打开一个evil website,致使我的会话信息泄露,那么内部网站的数据将会泄露
(5). 另外,不是设置了Access–Control-Allow-Origin,而且对请求站点作了权限控制,就能够防止信息泄露,在返回权限错误的时候,请求的信息其实已经到了客户端。
(6). CORS默认不能携带会话信息,可是若是将withCredentials设置为true,则能够携带,因此这个属性最好设置为false。万一须要设置为true,请在Access–Control-Allow-Origin上设置具体的域名,不要使用 *。这是CORS的最后一层遮羞裤了,设置很差就裸奔了。
不要对Access–Control-Allow-Origin使用 *
要对跨域请求验证session信息。
严格审查请求信息,好比请求参数,还有http头信息。
CORS主要是提供了一种隐形的跨域数据传输方式,偷取信息用户是不能感觉到的,主要是两种利用方式。
第一个是须要将跨域js植入到被攻击的页面,这样子能够劫持到对方的cookie等认证信息。这种方式就是经过一个xss或者sqli,将js植入目标服务器,这样子就能够将认证信息偷过来了,若是是存储型就就更赞了,能够实时更新认证信息。
第二个是将跨域放在本身控制的网站上,经过用户点击来攻击指定由CORS漏洞的服务器。这个要求目标服务器对CORS没有设置好,有CORS配置漏洞。
另外ajax跨域不存在问题了,那么是否是CSRF也能够更隐蔽的进行了呢
这里的本地存储主要指的是localstorage和sessionstorage。其余的好比windows.history,png cache等等不作讨论。
就如余弦说的,localstorage是大势所趋,由于随着网站的复杂性升级,cookie最多只能有4k,每一个网站只能存放30或者50个cookie,这样大大制约了web的发展。因此localstorage和sessionstorage出现了(后面将不分开讨论)。
localstorage使用只能经过js去进行写入或者读取,存放格式为key-value格式,好比localStorage.set("key","value")
.这个意味着他没有cookie那么安全。
js获取,由于是只能经过js设置和获取,致使的结果是不能像cookie同样设置httponly。因此能够配合CORS来获取网站的localstorage的信息。因此localstorage中不能存放敏感信息。
由于在各大主流的浏览器中,除了opera采用base64加密,其余都是采用明文存储的,因此在存储的时候最好在服务器端进行加密。
还有一个,可能会被植入广告追踪标志。
不要存放敏感信息。
选择合适的域存放合适的信息,好比一次过时的信息就放在sessionstorage中。
对存放在其中的信息最好可以在服务端进行加密。
配合CORS或者XSS获取本地存储中的数据。
H5在以前引入了本地SQL这个东西,可是后面被废除了,他的安全点和后台数据库的关注点差很少,就是要防止在数据中混入sql查询指令。这里再也不展开。
H5中“解决”了js单线程问题,提出了web worker机制,它为js提供多线程支持,可是多线程带来了一个很是可怕的危险-僵尸网络。
var worker = new Worker("worker.js"); worker.postMessage("hello world"); worker.onmessage = function(){}
风险点只有一个,那就是在用户不知情的状况下,使用pc端的资源往外发送大量的请求,若是受控的客户端(僵尸)够多,而且针对某一个目标发送,能够形成应用层的DDOS。(虽然是异域,可是不须要CORS配合,由于CORS只是限制客户端是否可以拿到服务器的数据,而不会限制发送这个事情)
其实这里还有一个postMessage
的问题,放到API风险那个小结。
不要访问不安全的站点
用户注意观察客户端资源占用状况,发现某个页面资源占用反常就关掉。
很是清晰,写一个webworker,而后注入到一些页面中去,只要访问这个页面,web worker就开始工做。
H5的web socket 颠覆了传统的http通讯方式(request-response),他经过创建一个长连接,让服务器能够随时推送消息给客户端,而不是采用轮询的方式去作这个事情。
他是经过开启另一个非80的端口去作这件事情。从而致使嗅探的可能性。
H5引进了不少新的标签,好比<video><audio><cavans>
等等,具体的能够去w3school查看。
新标签意味着以前指定的xss过滤或者转义规则可能会不适用。
新的方式以下:
<video onerror=alert(1)><source> <video><sourceonerror="javascript:alert(1)" <video src=".." onloadedmetadata="alert(1)" ondurationchanged="alert(2)" ontimeupdate="alert(3)"></video> <video><sourceonerrorsourceonerrorsourceonerrorsourceonerror="javascript:alert(1)“> <videopostervideopostervideopostervideoposter=”javascript:alert(1)”>
待补充#todo
新方式以下:
<form id="test" /><button form="test" formaction="javascript:alert(1)">X <form id=test onforminput=alert(1)><input></form><button form=test on formchange=alert(2)>X <input onfocus=write(1) autofocus>
待补充#todo
更多可查看:HTML5 标签安全
postMessage是web worker中的一个函数,它的做用是主线程给新线程post数据用的,可是有一个问题就是postMessage是不经过服务器的,那么颇有可能形成DOM-based XSS。
防护方式
可是postMessage的防护点不在自己,而在onmessage上,onmessage中不能直接使用innerHTML相似的语句添加或者修改网页。
利用方式:
postMessage("<script>alert(1)</script>"); worker.onmessage = function(e) { document.getElementById("test").innerHTML = e.data; }
H5在History API新增了两个API:pushState()和replaceState(),这两个方法能够在不刷新页面的状况下添加或者修改历史条目
pushState(data,title [, url])
他的做用是在浏览器历史列表的站定添加一条记录,一个是状态,一个是标题,一个是URL(可选,同域)
replaceState(data,tile [,url])
参数和上一个相同,它的做用是更改当前页面的历史纪录。
利用方式:
能够利用他来假装GET方法下的反射型xss。
好比,存在一个有漏洞的连接 http://www.foo.com/?a=1
,能够进行XSS注入,如:http://www.foo.com/?a=<script>alert(1)</script>
可是若是这么直接写在页面上让用户点击,通常都会发现有问题,因此能够采用短连接的方式,假设上述连接转换为:http://www.foo.com/TqsjW
,用户应该会点过去了,可是点过去以后,URL栏中仍是原来的长连接,一样会被发现。
可是这么写的话:
http://www.foo.com/?a=<script>history.pushState({},'',location.href.split("?").shift();alert(1))</script>
将他转换成短连接,点击以后,会转换到http://www.foo.com/
这个上面,因此就完美的隐藏了。