v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.go.cookie.gin-insecure

A Gin auth/session cookie is written with secure or httpOnly set to a literal false.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

gin.Context.SetCookie takes them positionally: SetCookie(name, value, maxAge, path, domain, secure, httpOnly). With secure=false the cookie rides over plain HTTP where a network attacker can read it; with httpOnly=false any XSS can read it from JavaScript. For OAuth/OIDC this exposes session and token cookies to theft and hijacking (CWE-1004, CWE-614). LLM-generated Gin handlers frequently pass false, false to "make it work" over http://localhost.

Set both flags to true on auth cookies: c.SetCookie("session_id", tok, 3600, "/", "", true, true)

VULNERABLE
vulnerable.go
package main

import "github.com/gin-gonic/gin"

func setInsecure(c *gin.Context) {
	// ruleid: auth.go.cookie.gin-insecure
	c.SetCookie("session_id", "tok", 3600, "/", "", false, false)

	// ruleid: auth.go.cookie.gin-insecure
	c.SetCookie("auth_token", "tok", 3600, "/", "example.com", false, true)

	// ruleid: auth.go.cookie.gin-insecure
	c.SetCookie("refresh_token", "tok", 3600, "/", "", true, false)
}
SAFE
safe.go
package main

import "github.com/gin-gonic/gin"

func setSecure(c *gin.Context) {
	// Both flags true on an auth cookie: not flagged.
	c.SetCookie("session_id", "tok", 3600, "/", "", true, true)

	// Non-sensitive cookie name: outside the auth-cookie scope.
	c.SetCookie("theme", "dark", 3600, "/", "", false, false)

	// Flags supplied as variables (e.g. from config), not literal false.
	secure := true
	httpOnly := true
	c.SetCookie("access_token", "tok", 3600, "/", "", secure, httpOnly)
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.go.cookie.gin-insecure -- <reason>

References

https://pkg.go.dev/github.com/gin-gonic/gin#Context.SetCookie ↗https://cwe.mitre.org/data/definitions/1004.html ↗https://cwe.mitre.org/data/definitions/614.html ↗