Bad Context Key

ID

go.bad_context_key

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

reliability, suspicious

Description

Reports a call to context.WithValue(ctx, key, val) whose key is a basic-type literal — a string, integer or other built-in constant. The standard library documentation explicitly warns against using built-in types as context keys, because the key space is global to the process: two packages that both use the string "id" will collide and overwrite each other’s values.

Rationale

A built-in literal key offers no namespacing. Any other package using the same literal reads or clobbers the value, and the collision is invisible until something breaks at runtime. The recommended pattern is an unexported named type — type ctxKey string or type ctxKey int — with package-private key constants, which makes every key unique to its package.

context.WithValue(ctx, "user", u)   // FLAW — string literal key collides across packages
context.WithValue(ctx, 0, u)        // FLAW — integer literal key

context.WithValue(ctx, userKey, u)  // OK — key is an unexported typed constant

Remediation

Define an unexported key type and use typed constants:

type ctxKey string
const userKey ctxKey = "user"
context.WithValue(ctx, userKey, u)