【问题标题】:What's the point of the X-Requested-With header?X-Requested-With 标头有什么意义?
【发布时间】:2013-07-02 22:58:56
【问题描述】:

JQuery 等框架添加如下头部:

X-Requested-With: XMLHttpRequest

为什么需要这个?为什么服务器要以不同于普通请求的方式处理 AJAX 请求?

更新:我刚刚找到了一个使用此标头的真实示例:https://core.spreedly.com/manual/payment-methods/adding-with-js。如果在没有 AJAX 的情况下请求支付处理器,它会在完成后重定向回原始网站。当使用 AJAX 请求时,不会进行重定向。

【问题讨论】:

  • "[当] 不使用 AJAX 请求时,完成后会重定向回原始网站。使用 AJAX 请求时,不会进行重定向。" -> 这正是你想要这样做的原因。 :)
  • 另一个用例:我工作的一个应用程序将未经身份验证的用户重定向到常规请求的登录页面。如果请求是通过 AJAX(使用此标头检测),如果用户未经身份验证,则不会发生重定向,但会返回错误。 Django Web 编程框架有一个is_ajax 函数来检测使用此标头的ajax 调用。

标签: jquery ajax http-headers cors


【解决方案1】:

一个很好的理由是为了安全 - 这可以防止CSRF 攻击,因为在未经服务器同意的情况下,此标头不能通过CORS 添加到跨域的 AJAX 请求中。

仅允许以下标头跨来源:

  • 接受
  • 接受语言
  • 内容-语言
  • 最后一个事件 ID
  • 内容类型

任何其他因素都会导致在支持 CORS 的浏览器中发出“飞行前”请求。

如果没有 CORS,则无法将 X-Requested-With 添加到跨域 XHR 请求中。

如果服务器正在检查此标头是否存在,则它知道该请求不是从尝试使用 JavaScript 代表用户发出请求的攻击者的域发起的。这还检查请求不是从常规 HTML 表单发布的,如果不使用令牌,就很难验证它不是跨域的。 (不过,checking the Origin header 可能是支持的浏览器中的一个选项,although you will leave old browsers vulnerable。)

发现新的 Flash 绕过

您可能希望combine this with a token,因为 Flash 在 OSX 上的 Safari 上运行 can set this header if there's a redirect step。它显示为 it also worked on Chrome,但现在已修复。 More details here 包括受影响的不同版本。

OWASP Recommend combining this with an Origin and Referer check:

在第 4.3 节中专门讨论了这种防御技术 跨站点请求伪造的强大防御。然而,绕过 这种使用 Flash 进行的防御早在 2008 年就被记录在案,并且在 最近是 Mathias Karlsson 在 2015 年利用 Vimeo 中的 CSRF 漏洞。 但是,我们认为 Flash 攻击无法欺骗 Origin 或 引用标头,因此通过检查它们两个我们相信这一点 检查组合应防止 Flash 绕过 CSRF 攻击。 (笔记: 如果有人可以证实或反驳这一信念,请告诉我们,以便我们 可以更新这篇文章)

但是,由于已经讨论过的原因,检查 Origin 可能会很棘手。

更新

CORS, CSRF and X-Requested-With here 上写了一篇更深入的博文。

【讨论】:

  • 我不明白。是什么阻止了攻击者构建请求并同时添加 X-Requested-With 标头?
  • @Greg:浏览器 - 它不允许跨域。
  • 哦,我没有意识到只要你在同一个域上就不需要 CORS 配置。但是,当您考虑它时,这很明显。谢谢!
  • @vol7ron:没有什么能阻止他们,但是他们不会在请求中包含受害者的 cookie,这会破坏他们发出请求的对象。为了使 CSRF 成功,攻击者需要浏览器自动在请求中附加 cookie,因此没有浏览器就没有 CSRF 攻击。
  • @vol7ron:前者。 CSRF 是一个confused deputy 问题。浏览器是困惑的代理,被“欺骗”为用户没有自己提出的请求发送 cookie。
【解决方案2】:

请务必阅读 SilverlightFox 的回答。它突出了一个更重要的原因。

原因主要是如果您知道请求的来源,您可能希望稍微自定义一下。

例如,假设您有一个包含许多食谱的网站。您使用自定义 jQuery 框架根据他们单击的链接将食谱滑入容器中。 链接可能是www.example.com/recipe/apple_pie

现在通常会返回一个完整的页面、页眉、页脚、食谱内容和广告。但是,如果有人正在浏览您的网站,其中一些部分已经加载。因此,您可以使用 AJAX 来获取用户选择的配方,但为了节省时间和带宽,请不要加载页眉/页脚/广告。

现在您可以为www.example.com/recipe_only/apple_pie 之类的数据编写一个辅助端点,但这更难维护和分享给其他人。

但更容易检测到它是一个 ajax 请求发出请求,然后只返回部分数据。这样,用户浪费的带宽更少,网站的响应速度更快。

框架只是添加标头,因为有些人可能会发现跟踪哪些请求是 ajax 以及哪些不是很有用。但使用这些技术完全取决于开发人员。

它实际上有点类似于Accept-Language 标头。浏览器可以请求网站,请显示该网站的俄语版本,而无需在 URL 中插入 /ru/ 或类似内容。

【讨论】:

  • 哇,这听起来像是一场可怕的维护噩梦。如果要返回同一页面的不同表示,则应为 Accept 标头提供不同的内容类型。为此使用自定义标题听起来像是错误的方法。
【解决方案3】:

一些框架正在使用这个标头来检测 xhr 请求,例如grails spring security 正在使用此标头来识别 xhr 请求并给出 json 响应或 html 响应作为响应。

大多数 Ajax 库(从 v2.1 开始的 Prototype、JQuery 和 Dojo)都包含一个 X-Requested-With 标头,指示请求是由 XMLHttpRequest 发出的,而不是通过单击常规超链接或表单提交按钮触发的。

来源:http://grails-plugins.github.io/grails-spring-security-core/guide/helperClasses.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2010-10-12
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 2020-03-01
    相关资源
    最近更新 更多