像Javascript的客户端技术中,存在许多有用的特色。这是造就了它为世界上最受欢迎的编程语言的原因。Javascript特色突出许多优点,其一便是即时编译。这有一些益处,比如,浏览器可以边下载内容边执行代码。不过,这种层次的自由也来了责任。
本文中,我们将共同探索JavaScritp的安全风险。这里只会包含在浏览器运行的前端代码,以后的文章中,我们再关注其它的方面。
设想下浏览器为了执行JavaScript必须做些什么。首先,浏览器必须下载页面,并开始解析。浏览器不会等待所有的内容下载完成后才采取解析,它有能力同时边下载边解析界面。那么,浏览器遇到Javascript代码时,发生了什么呢?
Javascript是渲染阻塞的,当它执行的时候,这会有一个巨大的优点。这意味着,浏览器将会暂停解析,先执行代码后,再继续解析。这让我们在使用这门编程语言时具有根本的灵活性,也让代码面临任何可能性。
不过,问题是如此特点将会造成什么影响呢?
为了解释,看下面的代码片段:
<div id="hack-target"></div>
<button>Set Value</button>
<script>
document.querySelector('button').addEventListener('click', setValue);
function setValue() {
var value = '2';
document.getElementById('hack-target').innerText = value;
}
</script>
上述代码声明了一个HTML中的一个目标(hack-target),并连接了事件。当你单击按钮时,函数调用触发。
对于客户端Javascript,我们可以在代码设置值的地方设置断点。事件触发,断点会激活。这个值可以通过 varvalue='2';
任意改变。调试器暂停执行,这就可以允许他人能够篡改该页面。这个特点非常伟大,并且即使程暂停执行发生了,浏览也不会做任何提示。
由于调试器暂停了执行,它也能够暂停页面渲染。调试器是内置在浏览器工具的一部分,因此任何人都可以使用。它们就是web开发者工具。
想要查看该技术的运行,可以查看这个页面Code Pen。下面是该特点的一个截图:
该特色非常有利于调试Javascript,但是这对于安全而言,意味着什么?
这意味着攻击者可以在运行的时候修改Javascript。攻击者可以攻击断点(hit a breakpoint),改变DOM并在调控台输入任意的Javascript。这种攻击利用了客户端的缺陷。攻击者可以在页面上改变数据,劫持session,做任意的Javascript改变。
例如,在打开Web开发者工具的情况下,任何人都可以选择调控台(Console)选项,并输入:
document.querySelector('button').addEventListener('click', function () { alert('sacked'); });
下次该事件触发的时候,就会触发此处Javascript的改变。
你可能会问的是,为什么一切会变成这样呢?当时,Netscape在1995年发布Javascript。该新的编程语言成为了互联网的“粘合语言(glue language)”。
Netscape向Ecma国际(Ecma International)提交他们的Javascript标准,并且恰好他们的版本成为了标准,也就是更为大家所知的ECMAScript。由于ECMAScript已标准化的事实,任何声明支持ECMAScript的浏览器厂商就必须遵循该标准,这样代码在不同浏览器下运行时就不会引发冲突。这意味着你在Google Chorome下写的脚本,同样也必须能够Opera,NetScape,IE以及微软Edge上运行。
JavaScript的创建围绕灵活性,该灵活性赋予你使用它想做任何事情的必要能力。JavaScipt的动态本性就是流淌自这种设计模式。这让它成为了浏览器的事实标准语言。
与现在而言,所有的这些都是古老的历史,但是至于JavaScript安全呢?
为了防止恶意JavaScript,最好的选择是增加运行时保护。运行时应用自我保护(Runtime Application Self-Protection,简称RASP)将在运行期间保护客户端代码。由于web的灵活、动态特性,诞生了运行时安全的需求,这是因为攻击者可以在客户端随意改变JavaScript。
RASP是保护客户端应用最有效方式,它的总结如下:
运行时应用自我保护是一种安全技术,这种安全技术内置入应用或者链接应用的运行时环境,能够控制应用执行,侦测并阻止实时攻击。
一旦Javascipt影响浏览器,便无法彻底地安全保护它的执行。RASP只是能够防止在运行期间发生的调试和代码篡改攻击。这包括修改应用的攻击,即使应用处于离线。一个好的RASP方案是可以混杂代码,以至于攻击无法使用自己的方案篡改代码,并能轻松地越过它。这几层防护保障了开放web的安全。
如果RASP解决方案再好的化,当攻击者尝试阻止代码时,它能够发出提醒。这能够让我们知晓,并采取行动,例如取消用户的session。
Jscrambler 提供一种RASP解决方案,它能够保护应用免于遭受运行时攻击。Jscramber具有自我防护性,并能够侦测攻击。这种自我防护能力增加了对于JavaScript应用的保护。Jscrambler使用反调试和反篡改技术(非常知名的应用保护理念),但是对于JavaSript有着特殊的现实性和限制性。反调试侦测调试工具的使用(如DevTools,FireBug),并且尝试阻止方向工程使用它来调试程序。这里是通过代码陷阱实现,导致调试工具停止工作,并且调用栈增长,阻止用户侦测应用的控制流。反篡改侦测代码改变,并作出相应反应。例如,如果你从一个具有自我保护性的的函数增加或删除一个分号,它能够侦测那个改变,并使代码停止运行。两种技术与混杂代码共同致使其无法篡改该应用。
实现JavaScript的安全必须考虑运行时发生了什么。从其本身而言,这种web动态语言本身很灵活。同任何好的双刃剑一样,你必须负责任地使用它。
往期精选文章 |
---|
使用虚拟dom和JavaScript构建完全响应式的UI框架 |
扩展 Vue 组件 |
使用Three.js制作酷炫无比的无穷隧道特效 |
一个治愈JavaScript疲劳的学习计划 |
全栈工程师技能大全 |
WEB前端性能优化常见方法 |
一小时内搭建一个全栈Web应用框架 |
干货:CSS 专业技巧 |
四步实现React页面过渡动画效果 |
让你分分钟理解 JavaScript 闭包 |
小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。