introduce

This article describes how to implement server CSRF authentication logic through RK-boot.

What is CSRF?

Cross-site request forgery Cross-site Request Forgery, also known as one-click attack or session riding, usually abbreviated as CSRF or XSRF, Is a method of hijacking a user to perform unintended actions on a currently logged Web application.

In contrast to cross-site scripting (XSS), which exploits the user’s trust in a given site, CSRF exploits the site’s trust in the user’s Web browser.

* * any changes

What are the defenses?

There are several popular defense methods as follows. We use examples to implement the defense of adding checktoken.

1: Token synchronization mode 2: Referer field is checked 3: Token is added

Please visit the following address for the full tutorial:

  • rkdocs.netlify.app/cn

The installation

go get github.com/rookie-ninja/rk-boot/gin
Copy the code

Quick start

1. Create the boot. Yaml

The boot.yaml file tells RK-boot how to start the Gin service.

In the YAML file below, we declare one thing:

  • Start the CSRF interceptor, using the default parameters. The interceptor checks the x-CSRF-Token value in the request Header to determine if the Token is correct.
---
gin:
  - name: greeter                     # Required
    port: 8080                        # Required
    enabled: true                     # Required
    interceptors:
      csrf:
        enabled: true                 # Optional, default: false
Copy the code

2. Create a main. Go

We added two Restful apis to Gin.

  • GET /v1/greeter: Returns a CSRF Token generated by the server
  • POST/V1 /greeter: Verifies a CSRF Token
// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.
package main

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/rookie-ninja/rk-boot"
	"github.com/rookie-ninja/rk-boot/gin"
	"net/http"
)

// Application entrance.
func main(a) {
	// Create a new boot instance.
	boot := rkboot.NewBoot()

	ginEntry := rkbootgin.GetGinEntry("greeter")
	// Register /v1/greeter GET
	ginEntry.Router.GET("/v1/greeter".func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, "Hello!")})// Register /v1/greeter POST
	ginEntry.Router.POST("/v1/greeter".func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, "Hello!")})// Bootstrap
	boot.Bootstrap(context.Background())

	// Wait for shutdown sig
	boot.WaitForShutdownSig(context.Background())
}
Copy the code

3. Folder structure

.├ ── Go.tempo ├── go.tempo ├─ main. Go 0 directories, 4 filesCopy the code
  • go.mod
Module github.com/rookie-ninja/rk-demo go 1.16 require (github.com/rookie-ninja/rk-boot v1.4.0 Github.com/rookie-ninja/rk-boot/gin v1.2.12)Copy the code

4. Verify

  • Send a GET request to /v1/ Greeter and we will GET a CSRF Token.
$ curl -X GET -vs localhost:8080/v1/greeter ... < HTTP/1.1 200 OK < content-type: application/json; charset=utf-8 < Set-Cookie: _csrf=XVlBzgbaiCMRAjWwhTHctcuAxhxKQFDa; Expires=Mon, 27 Dec 2021 09:35:20 GMT < Vary: Cookie < Date: Sun, 26 Dec 2021 09:35:20 GMT < Content-Length: 8 < * Connection #0 to host localhost left intact "Hello!" *Copy the code
  • Send a POST request to /v1/greeter to provide a valid CSRF Token.
$ curl -X POST -v --cookie "_csrf=my-test-csrf-token" -H "X-CSRF-Token:my-test-csrf-token" localhost:8080/v1/greeter ...  > Cookie: _csrf=my-test-csrf-token > X-csrF-token :my-test-csrf-token > < HTTP/1.1 200 OK < content-type: application/json; charset=utf-8 < Set-Cookie: _csrf=my-test-csrf-token; Expires=Mon, 27 Dec 2021 09:35:43 GMT < Vary: Cookie < Date: Sun, 26 Dec 2021 09:35:43 GMT < Content-Length: 8 < * Connection #0 to host localhost left intact "Hello!" *Copy the code
  • Send a POST request to /v1/ Greeter to provide an illegal CSRF Token.
$ curl -X POST -v -H "X-CSRF-Token:my-test-csrf-token" localhost:8080/v1/greeter ... > x-csrf-token :my-test-csrf-token > < HTTP/1.1 403 Forbidden < content-type: application/json; charset=utf-8 < Date: Sun, 26 Dec 2021 09:36:18 GMT < Content-Length: 91 < * Connection #0 to host localhost left intact {"error":{"code":403,"status":"Forbidden","message":"invalid csrf token","details":[null]}}Copy the code

CSRF interceptor option

Rk-boot provides several CSRF interceptor options, and override options are not recommended except for special needs.

options describe type The default value
gin.interceptors.csrf.enabled Start the CSRF interceptor boolean false
gin.interceptors.csrf.tokenLength The length of the Token int 32
gin.interceptors.csrf.tokenLookup Where to obtain the Token, please refer to the following introduction string “The header: X-ray CSRF Token -“
gin.interceptors.csrf.cookieName The Cookie name string _csrf
gin.interceptors.csrf.cookieDomain Cookie domain string “”
gin.interceptors.csrf.cookiePath Cookie path string “”
gin.interceptors.csrf.cookieMaxAge Cookie MaxAge (seconds) int 86400 (24 hours)
gin.interceptors.csrf.cookieHttpOnly Cookie HTTP Only option bool false
gin.interceptors.csrf.cookieSameSite Cookie SameSite option, supported [lax, strict, None, default] string “lax”
gin.interceptors.csrf.ignorePrefix The Restful API Path verified by CSRF is ignored []string []

TokenLookup format

Currently, three methods are supported. The interceptor uses one of the following methods to look for tokens in the request.

  • From the HTTP Header
  • From the HTTP Form
  • From the HTTP Query
// Optional. Default value "header:X-CSRF-Token".
// Possible values:
// - "header:<name>"
// - "form:<name>"
// - "query:<name>"
// Optional. Default value "header:X-CSRF-Token".
Copy the code