CSRF
What is CSRF?
Cross-site request forgery (also known as CSRF) is a web security vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform. It allows an attacker to partly circumvent the same origin policy, which is designed to prevent different websites from interfering with each other.
Preventing CSRF attacks
The most robust way to defend against CSRF attacks is to include a CSRF token within relevant requests. The token should be:
Unpredictable with high entropy, as for session tokens in general.
Tied to the user's session.
Strictly validated in every case before the relevant action is executed.
Find CSRF vulnerabilities using Burp Suite's web vulnerability scanner An additional defense that is partially effective against CSRF, and can be used in conjunction with CSRF tokens
, is SameSite
cookies.
Read more at: https://portswigger.net/web-security/csrf
CSRF Protection
Iris makes it easy to protect your application from cross-site request forgery (CSRF) attacks. You'll learn how to use the Iris CSRF middleware to generate csrf token and protect your APIs.
Install
The CSRF middleware's source code is located at the iris-contrib/middleware repository.
CSRF is easy to use: add the middleware to your router with the below:
...and then collect the token with csrf.Token(ctx)
in your handlers before passing it to the template, JSON body or HTTP header (see below).
Note that the authentication key passed to csrf.Protect([]byte(key))
should be 32-bytes long and persist across application restarts. Generating a random key won't allow you to authenticate existing cookies and will break your CSRF validation.
CSRF inspects the HTTP headers (first) and form body (second) on subsequent POST/PUT/PATCH/DELETE/etc. requests for the token.
Excluding Routes From CSRF Protection
Sometimes you may wish to exclude some routes from CSRF protection under a group. There are two available ways to do this. Read below...
1. Using the *Route.RemoveHandler
method:
2. The UnsafeSkipCheck
will skip the CSRF check for any requests. This must be called before the CSRF middleware:
Note: You should not set this without otherwise securing the request from CSRF attacks. The primary use-case for this function is to turn off CSRF checks for non-browser clients using authorization tokens against your API.
HTML Forms
Here's the common use-case: HTML forms you want to provide CSRF protection for, in order to protect malicious POST requests being made:
Note that the CSRF middleware will (by necessity) consume the request body if the token is passed via POST form values. If you need to consume this in your handler, insert your own middleware earlier in the chain to capture the request body.
JavaScript Applications
This approach is useful if you're using a front-end JavaScript framework like React, Ember or Angular, and are providing a JSON API. Specifically, we need to provide a way for our front-end fetch/AJAX calls to pass the token on each fetch (AJAX/XMLHttpRequest) request. We achieve this by:
Parsing the token from the
<input>
field generated by thecsrf.TemplateField(ctx)
helper, or passing it back in a response header.Sending this token back on every request
Ensuring our cookie is attached to the request so that the form/header value can be compared to the cookie value.
In our JavaScript application, we should read the token from the response headers and pass it in a request header for all requests. Here's what that looks like when using Axios, a popular JavaScript HTTP client library:
If you plan to host your JavaScript application on another domain, you can use the Trusted Origins feature to allow the host of your JavaScript application to make requests to your Go application. Observe the code snippet below:
On the example above, you're authorizing requests from ui.domain.com
to make valid CSRF requests to your application, so you can have your API server on another domain without problems.
Setting SameSite
Go 1.11 introduced the option to set the SameSite attribute in cookies. This is valuable if a developer wants to instruct a browser to not include cookies during a cross site request. SameSiteStrictMode
prevents all cross site requests from including the cookie. SameSiteLaxMode prevents CSRF prone requests (POST) from including the cookie but allows the cookie to be included in GET requests to support external linking.
Setting Options
What about providing your own error handler or store and changing the HTTP header the package inspects on requests? (i.e. an existing API you're porting to Go). Well, CSRF provides options for changing these as you see fit:
The CSRF.Filter
method.
OR use the iris.NewConditionalHandler
:
The main CSRF.Protect
method (same as csrf.Protect
package-level function as we've seen in the previous examples).
Last updated