【问题标题】:Bookmarklet security considerations, CSRF, hashed key书签安全注意事项、CSRF、散列密钥
【发布时间】:2011-07-06 16:42:09
【问题描述】:

我的书签可以从任何网站调用,基本上允许用户从远处向他的收藏中插入一行 - 如果他已登录。

现在我想为我的网站启用 CSRF 保护,并且由于书签基本上是非伪造的跨站点请求,我考虑如何将其与伪造的请求区分开来。
这不是一个高安全性的环境,但我对原则也很感兴趣。

我以为我有办法做到这一点,但后来意识到它有很多问题。

最初的想法

  • 生成包含在小书签链接中的随机密钥。密钥的哈希值保存在数据库中。随机密钥仅允许访问插入此集合的特权,不能在其他任何地方使用。
  • 书签从我的服务器加载更长的脚本,因此我可以通过这种方式提供 CSRF 预防令牌
  • 要求用户登录

问题

  • 如果我有书签密钥,是否需要 counter-CSRF 令牌?
  • 如果用户在恶意网站上单击他的书签,我有什么方法可以保护书签密钥?
  • 我不希望用户名和密码存储在书签链接中,因为任何可以访问计算机的人都会得到密码,所以我决定使用随机密钥。
    • 但是如果我只存储哈希值,我就无法生成相同的书签链接两次,因此当用户想要在另一台浏览器/计算机中使用书签时,他不得不从旧链接导入链接或中断对旧链接的支持.
    • 但我不应该存储明文密钥,因为有权访问数据库的人可以使用此密钥将行插入到不属于他的帐户中。
    • 可能的解决方案我可以要求用户在他创建小书签的任何时候提供他的密码并散列密码很多次并将该散列放入 URL 并放入该散列的散列我的数据库。但这当然会带来更糟糕的安全漏洞。
      • 我可以用“母亲的娘家姓”之类的东西来代替
      • 由于随机盐,我不能使用 bcrypt 进行散列,对吗?什么哈希函数是正确的?还是您会放弃整个想法?
  • 如果我不使用小书签密钥,恶意网站可以简单地嵌入小书签并从中提取有效的 CSRF 令牌,对吗?

更好的想法?或者没有 F 就不能有 CSR?


编辑,指定用例

我根本没有想到的一件事是使用 Sripathi Krishnan 建议的 iframe。

我没有指定我的用例,所以是的,iframe 是上述问题的有效解决方案 问题。

然而,实际上我现在的书签确实在运行时与网站进行了一些基本的交互(这意味着表单已经存在,用户可以在网站 DOM 中更改他的选择,这应该会更改表单)。我准备为我的用例取消此功能,如果事实证明,没有合理安全的方法来区分伪造和非伪造的跨站点请求 - 但我仍然对理论层面感兴趣。

【问题讨论】:

  • 查看我修改后的答案以响应您的编辑

标签: security hash bookmarklet csrf


【解决方案1】:

如果不消除伪造部分,您将无法发出跨站点请求。但是对于您的用例,我认为您不需要跨站点请求。

假设您的服务允许用户为他希望的任何页面添加书签。小书签的工作是将 {url, title} 保存到数据库中。同时,要防止恶意网站自动为登录的用户保存网址。

这是我要解决的问题 -

  1. 在您的域上创建一个具有标准 html 表单的页面,该表单具有常规的 CSRF 保护。此页面接受参数 {url, pagetitle},但仅当用户明确单击“保存”按钮时才会保存此元组。
  2. 书签的工作是加载 iframe
  3. 加载 iframe 后,它是一个正常的同源请求

这或多或少是 Google 阅读器作为其书签的一部分所做的。这是它的小书签的代码 - 请注意它没有任何标记

javascript: var b=document.body; var GR________bookmarklet_domain='http://www.google.com'; if(b&&!document.xmlVersion) { void(z=document.createElement('script')); void(z.src='http://www.google.com/reader/ui/link-bookmarklet.js'); void(b.appendChild(z)); } else{}

编辑: 您仍然可以支持与 iframe 方法的交互。小书签在网站的上下文中执行,因此它可以访问 DOM。您可以随心所欲地与网站进行交互。当您准备好保存时,打开 iframe。 iframe 将是一种只有一个保存按钮的确认屏幕。

诀窍是延迟 iframe 的创建。只有在用户准备好保存时才创建 iframe。

【讨论】:

  • 哦。是的,这显然解决了问题,我没有想到,一旦我开始了另一条思路。但是,我没有将我的用例指定为不需要与网站内容进行动态交互。如果我被困在 iframe 中——或者措辞不同——谷歌如何获得网站的标题,这难道不是不可能的吗?
  • 动态交互是可能的。您的小书签可以访问网站的 DOM,因此它可以获取它想要的任何信息。诀窍是将所有数据包含在 iframe URL 中。创建并加载 iframe 后,您将无法进行任何进一步的交流,但这不应该成为问题。
  • 有可能。在您的 Google Reader 用例中,这不是问题。但我无法通过查询字符串传输整个 DOM。我的用例包括在网站上选择两个文本块,在 iFrame 中编辑它们。我可以杀死 dynamically-gets-chunk 方面并依赖复制粘贴,但我对合法 CSR 的兴趣尚未熄灭。将编辑帖子。
  • 您不限于 GET / Query String。小书签可以使用整个 HTML 创建一个动态表单,然后将其发布到您的服务器。表单的目标应该是您显示的 iframe。
  • 哦,是的。如果网站在创建 iFrame 后通过 Ajax 更改其内容,则必须重新加载 iframe,对吗?因此,当您以 iframe 方式执行此操作时,会丢失一个假设的(在我的情况下甚至是真实的,尽管并不重要)功能。
【解决方案2】:

如果书签存储在网络浏览器中,那么在数据库中包含一个散列的密钥是一个好主意。这将阻止 CSRF,尽管它并不理想,因为从某种意义上说,这是一个不会超时的会话 id。应该清楚的是,此令牌仅用于此小书签操作。尽管有此限制,但您不太可能受到攻击。添加 HTTPS 将使其更强大,因为它会更难溢出此令牌。

如果小书签来自第 3 方网站,则您无能为力。这就是 CSRF 的定义。

【讨论】:

  • 是的,书签是我的,将存储在网络浏览器中。但是,与永久会话 ID 不同,它可以被调用它的网站读取,我正在尝试提出对策(但我不确定这在原则上是否不可能)。我意识到这是一个不太可能发生的情况,尤其是在我的情况下。我只是好奇。持久性不理想是很清楚的,这就是为什么我认为必须将登录作为辅助要求。 & 当我只存储哈希时,我想知道如何获得所说的持久性。
猜你喜欢
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多