csrf

package module
v0.0.0-...-a8bb8f8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2020 License: MIT Imports: 10 Imported by: 0

README

revel-csrf

revel-csrf implements Cross-Site Request Forgery (CSRF) attacks prevention for the Revel framework.

Code is based on the nosurf package implemented by Justinas Stankevičius.

Installation

go get github.com/cbonello/revel-csrf

A demo application is provided in the samples directory. To launch it:

revel run github.com/cbonello/revel-csrf/samples/demo

Configuration options

Revel-csrf supports following configuration options in app.conf:

  • csrf.ajax A boolean value that indicates whether or not revel-csrf should support the injection and verification of CSRF tokens for XMLHttpRequests. Default value is false.

  • csrf.token.length An integer value that defines the number of characters that should be found within CSRF tokens. Token length should be in [32..512] and default value is 32 characters.

Operating instructions

Simply call the CSRFFilter() filter in app/init.go.

package app

import (
    "github.com/cbonello/revel-csrf"
    "github.com/revel/revel"
)

func init() {
    // Filters is the default set of global filters.
    revel.Filters = []revel.Filter{
	    revel.PanicFilter,             // Recover from panics and display an error page instead.
	    revel.RouterFilter,            // Use the routing table to select the right Action
	    revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
	    revel.ParamsFilter,            // Parse parameters into Controller.Params.
	    revel.SessionFilter,           // Restore and write the session cookie.
	    revel.FlashFilter,             // Restore and write the flash cookie.
	     csrf.CSRFFilter,              // CSRF prevention.
	    revel.ValidationFilter,        // Restore kept validation errors and save new ones from cookie.
	    revel.I18nFilter,              // Resolve the requested language
	    revel.InterceptorFilter,       // Run interceptors around the action.
	    revel.ActionInvoker,           // Invoke the action.
    }
}

Insert a hidden input field named csrf_token in your forms.

<form action="/Hello" method="POST">
    <input type="text" name="name" />
    <input type="hidden" name="csrf_token" value="{{ .csrf_token }}" />
    <button type="submit">Send</button>
</form>

Javascript-code sample to perform AJAX calls with jQuery 1.5 and newer.

function csrfSafeMethod(method) {
    // HTTP methods that do not require CSRF protection.
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    crossDomain: false,
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", {{ .csrf_token }});
        }
    }
});

$("#AJAXForm").submit(function(event){
	event.preventDefault();
    $.ajax({
        type: "POST",
        url: "/Hello",
        data: {
            name: $("#AJAXFormName").val()
        },
        success: function(data) {
            // Switch to HTML code returned by server on success.
            jQuery("body").html(data);
        },
        error: function(jqXHR, status, errorThrown) {
            alert(jqXHR.statusText);
        },
    });
});

You can call csrf.ExemptedFullPath() or csrf.ExemptedGlob() to exempt routes from CSRF checks. See app/init.go in demo application.

TODO

  • Unique token per-page.
  • Test cases.

CONTRIBUTORS

  • Otto Bretz
  • Allen Dang

Documentation

Overview

Package csrf is a synchronizer Token Pattern implementation.

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

Package csrf is a synchronizer Token Pattern implementation.

Management of routes exempted from CSRF checks.

Generation of tokens.

Index

Constants

This section is empty.

Variables

View Source
var CSRFFilter = func(c *revel.Controller, fc []revel.Filter) {
	r := c.Request

	tokenCookie, found := c.Session[cookieName]
	realToken := ""
	if !found {
		realToken = generateNewToken(c)
	} else {
		realToken = tokenCookie.(string)

		if len(realToken) != lengthCSRFToken {

			revel.AppLog.Debugf("REVEL_CSRF: Bad token length: found %d, expected %d",
				len(realToken), lengthCSRFToken)
			realToken = generateNewToken(c)
		}
	}

	c.ViewArgs[fieldName] = realToken

	unsafeMethod := !safeMethods.MatchString(r.Method)
	if unsafeMethod && !IsExempted(r.URL.Path) {
		revel.AppLog.Infof("REVEL-CSRF: Processing unsafe '%s' method...", r.Method)
		if r.URL.Scheme == "https" {

			referer, err := url.Parse(r.Header.Get("Referer"))
			if err != nil || referer.String() == "" {

				c.Result = c.Forbidden(errNoReferer)
				return
			}

			if !sameOrigin(referer, r.URL) {
				c.Result = c.Forbidden(errBadReferer)
				return
			}
		}

		sentToken := ""
		if ajaxSupport := revel.Config.BoolDefault("csrf.ajax", false); ajaxSupport {

			sentToken = r.Header.Get(headerName)
		}
		if sentToken == "" {

			sentToken = c.Params.Get(fieldName)
		}
		revel.AppLog.Debugf("REVEL-CSRF: Token received from client: '%s'", sentToken)

		if len(sentToken) != len(realToken) {
			c.Result = c.Forbidden(errBadToken)
			return
		}
		comparison := subtle.ConstantTimeCompare([]byte(sentToken), []byte(realToken))
		if comparison != 1 {
			c.Result = c.Forbidden(errBadToken)
			return
		}
		revel.AppLog.Debugf("REVEL-CSRF: Token successfully checked.")
	}

	fc[0](c, fc[1:])
}

CSRFFilter implements the CSRF filter.

Functions

func ExemptedFullPath

func ExemptedFullPath(path string)

ExemptedFullPath exempts one exact path from CSRF checks.

func ExemptedFullPaths

func ExemptedFullPaths(paths ...string)

ExemptedFullPath exempts exact paths from CSRF checks.

func ExemptedGlob

func ExemptedGlob(path string)

ExemptedGlob exempts one path from CSRF checks using pattern matching. See http://golang.org/pkg/path/#Match

func ExemptedGlobs

func ExemptedGlobs(paths ...string)

ExemptedGlobs exempts paths from CSRF checks using pattern matching.

func IsExempted

func IsExempted(path string) bool

IsExempted checks whether given path is exempt from CSRF checks or not.

Types

This section is empty.

Directories

Path Synopsis
samples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL