如何在JavaScript中清除敏感内存?

5

我有一个登录表单,用户需要输入密码。该表单绑定了AngularJS模型。假设在相应的控制器中,用户输入的密码可以通过$scope.password获得。

实际的登录过程由此函数调用处理:login($scope.email, $scope.password)。在此过程之后,应用程序逻辑不再需要密码,我的愿望是从浏览器内存中清除它。

对我来说,最明显的问题是:在调用login($scope.email, $scope.password)之后,我可以做什么来清除当前绑定到$scope.password的值所占用的内存?希望这个问题对JavaScript一般都是有效的。

但接下来,我有两个更具体的AngularJS问题:

  • 密码表单值是否绑定到多个AngularJS内部变量而不仅仅是$scope.password?如果是这样,覆盖$scope.password将无效。

  • 当切换视图时,对应旧视图的控制器及其作用域会被“销毁”。我是否应该简单地依赖垃圾回收来在切换离开登录视图后的短时间间隔内清除包含密码的内存?


2
你试图解决的问题是什么?实际上,你无法在JavaScript中做到这一点,因为运行时不能控制字符串原始值在垃圾回收时会发生什么。 - Pointy
@Pointy:如果这就是你想要表达的意思,“从内存中清除密码通常不会被执行或者无法以可靠的方式实现”,那么我认为这已经是一个答案了。这是我正在开发的第一个基于JavaScript的大型客户端应用程序,当然我对最佳实践方法很感兴趣。 - Dr. Jan-Philip Gehrcke
问题在于Web应用程序必须依赖一组安全相关的行为,由客户端浏览器正确实现。例如,保护免受跨站点请求攻击和正确实现cookie安全等都是您的代码必须信任的类似事情。每个窗口(或者说每个窗口家族)都有一个隔离的JavaScript运行环境。此外,由于没有底层的原始内存分配,因此真正没有办法扫描空闲内存(除非利用浏览器漏洞)。 - Pointy
为什么你这么专注于内存攻击呢?几乎每个需要标准登录表单的网络应用都有可能面临内存攻击的风险。我不确定这是否是你需要关注的事情。 - Neil Smithline
显示剩余3条评论
3个回答

9

由于各种与Web浏览器相关的情况都不能对浏览器内存的内容做出承诺,因此您永远无法确定是否正在清除内存。

考虑以下简单的JS代码:

x=1234;
x=5678;

即使在这么简单的代码片段中,您也无法保证已经从内存中删除了1234。您只知道当引用x时,它的值将为5678。您不知道5678是否覆盖了1234,还是写入了一个新的内存位置。
同样地,一旦用户输入其密码以响应包含以下内容的表单:
<input type="password" name="p">

您无法保证您能够永久擦除保存密码的内存,即使您再次运行表单也不行。
唯一避免这些限制的方法是编写一个运行为桌面应用或浏览器插件的胖客户端。
请注意,以上内容并不意味着浏览器在其内存中松散处理机密。它们通常会尝试防止内存检查漏洞。只是您无法了解它们如何操作以及如何利用它们。即使您了解了,它也将针对每个浏览器版本具体实现。
因此,除非您感觉需要更好地保护密码(例如银行密码),否则必须接受将用户密码放入(希望)值得信赖的浏览器手中的事实。

6

1
如果这对您的应用程序是真正的风险,那么您唯一的选择就是创建一个与应用程序分开的登录页面。
您可以使用标准的登录表单来提交密码,响应将强制浏览器获取新页面,并忽略所有现有的带有密码的内存。

1
这个问题是关于如何清除内存中的密码。你无法控制浏览器中的内存管理方式。你所建议的最好情况只是释放了内存,但并没有真正清除它。内存扫描或进程转储仍然可能包含明文密码。 - Neil Smithline
真的。我所提到的风险是客户端应用程序中的一个漏洞,可以在密码提交后读取保存密码的JavaScript变量。例如,alert(pwVar)。通过为应用程序和密码表单强制使用单独的执行环境,您可以消除变量泄漏的可能性。 - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接