4

我有一个带有 @Consumes(MediaType.JSON) 之类的注释的 RESTful API - 在这种情况下,CSRF 攻击是否仍然可以在这样的服务上进行?我一直在修补在服务器端使用 CSRFGuard 保护我的服务或从客户端进行双重提交。但是,当我尝试使用带有 enctype="text/plain" 的 FORM 发布请求时,它不起作用。此处解释了该技术如果我的消费注释中有 MediaType.APPLICATION_FORM_URLENCODED,则此方法有效。当我使用 POST/PUT/DELETE 动词时,内容协商很有用,但 GET 仍然可以访问,这可能需要研究。

任何建议或意见都会很棒,如果您需要更多信息,请告诉我。

干杯

4

2 回答 2

10

JAX-RS 旨在创建应该是无状态的 REST API。跨站点请求伪造不是无状态应用程序的问题。

Cross Site Request Forgery 的工作方式是有人可能会欺骗您单击链接或在浏览器中打开链接,这会将您定向到您登录的站点,例如某些在线论坛。由于您已经在该论坛上登录,攻击者可以构造一个 url,这样说:someforum.com/deletethread?id=23454

该论坛程序设计不当,将根据会话 cookie 识别您,并确认您有能力删除该主题,实际上将删除该主题。

这一切都是因为程序根据会话 cookie 对您进行了身份验证(甚至基于“记住我”cookie)

使用 RESTful API 没有 cookie,请求之间不维护任何状态,因此无需防止会话劫持。

您通常使用 RESTFul api 进行身份验证的方式是发送一些额外的标头。如果有人欺骗您点击指向 RESTful API 的 url,浏览器不会发送额外的标头,因此没有风险。

简而言之 - 如果 REST API 的设计方式应该是无状态的,那么就没有跨站点伪造的风险,也不需要 CSRF 保护。

于 2013-04-01T15:46:22.650 回答
1

添加另一个答案,因为 Dmitri 的答案混合了服务器端状态和 cookie。

如果您的服务器通过多个请求将用户信息存储在内存中,则应用程序不是无状态的。这会降低水平可伸缩性,因为您需要为每个请求找到“正确”的服务器。

Cookie 只是一种特殊的 HTTP 标头。它们通常用于识别用户会话,但并非每个 cookie 都意味着服务器端状态。服务器也可以在不启动会话的情况下使用来自 cookie 的信息。另一方面,使用其他 HTTP 标头并不一定意味着您的应用程序自动是无状态的。如果您将用户数据存储在服务器的内存中,则不是。cookie 和其他标头之间的区别在于浏览器处理它们的方式。对我们来说最重要的是浏览器会在每个后续请求中重新发送它们。如果有人欺骗用户提出他不想提出的请求,这将是有问题的。

这对于使用 JSON 的 API 来说是个问题吗?是的,分两种情况:

  • 攻击者让用户提交一个带有enctype=text/plain: Url 编码内容的表单不是问题,因为结果不能是有效的 JSON。text/plain如果您的服务器将内容解释为 JSON 而不是纯文本,则会出现问题。如果您的资源带有注释,@Consumes(MediaType.JSON)那么您应该没有问题,因为它不会接受text/plain并且应该返回 status 415。(请注意,JSON 可能有一天会成为有效的编码类型,而这将不再有效)。
  • 攻击者让用户提交 AJAX 请求:同源策略阻止向其他域发出 AJAX 请求,因此只要您不使用诸如Access-Control-Allow-Origin: *.
于 2016-07-31T11:15:01.690 回答