关于html5:本地存储可以被认为是安全的吗?

Can local storage ever be considered secure?

我需要开发一个长期离线运行的Web应用程序。为了实现这一点,我不能避免在本地存储中保存敏感数据(个人数据,而不是您只存储哈希的数据)。

我接受这不是推荐的做法,但几乎没有选择,我正在执行以下操作来保护数据:

  • 使用斯坦福javascript加密库和AES-256加密所有进入本地存储的内容
  • 用户密码是加密密钥,不存储在设备上
  • 通过SSL从单个受信任服务器提供所有内容(联机时)
  • 正在使用owasp反艾米项目验证服务器上所有进出本地存储的数据
  • 在appcache的网络部分,不使用*,而是只列出与受信任服务器连接所需的URI。
  • 一般来说,尝试应用OWASP XSS备忘表中建议的指导原则

我很欣赏这个魔鬼经常出现在细节上,我知道人们对本地存储和基于javascript的安全性有很多怀疑。有人能评论一下是否有:

  • 上述方法的根本缺陷?
  • 有没有可能解决这些缺陷?
  • 当HTML5应用程序必须长时间脱机运行时,有没有更好的方法来保护本地存储?

谢谢你的帮助。


网络加密

下面详细介绍了客户端(浏览器)JavaScript中的加密技术问题。除了一个以外,所有这些问题都不适用于WebCryptoAPI,它现在得到了相当好的支持。

对于离线应用程序,您仍然必须设计和实现一个安全的密钥库。

旁白:如果您使用node.js,请使用内置加密API。

本机javascript加密(pre-webcrypto)

我认为最主要的问题是有人可以物理访问你的站点的localStorage,而你希望加密技术帮助阻止这种访问。

如果有人有物理访问权限,你也会受到其他攻击,比阅读更糟糕。这些包括(但不限于):键盘记录器、脱机脚本修改、本地脚本注入、浏览器缓存中毒和DNS重定向。只有当用户在机器受到威胁后才使用机器时,这些攻击才会起作用。然而,在这种情况下,物理访问意味着您有更大的问题。

因此,请记住,如果机器被盗,本地加密的价值有限。

有些库确实实现了所需的功能,例如斯坦福JavaScript加密库。不过,也存在一些固有的弱点(如@ircmaxell答案中的链接所述):

  • 缺乏熵/随机数生成;
  • 缺少安全密钥库,即如果将私钥存储在本地或存储在服务器上(禁止脱机访问),则必须对其进行密码保护;
  • 缺乏安全擦除;
  • 缺乏定时特性。
  • 这些弱点中的每一个都对应着一类密码妥协。换言之,虽然您可以通过名字来"加密",但它将远远低于您在实践中所追求的严格性。

    尽管如此,精算评估并没有"javascript加密很弱,不要使用它"那么简单。这不是一个认可,严格来说是一个警告,它要求你完全理解上述弱点的暴露,你所面对的向量的频率和成本,以及你在失败时的缓解或保险能力:尽管javascript加密有弱点,但它可以减少你的暴露,但只针对小偷技术能力有限。但是,您应该假设javascript加密对于目标是该信息的确定且有能力的攻击者没有价值。有些人会认为,当已知有如此多的弱点是实现固有的时,将数据称为"加密"是一种误导。换句话说,你可以稍微减少你的技术风险,但是你可以通过披露增加你的财务风险。当然,每种情况都是不同的——减少财务风险的技术风险的分析是非常重要的。这里有一个说明性的类比:尽管存在固有的风险,一些银行仍然需要弱密码,因为它们面临的弱密码损失比支持强密码的最终用户成本要低。

    ?如果你读到最后一段,认为"互联网上有个叫布莱恩的人说我可以使用javascript加密",不要使用javascript加密。

    对于问题中描述的用例,用户加密本地分区或主目录并使用强密码似乎更有意义。这种类型的安全性通常都经过了良好的测试,得到了广泛的信任,并且普遍可用。


    这里的基本前提是:不,它还不安全。

    基本上,你不能在javascript中运行加密:javascript加密被认为是有害的。

    问题是,您不能可靠地将密码输入浏览器,即使可以,JS也不能让您安全地运行它。因此,在浏览器拥有加密容器(加密的媒体扩展提供了该容器,但为了DRM的目的而进行了重新组合)之前,将不可能安全地执行此操作。

    至于"更好的方法",目前还没有。您唯一的选择是以纯文本形式存储数据,并希望得到最好的结果。或者根本不存储信息。不管怎样。

    或者,如果您需要这种安全性,并且需要本地存储,请创建一个自定义应用程序…


    作为对这个主题的探索,我有一个题为"使用Web密码API保护todomvc"(视频、代码)的演示。

    它使用Web加密API通过密码保护应用程序和使用密码派生密钥进行加密来存储在本地存储中加密的TODO列表。如果忘记或丢失密码,将无法恢复。(免责声明-这是一个POC,不用于生产。)

    正如另一个答案所说,这仍然容易受到安装在客户端计算机上的XSS或恶意软件的影响。但是,当数据存储在服务器上并且应用程序正在使用时,任何敏感数据也将在内存中。我建议离线支持可能是令人信服的用例。

    最后,加密localstorage可能只保护数据不受对系统或其备份具有只读访问权限的攻击者的攻击。它为OWASP前10项A6敏感数据曝光增加了少量的深度防御,并允许您回答"这些数据中是否有任何一个长期以明文形式存储?"正确地。


    这是一篇非常有趣的文章。我正在考虑实现JS加密,以便在使用本地存储时提供安全性。很明显,这只会在设备被盗(并正确实施)的情况下提供保护。它不会提供对键盘记录器等的保护,但这不是JS问题,因为键盘记录器威胁是所有应用程序的问题,无论其执行平台(浏览器、本机)如何。对于第一个答案中引用的"javascript加密被认为有害"一文,我有一个批评意见:它指出"您可以使用ssl/tls来解决这个问题,但这是昂贵和复杂的"。我认为这是一个非常野心勃勃的主张(可能有很大的偏见)。是的,SSL是有成本的,但是如果考虑到为多个操作系统开发本机应用程序的成本,而不是仅仅因为这个问题而基于Web,那么SSL的成本将变得微不足道。

    我的结论是,客户端加密代码有一个位置,但是与所有应用程序一样,开发人员必须认识到它的局限性,并在适合其需求的情况下实施,并确保有减轻风险的方法。


    不可访问任何网页(true),但可通过开发工具(如chrome(ctl-shift-j))轻松访问和编辑。因此,在存储值之前需要自定义加密。

    但是,如果javascript需要解密(验证),那么解密算法就会被公开并可以被操作。

    Javascript需要一个完全安全的容器,并且能够正确地实现仅对JS解释器可用的私有变量和函数。但是,这违反了用户安全——因为跟踪数据可以不受惩罚地使用。

    因此,JavaScript永远不会完全安全。


    不。

    任何网页都可以访问localstorage,如果您有密钥,您可以更改所需的任何数据。

    也就是说,如果您能够设计一种安全加密密钥的方法,那么无论您如何传输数据,如果您能够在一个闭包中包含数据,那么数据(在某种程度上)是安全的。