gofiber/fiber · critical

CSRF: Extractor reads from the same cookie '${CookieName}' u

Error message

CSRF: Extractor reads from the same cookie '${CookieName}' used for token storage. This completely defeats CSRF protection.

What it means

The CSRF middleware stores its token in a cookie named CookieName (default "csrf_"); if you configure the token Extractor to read from that same cookie (SourceCookie with matching Key), the submitted token would always match the stored one, completely defeating CSRF protection. validateExtractorSecurity (csrf/config.go:182-205) detects this exact case on the primary extractor and panics at startup.

Source

Thrown at middleware/csrf/config.go:188

	}
	// Check if Extractor is zero value (since it's a struct)
	if cfg.Extractor.Extract == nil {
		cfg.Extractor = ConfigDefault.Extractor
	}
	// Validate extractor security configurations
	validateExtractorSecurity(&cfg)

	return cfg
}

// validateExtractorSecurity checks for insecure extractor configurations
func validateExtractorSecurity(cfg *Config) {
	if cfg == nil {
		return
	}
	// Check primary extractor
	if isInsecureCookieExtractor(cfg.Extractor, cfg.CookieName) {
		panic("CSRF: Extractor reads from the same cookie '" + cfg.CookieName +
			"' used for token storage. This completely defeats CSRF protection.")
	}

	// Check the full extractor tree so a nested chain cannot hide a fallback
	// that reads from the CSRF storage cookie.
	if cfg.Extractor.Contains(func(extractor extractors.Extractor) bool {
		return isInsecureCookieExtractor(extractor, cfg.CookieName)
	}) {
		panic("CSRF: Chained extractor reads from the same cookie '" + cfg.CookieName +
			"' used for token storage. This completely defeats CSRF protection.")
	}

	// Additional security warnings (non-fatal)
	if cfg.Extractor.Source == extractors.SourceQuery || cfg.Extractor.Source == extractors.SourceParam {
		log.Warnf("[CSRF WARNING] Using %v extractor - URLs may be logged", cfg.Extractor.Source)
	}
}

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Use the default header extractor (extractors.FromHeader("X-Csrf-Token")) which reads the token from a request header the attacker cannot forge cross-site.
  2. If you must read a cookie, use a different cookie name than CookieName and ensure that cookie is not the signed/authenticating one.
  3. Switch SingleUseToken on for stronger protection, but keep the extractor source distinct from the storage cookie.

Example fix

// before
csrf.New(csrf.Config{
    CookieName: "csrf_",
    Extractor:  extractors.FromCookie("csrf_"),
})

// after
csrf.New(csrf.Config{
    CookieName: "csrf_",
    Extractor:  extractors.FromHeader("X-Csrf-Token"), // default
})
Defensive patterns

Strategy: validation

Validate before calling

func validateCSRFExtractor(cfg csrf.Config) error {
    if cfg.Extractor.Source == extractors.SourceCookie && cfg.Extractor.Key == cfg.CookieName {
        return fmt.Errorf("extractor reads storage cookie %q", cfg.CookieName)
    }
    return nil
}

if err := validateCSRFExtractor(cfg); err != nil { log.Fatal(err) }

Prevention

When it happens

Trigger: Setting Extractor: extractors.FromCookie("csrf_") while CookieName is also "csrf_" (or any matching name). The extractor struct's Source == SourceCookie and Key == CookieName.

Common situations: Building a double-submit cookie flow but accidentally pointing the extractor at the storage cookie instead of a separate readable token cookie; or copying a FromCookie example without realizing the default CookieName is "csrf_".

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/721026db84be21c1.json. Report an issue: GitHub.