如何保护小部件免受伪造请求的侵害

How to protect widgets from forged requests

本文关键字:伪造 请求 何保护 保护 小部      更新时间:2023-09-26

假设你有一个JavaScript小部件,当且仅当用户想要点击它时,它需要向你的web应用程序发出请求。您不希望这个请求容易受到CSRF的攻击,所以您向页面写入了一个iframe。根据源继承规则,父站点将无法读取CSRF令牌。但是点击劫持(或点赞劫持)呢?由于CSRF,您必须在iframe内,而x-frame选项不起作用,对于frame-busters也是如此。

攻击者将在小部件加载后对iframe应用SVG掩码。这个掩码将使iframe不可见。此时,攻击者可以将iframe的大小调整为页面的大小,或者让这个现在不可见的iframe跟随光标。无论何时用户单击页面上的任何位置,iframe都会收到单击事件,游戏结束。

所以有一个二元性,你似乎被困在CSRF和Clickjacking之间。对这个问题最好的解决办法是什么?

单击小部件需要打开一个包含新页面的弹出窗口- iframe不够好,它必须是一个新窗口-这完全在您的web应用程序的控制之下。确认该操作,无论它是什么,在该页

是的,这有点不优雅,但是目前的Web安全体系结构并没有给您更好的选择。

在点击劫持攻击下没有办法防止请求伪造。没有任何CSRF防御可以抵御点击劫持攻击,因为在客户端没有办法区分真正的点击和虚假的点击。

OWASP在他们的CRSF预防电子表格中提到,CSRF令牌防御工作的先决条件之一是没有XSS攻击正在进行。

在我看来,这也应该包括点击劫持,因为CSRF令牌即使隐藏在iframe内也无法防御点击劫持。请求是由直接用户点击伪造的。

所以最后我们并没有真正被困在CSRF和Clickjacking之间——CSRF防御是针对不同类型的攻击,攻击者的力量要小得多。

对于你提到的关于点击劫持和CSRF的问题:

  • 这个问题的最佳解决方案是什么?—在客户端防范点击劫持的最好方法是打开一个新的浏览器选项卡或一个调整大小的浏览器窗口,从你的站点打开一个页面,并确认那里的操作,正如@Zack提到的。这就是twitter按钮的作用,在这种情况下也不能有请求伪造。

  • 所以有一个二元性,似乎你被卡在CSRF和Clickjacking之间 - CSRF防御并不意味着像XSS或Clickjacking攻击这样的情况,它们只对较弱的攻击有效(带有恶意链接的电子邮件,在论坛上发布恶意链接等)

在点击劫持上没有好的可编程解决方案。一些公司起诉垃圾邮件发送者,作为对点击劫持的辩护。其他人选择在用户点击iframe后显示弹出窗口,尽管这会降低用户体验,特别是在单点击按钮的情况下。这正是Twitter为"转发"按钮所做的。Facebook目前为"喜欢"按钮部署了这种方法,每当来自黑名单域名的请求时,都会要求确认。我听说Googlebot在使用"+1"按钮索引页面时执行一些点击劫持启发式(检查计算样式,元素重叠等)…

—UPDATE—当您说"小部件"时,如果您指的是应用程序之外未经身份验证的人与之交互的东西,那么请忽略这个答案。我重读了你的问题,你从来没有真正说明你所说的"小部件"是什么意思。我们的应用程序中有各种各样的"小部件"。我以为这就是你所说的,只有经过认证的用户才能与之交互的应用程序中的所有东西。如果是这样的话,那么这个答案就是OWASP推荐的。

——最初的回答——"您不希望此请求容易受到CSRF的攻击,因此您向页面写入iframe。"不,不要创建iframe,这样你就可以按照OWASP的建议来防止跨站帧。

要防止CSRF散列某些值,请将其包含在表单中(或ajax POST数据),然后在后端检查散列值。如果匹配,那就是来自你的网站。您可以在散列中放入的具体数据越多越好。

示例:当用户登录时,您可以创建一个长随机字符串并将其绑定到他们的会话。这个字符串永远不能在您的站点上或在查看源代码时可见。然后让我们假设用户调出一些他们想要编辑的特定记录。然后你可以获取你创建的用户随机字符串,将记录主键附加到它,然后散列它们。该哈希值的结果可以作为隐藏项包含在表单中。然后在你做任何事情之前,在你的后端检查隐藏的存在,如果它不存在,中止。如果它确实存在,取用户的随机会话字符串和他们提交的明文主键,散列它们,如果匹配,你知道它来自你的网站。

即使你的网站已经写好了(假设你的网站在所有页面上都包含了一些单独的代码,比如页脚),也很容易在任何地方添加

。制作散列值并将其放置在页脚某处的隐藏div中。然后,可以使用jQuery动态地将这个隐藏的哈希值添加到页面上的所有表单中。你可以使用jQuery。ajaxPrefilter自动添加到所有ajax post中,以防您正在做ajax post而不是普通表单post。我们已经保护了一些已经以这种方式编码的非常大的网站。

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_ (CSRF) _Prevention_Cheat_Sheet

如果这听起来像您想要的路径,我可以展示一些jQuery代码来实现它。至于你在哈希什么,你想在后端如何检查它,等等…这完全取决于你是否使用ColdFusion, PHP, PL/SQL (psp)等…如果是其中之一,我可以给你指出正确的方向。

我想我明白你在做什么。您希望允许任何站点对您的小部件进行iframe,这样攻击者就可以完全控制父站点的源代码,并可以创建clickjacking例程来强制用户单击小部件。

因此iframe将能够使用CSRF令牌,只要父框架无法读取令牌,它就可以防止这种类型的攻击。

点击劫持,我相信你知道,是一种完全不同于CSRF的攻击,需要不同的防御。

真的,如果小部件非常重要,那么应该实现两阶段身份验证。使用http://twilio.com呼叫用户并让他输入pin。或者向用户发送带有验证链接的电子邮件。或者要求用户在下次登录您的小部件网站时验证该操作。

如果你有父框架的控制权,那么你将有更多的选择。这将是一个XSS保护问题。

选择正确答案后更新

所以我防止点击劫持的方法有点过头了。看起来可以使用带有确认动作的弹出窗口来保护它。

由于CSRF,您必须在iframe内…

。您无法使用表单cookie和其他nonce技巧来修复CSRF。你把它们放在哪里并不重要。

所以这是一个二元性,看起来你被困在CSRF之间"点击劫持"。对这个问题最好的解决办法是什么?

要修复CSRF,您必须通过修复具有注入或恶意代码的服务器来消除威胁,停止网络钓鱼电子邮件等。在没有良性环境的情况下,您需要重新验证用户(或提供另一个质询/响应以确保用户是交互式的)。看到:

  • 防止跨站点请求伪造(CSRF)小抄单

补救Clickjacking,在Javascript中使用X-Frame-Options或破帧代码。但我不认为两者都是万无一失的。看到:

  • 点击劫持防御小抄