Javascript安全问题

JAVASCRIPT SECURITY

JavaScript安全性

自发布以来,已经出现了一些引起广泛关注的JavaScript安全问题。首先,JavaScript与DOM交互的方式使恶意行为者通过Web传递脚本并在客户端计算机上运行脚本,从而给最终用户带来风险。可以采取两种措施来控制此JavaScript安全风险。首先是沙箱,或单独运行脚本,以便它们只能访问某些资源并执行特定任务。第二项措施是使用同源策略,该策略可防止来自一个站点的脚本访问其他站点的数据。许多JavaScript安全漏洞是浏览器作者未能采取这些措施来包含基于DOM的JavaScript安全风险的结果。

基于 DOM 的跨站点脚本

存在 DOM based XSS 的 HTML 代码

1
2
3
4
5
6
7
8
9
10
11
<HTML>
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf("name=")+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome to our system

</HTML>

按照该页面 JavaScript 代码逻辑,它会接受 URL 中传入的 name 参数并展示欢迎信息

正常情况下的访问 URL

http://www.xss.com/welcome.html?name=pwn

但如果恶意攻击者输入类似如下的脚本,该页面则会执行被注入的 JavaScript 脚本。

http://www.xss.com/welcome.html?name=<script>alert(document.cookie)</script>

值得关注的是,通过以上示例可以看出,恶意代码不需要嵌入服务器的响应中,基于 DOM 的跨站点脚本编制攻击也能成功。可能某些读者会认为:目前主流浏览器会自动转义 URL 中的 ‘<’ 和 ‘>’ 符号,转义后的注入脚本就不会被执行了,基于 DOM 的跨站点脚本编制也就不再有什么威胁了。这句话前半段是对的,但后半段就不准确了。我们要意识到攻击者可以很轻松地绕过浏览器对 URL 的转义,譬如攻击者可以利用锚点 ‘#’ 来欺骗浏览器,下面的POC中,浏览器会认为 ‘#’ 后面的都是片段信息,将不会做任何处理。

http://www.xss.com/welcome.html#?name=<script>alert(document.cookie)</script>

通过 URL 重定向钓鱼

网络钓鱼是一个通称,表示试图欺骗用户获取用户的PII信息,以便电子欺骗身份。通过 URL 重定向钓鱼指的是 Web 页面会采用 HTTP 参数来保存 URL 值,且 Web 页面的脚本会将请求重定向到该保存的 URL 上,攻击者可以将 HTTP 参数里的 URL 值改为指向恶意站点,从而顺利启用网络钓鱼欺骗当前用户并窃取用户凭证。清单 5 给出了较为常见的含有通过 URL 重定向钓鱼漏洞的代码片段。

依然是看一段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<SCRIPT>

var sData = document.location.search.substring(1);
var sPos = sData.indexOf("url=") + 4;
var ePos = sData.indexOf("&", sPos);
var newURL;
if (ePos< 0) {
newURL = sData.substring(sPos);
} else {
newURL = sData.substring(sPos, ePos);
}
window.location.href = newURL;

</SCRIPT>

可以看出,这些 JavaScript 脚本负责执行重定向,新地址是从 document.location、document.URL 或者 document.referer 等 DOM 元素的属性值中截取出来的,例如下面的示例链接

http://www.vulnerable.site/redirect.html?url=http://www.phishing.site

显然用户一旦执行了该URL,将被重定向到钓鱼网站。这个漏洞的原理很简单,比服务器端的重定向漏洞更好理解。但通过 URL 重定向钓鱼的情况下,钓鱼站点的网址并不会被服务端拦截和过滤,因此,这个漏洞往往比服务器端重定向漏洞更具有隐蔽性。

Cookie 通常由 Web 服务器创建并存储在客户端浏览器中,用来在客户端保存用户的身份标识、Session 信息,甚至授权信息等。客户端 JavaScript 代码可以操作 Cookie 数据。如果在客户端使用 JavaScript 创建或修改站点的 cookie,那么攻击者就可以查看到这些代码,通过阅读代码了解其逻辑,甚至根据自己所了解的知识将其用来修改 cookie。一旦 cookie 包含了很重要的信息,譬如包含了权限信息等,攻击者很容易利用这些漏洞进行特权升级等攻击。但还好我们有HTTPonly来保护我们的cookie不被恶意读取。

JavaScript 劫持

许多 Web 应用程序都利用 JSON 作为 Ajax 的数据传输机制,这通常都容易受到 JavaScript 劫持攻击,传统的 Web 应用程序反而不易受攻击。JSON 实际上就是一段 JavaScript,通常是数组格式。攻击者在其恶意站点的页面中通过 SCRIPT 标签调用被攻击站点的一个 JSON 动态数据接口,并通过 JavaScript Function Hook 等技术取得这些 JSON 数据。如果用户登录被攻击网站后(假定其身份认证信息是基于 Session Cookie 来保存的),又被攻击者诱引访问了恶意站点页面,那么,由于 <SCRIPT src=”> 这种标签的请求会带上 Cookie 信息,恶意站点会发送 JSON 数据获取请求至被攻击站点,被攻击站点服务器会认为当前请求是合法的,并返回给恶意站点当前用户的相关 JSON 数据,从而导致用户数据泄密。整个过程相当于一个站外类型的跨站点请求伪造 CSRF 攻击。
随着 Ajax 的进一步推广,以及 HTML5 的逐步应用,还有更多的客户端安全漏洞出现。目前对于 JavaScript 的安全研究尚不多,新推出的 HTML5 客户端存储、跨域通信等新特型也都跟安全紧密相关。

一些防御的姿势

其他前端安全防范实践

1)更安全的使用Cookie

避免泄露Cookie信息的有效方式是设置Cookie的HttpOnly,即禁止了对JavaScript操作Cookie。

另外一个和安全相关的设置,即Secure。设置了Secure的Cookie只能在浏览器使用HTTPS请求时被发送到服务器端。如果站点使用了SSL,则应该启用Cookie的Secure设置。

Cookie的另外两个常用的设置是domain(域)和path(路径),这两个设置是用来确定Cookie作用域范围的。

2)防止网页被其他网站内嵌为iframe

传统的方式是使用JavaScript代码来阻止网页被其他网页嵌套。

浏览器也支持通过设置X-Frame-Options响应头来控制页面被其他页面内嵌。X-Frame-Options有三种设置选项:DENY、SAMEORIGIN及ALLOW-FROM uri,分别表示禁止、允许相同域及特定域页面内嵌此页面。