csrf

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2026 License: BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Overview

Package csrf provides CSRF (Cross-Site Request Forgery) protection middleware for Hertz.

It implements the Double Submit Cookie pattern using HMAC-SHA256. Cookies are session-level and automatically cleared when the browser closes.

Hertz Backend Setup

// Initialize CSRF protection
csrfProtect := csrf.New(
	csrf.SetKey("your-secret-key-at-least-32-bytes"),
	csrf.SetDomain("example.com"),
)

// CSRF token endpoint (called on first page load)
h.GET("/csrf-token", func(ctx context.Context, c *app.RequestContext) {
	csrfProtect.SetToken(c)
	c.JSON(200, utils.H{"message": "ok"})
})

// Login endpoint (refresh CSRF token after login for security)
h.POST("/auth/login", func(ctx context.Context, c *app.RequestContext) {
	// ... validate credentials ...
	csrfProtect.SetToken(c) // Refresh CSRF token
	c.JSON(200, utils.H{"accessToken": token})
})

// Protect API routes with CSRF middleware
api := h.Group("/api", csrfProtect.VerifyToken())
api.POST("/submit", submitHandler)
api.PUT("/update", updateHandler)
api.DELETE("/remove", removeHandler)

Angular Frontend Setup

Angular has built-in XSRF support that works with default cookie/header names.

1. Configure HttpClient in app.config.ts:

import { provideHttpClient, withXsrfConfiguration } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withXsrfConfiguration({
        cookieName: 'XSRF-TOKEN',  // Must match backend default
        headerName: 'X-XSRF-TOKEN' // Must match backend default
      })
    )
  ]
};

2. Create CSRF service:

@Injectable({ providedIn: 'root' })
export class CsrfService {
  constructor(private http: HttpClient) {}

  initToken(): Observable<void> {
    return this.http.get<void>('/csrf-token', { withCredentials: true });
  }
}

3. Get CSRF token on app initialization (app.component.ts):

export class AppComponent implements OnInit {
  constructor(private csrfService: CsrfService) {}

  ngOnInit() {
    this.csrfService.initToken().subscribe();
  }
}

4. Refresh CSRF token after login (recommended):

login(credentials: LoginRequest) {
  return this.http.post<LoginResponse>('/auth/login', credentials, {
    withCredentials: true
  }).pipe(
    tap(res => localStorage.setItem('token', res.accessToken))
    // CSRF cookie is refreshed automatically by backend
  );
}

5. Ensure all HTTP requests include credentials:

this.http.post('/api/submit', data, { withCredentials: true })

Security Notes

  • Cookies are session-level (cleared when browser closes)
  • XSRF-TOKEN cookie is readable by JavaScript (HttpOnly=false)
  • XSRF-SALT cookie is HttpOnly=true for additional security
  • Both cookies use SameSite=Strict to prevent cross-site requests
  • Refresh CSRF token after login to prevent pre-auth token theft
  • Always use HTTPS in production

Index

Constants

View Source
const (
	DefaultCookieName = "XSRF-TOKEN"
	DefaultSaltName   = "XSRF-SALT"
	DefaultHeaderName = "X-XSRF-TOKEN"
	DefaultSaltLength = 16
)

Default configuration values.

Variables

View Source
var (
	ErrMissingHeader = errors.New("csrf: missing token in header")
	ErrMissingSalt   = errors.New("csrf: missing salt cookie")
	ErrInvalidToken  = errors.New("csrf: invalid token")
	ErrEmptyKey      = errors.New("csrf: secret key cannot be empty")
)

Errors returned by csrf functions.

Functions

This section is empty.

Types

type Csrf

type Csrf struct {
	Key           string
	CookieName    string
	SaltName      string
	HeaderName    string
	Domain        string
	IgnoreMethods map[string]bool
}

Csrf provides CSRF protection using Double Submit Cookie pattern.

func New

func New(options ...Option) *Csrf

New creates a new Csrf instance with the given options. At minimum, SetKey must be provided with a secret key.

func (*Csrf) SetToken

func (x *Csrf) SetToken(c *app.RequestContext)

SetToken generates and sets CSRF cookies on the response. Cookies are session-level (deleted when browser closes). Call this on login or when the frontend needs a fresh token.

func (*Csrf) Tokenize

func (x *Csrf) Tokenize(salt string) string

Tokenize creates an HMAC-SHA256 token from the given salt.

func (*Csrf) VerifyToken

func (x *Csrf) VerifyToken() app.HandlerFunc

VerifyToken returns a Hertz middleware that validates CSRF tokens. Safe methods (GET, HEAD, OPTIONS, TRACE) are skipped by default.

type Option

type Option func(x *Csrf)

Option is a function that configures a Csrf instance.

func SetCookieName

func SetCookieName(v string) Option

SetCookieName sets the name of the token cookie.

func SetDomain

func SetDomain(v string) Option

SetDomain sets the cookie domain.

func SetHeaderName

func SetHeaderName(v string) Option

SetHeaderName sets the expected header name for token verification.

func SetIgnoreMethods

func SetIgnoreMethods(methods []string) Option

SetIgnoreMethods sets which HTTP methods should skip CSRF verification.

func SetKey

func SetKey(v string) Option

SetKey sets the secret key for HMAC signing. The key should be at least 32 bytes for security.

func SetSaltName

func SetSaltName(v string) Option

SetSaltName sets the name of the salt cookie.

Jump to

Keyboard shortcuts

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