使用oAuth的GAE端点上的CSRF

时间:2016-01-25 23:43:45

标签: google-app-engine google-oauth csrf google-cloud-endpoints

我希望在我的API中实施针对CSRF攻击的保护,我使用GAE端点开发了所有方法都需要oAuth2。

在实施任何特定保护之前,我正试图实际破坏我的应用程序(CSRF看起来很简单乍一看)。但是无法使其发挥作用。

当我在另一个页面中引用我的端点时,浏览器会添加cookie信息,但不会添加带有承载访问令牌的Authorization标头。这似乎不够,因为我的端点会自动返回带有www-authenticate:Bearer realm="https://accounts.google.com/"标头的401。

正如我所说,我没有针对CSRF的具体保护。但在HTTPS下使用带有oAuth2的Google Cloud Endpoints是否可以“免费”保护我免受此类攻击?

- 修改以发表评论

我尝试了一次简单的CSRF攻击。我的页面上有一个<img src="https://bla-bla-bla-appspot.com/_ah/api/myapi/v1/resource.getMethod">。然后我在另一个选项卡中打开我的应用程序时访问了此页面,因此我的浏览器将发送我的身份验证信息。它确实发送了cookie,但不发送我的oAuth令牌。

我甚至没有尝试过POST,如果我“破解”GET就已经很好了。

2 个答案:

答案 0 :(得分:2)

OAUth 2.0 explicitly protects against CSRF通过使用由客户端生成并由服务器验证的不可猜测的状态参数。即使攻击者能够欺骗客户端访问URL以授权恶意令牌,状态参数也不会与客户端的参数匹配,并且请求将被拒绝。

Google Cloud Endpoints库可以为您处理OAuth规范的这一部分,因此您可以清楚地了解这一点。

Oauth2要求所有请求都将承载访问令牌作为HTTP标头(使用javascript中的XMLhttpRequest来设置标头并发出请求)或者作为URL查询参数(access_token)。攻击者不会知道此秘密值,因此无法创建可通过验证的URL。

答案 1 :(得分:0)

这是(我希望)来自我的Kuoll remote debugger网络应用的有用的java片段。

package com.kuoll.server.filters;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CrossOriginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;

        resp.addHeader("Access-Control-Allow-Origin", "*");
        resp.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
        resp.setHeader("Access-Control-Allow-Headers", "origin, content-type, accept");

        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

}

*中的resp.addHeader("Access-Control-Allow-Origin", "*");替换为您的Origin(如果需要)。

的web.xml

<filter-mapping>
    <filter-name>CrossOriginFilter</filter-name>
    <url-pattern>/api/*</url-pattern>
</filter-mapping>