当前位置:  开发笔记 > 编程语言 > 正文

使用AngularJS的Gorilla CSRF

如何解决《使用AngularJS的GorillaCSRF》经验,为你挑选了1个好方法。

我正在尝试让AngularJS与Gorilla CSRF一起使用我的网络应用程序,但是我找不到很多文档,所以我不确定从哪里开始.我应该X-CSRF-Token为每个GET请求设置一个,还是应该在用户访问主页时执行此操作,就像我现在正在做的那样?另外,如何使用Gorilla CSRF使AngularJS CSRF保护工作?我需要进行某种比较吗?任何示例代码将不胜感激.

这是我的代码:

package main

import (
    "github.com/gorilla/csrf"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()


    r.HandleFunc("/", Home).Methods("GET")
    // Other routes handling goes here

    http.ListenAndServe(":8000",
        csrf.Protect([]byte("32-byte-long-auth-key"))(r))
}

func Home(w http.ResponseWriter, r *http.Request) {

    w.Header().Set("X-CSRF-Token", csrf.Token(r))
}
// More routes

evanmcdonnal.. 5

你的问题可能有点广泛,但总的来说你误用了这些工具,所以我只是试着解释基本的想法.您正在使用的应用程序使用"双提交"模式进行CSRF保护.这需要更改客户端和服务器代码库.服务器不应该设置X-CSRF-Token标头,即客户端的角色.我最近实际上实现了几个从头开始反CSRF解决方案,它们非常简单(都是双提交模式).我还使用了来自MSTF和Apache等供应商的一些软件包(必须在各种堆栈的20年应用程序中实现CSRF).

在双提交模式中,服务器应该设置具有随机值的cookie(如guid),cookie必须标记为安全.您也可以将其设为httponly,但是它需要您在前端资源上做更多的工作.在客户端,处理此问题的最简单方法是实现一些读取cookie值的JavaScript,并在任何POST请求之前将其添加为标头.您通常不需要保护GET.你可以,但是如果你的GET正在服务器方面做建设性/破坏性事情,那么你就是在滥用HTTP动词,我会通过将这些请求发送到POSTS而不是试图保护每一个请求来纠正它.

在服务器端,最好在所有请求进入的公共位置进行CSRF检查.当POST进入时,服务器应读取cookie值,检查标头值并进行比较.如果它们相等则应该允许请求通过,如果它们不是那么你应该用403或者其他东西启动它们.执行此操作后,服务器应重写cookie值(最好只使用一次).

您的客户端脚本可以具有类似下面的代码,只需确保资源在每个页面加载,并且您不使用表单提交,这将涵盖所有内容.如果您提交表单,则需要一些其他代码才能处理.有些方法更喜欢在DOM服务器端编写值.例如在.NET中,CSRF库使值为HTTPOnly和Secure,并期望开发人员在其项目中的每个单独的cshtml文件中的每个表单中放置一个占位符令牌......我个人认为这是非常愚蠢和低效的.不管你怎么做,你可能要做一些定制工作.Angular不会为gorillas CSRF库实现前端.大猩猩可能不会为您的客户端提供JavaScript,因为它是一个API库.无论如何,基本的JavaScript示例;

// three functions to enable CSRF protection in the client. Sets the nonce header with value from cookie
// prior to firing any HTTP POST.
function addXMLRequestCallback(callback) {
    var oldSend;
    if (!XMLHttpRequest.sendcallback) {
        XMLHttpRequest.sendcallback = callback;
        oldSend = XMLHttpRequest.prototype.send;

        // override the native send()
        XMLHttpRequest.prototype.send = function () {
            XMLHttpRequest.sendcallback(this);

            if (!Function.prototype.apply) {
                Function.prototype.apply = function (self, oArguments) {
                    if (!oArguments) {
                        oArguments = [];
                    }
                    self.__func = this;
                    self.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
                    delete self.__func;
                };
            }

            // call the native send()
            oldSend.apply(this, arguments);
        }
    }
}

addXMLRequestCallback(function (xhr) {
    xhr.setRequestHeader('X-CSRF-Token', getCookie('X-CSRF-Cookie'));
});

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return "";
}

现在,如果你可以稍微缩小你的问题,我可以提供一些更具体的指导,但这只是一个猜测(也许我会在我有一分钟时阅读他们的文档).如果您使用,Gorilla会自动设置您的cookie并为您进行服务器端检查csrf.Protect.你在Go中设置标题的代码,就是你需要上面的JavaScript.如果在服务器端设置标头,则根本没有提供安全性.这需要在浏览器中进行.如果您将该值与所有请求一起发送,Gorilla很可能会为您提供剩余的请求.

关于问题空间的一些其他随机想法.根据经验,如果攻击者无法重播请求,他们可能无法对您进行CSRF.这就是为什么这种简单方法如此有效.每个传入的请求都只有一个随机的GUID值.您可以将该值存储在cookie中,这样您就不必担心会话跨服务器移动ect(如果您不使用双提交模式,则需要共享数据存储服务器端;此cookie-header值比较业务).在目前的硬件限制下,这个值很难被强行逼迫.浏览器中的单一来源策略可防止攻击者读取您设置的cookie值(如果设置为安全,则只有来自您域的脚本才能访问它).利用这种方法的唯一方法是,如果用户之前已被XSS利用,我的意思是,由于攻击者已经拥有更多的控制/能力来使用XSS进行恶意攻击,因此无法实现CSRF的目的.



1> evanmcdonnal..:

你的问题可能有点广泛,但总的来说你误用了这些工具,所以我只是试着解释基本的想法.您正在使用的应用程序使用"双提交"模式进行CSRF保护.这需要更改客户端和服务器代码库.服务器不应该设置X-CSRF-Token标头,即客户端的角色.我最近实际上实现了几个从头开始反CSRF解决方案,它们非常简单(都是双提交模式).我还使用了来自MSTF和Apache等供应商的一些软件包(必须在各种堆栈的20年应用程序中实现CSRF).

在双提交模式中,服务器应该设置具有随机值的cookie(如guid),cookie必须标记为安全.您也可以将其设为httponly,但是它需要您在前端资源上做更多的工作.在客户端,处理此问题的最简单方法是实现一些读取cookie值的JavaScript,并在任何POST请求之前将其添加为标头.您通常不需要保护GET.你可以,但是如果你的GET正在服务器方面做建设性/破坏性事情,那么你就是在滥用HTTP动词,我会通过将这些请求发送到POSTS而不是试图保护每一个请求来纠正它.

在服务器端,最好在所有请求进入的公共位置进行CSRF检查.当POST进入时,服务器应读取cookie值,检查标头值并进行比较.如果它们相等则应该允许请求通过,如果它们不是那么你应该用403或者其他东西启动它们.执行此操作后,服务器应重写cookie值(最好只使用一次).

您的客户端脚本可以具有类似下面的代码,只需确保资源在每个页面加载,并且您不使用表单提交,这将涵盖所有内容.如果您提交表单,则需要一些其他代码才能处理.有些方法更喜欢在DOM服务器端编写值.例如在.NET中,CSRF库使值为HTTPOnly和Secure,并期望开发人员在其项目中的每个单独的cshtml文件中的每个表单中放置一个占位符令牌......我个人认为这是非常愚蠢和低效的.不管你怎么做,你可能要做一些定制工作.Angular不会为gorillas CSRF库实现前端.大猩猩可能不会为您的客户端提供JavaScript,因为它是一个API库.无论如何,基本的JavaScript示例;

// three functions to enable CSRF protection in the client. Sets the nonce header with value from cookie
// prior to firing any HTTP POST.
function addXMLRequestCallback(callback) {
    var oldSend;
    if (!XMLHttpRequest.sendcallback) {
        XMLHttpRequest.sendcallback = callback;
        oldSend = XMLHttpRequest.prototype.send;

        // override the native send()
        XMLHttpRequest.prototype.send = function () {
            XMLHttpRequest.sendcallback(this);

            if (!Function.prototype.apply) {
                Function.prototype.apply = function (self, oArguments) {
                    if (!oArguments) {
                        oArguments = [];
                    }
                    self.__func = this;
                    self.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
                    delete self.__func;
                };
            }

            // call the native send()
            oldSend.apply(this, arguments);
        }
    }
}

addXMLRequestCallback(function (xhr) {
    xhr.setRequestHeader('X-CSRF-Token', getCookie('X-CSRF-Cookie'));
});

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return "";
}

现在,如果你可以稍微缩小你的问题,我可以提供一些更具体的指导,但这只是一个猜测(也许我会在我有一分钟时阅读他们的文档).如果您使用,Gorilla会自动设置您的cookie并为您进行服务器端检查csrf.Protect.你在Go中设置标题的代码,就是你需要上面的JavaScript.如果在服务器端设置标头,则根本没有提供安全性.这需要在浏览器中进行.如果您将该值与所有请求一起发送,Gorilla很可能会为您提供剩余的请求.

关于问题空间的一些其他随机想法.根据经验,如果攻击者无法重播请求,他们可能无法对您进行CSRF.这就是为什么这种简单方法如此有效.每个传入的请求都只有一个随机的GUID值.您可以将该值存储在cookie中,这样您就不必担心会话跨服务器移动ect(如果您不使用双提交模式,则需要共享数据存储服务器端;此cookie-header值比较业务).在目前的硬件限制下,这个值很难被强行逼迫.浏览器中的单一来源策略可防止攻击者读取您设置的cookie值(如果设置为安全,则只有来自您域的脚本才能访问它).利用这种方法的唯一方法是,如果用户之前已被XSS利用,我的意思是,由于攻击者已经拥有更多的控制/能力来使用XSS进行恶意攻击,因此无法实现CSRF的目的.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有