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: MEDIUM auth.go.oauth.insecure-token-endpoint

An OAuth/OIDC endpoint is being contacted over cleartext http://.

Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.

Why this matters

Authorization codes, client_secret, access/refresh tokens, and the code_verifier then travel unencrypted. A network attacker can read or rewrite them and take over the flow.

RFC 6749 §3.1 / §10.9 require TLS for the authorization and token endpoints. Use https:// for every authorize, token, and userinfo URL (including oauth2.Endpoint{AuthURL, TokenURL}). http://localhost is fine for local development and is not flagged.

VULNERABLE
vulnerable.go
package main

import (
	"net/http"

	"golang.org/x/oauth2"
)

// oauth2.Endpoint configured with cleartext authorize/token URLs.
func insecureConfig() *oauth2.Config {
	return &oauth2.Config{
		ClientID:     "client",
		ClientSecret: "secret",
		// ruleid: auth.go.oauth.insecure-token-endpoint
		Endpoint: oauth2.Endpoint{
			AuthURL: "http://issuer.example.com/oauth/authorize",
			// ruleid: auth.go.oauth.insecure-token-endpoint
			TokenURL: "http://issuer.example.com/oauth/token",
		},
	}
}

// A hand-built authorize URL over http with OAuth query markers.
func insecureAuthorizeURL() string {
	// ruleid: auth.go.oauth.insecure-token-endpoint
	return "http://issuer.example.com/auth?response_type=code&client_id=app"
}

// A token request issued to a cleartext /connect/token endpoint.
func insecureTokenRequest() (*http.Response, error) {
	// ruleid: auth.go.oauth.insecure-token-endpoint
	return http.Post("http://issuer.example.com/connect/token", "application/x-www-form-urlencoded", nil)
}

func main() {}
SAFE
safe.go
package main

import (
	"net/http"

	"golang.org/x/oauth2"
)

// Safe: every OAuth endpoint uses https://.
func secureConfig() *oauth2.Config {
	return &oauth2.Config{
		ClientID: "client",
		// ok: auth.go.oauth.insecure-token-endpoint
		Endpoint: oauth2.Endpoint{
			AuthURL:  "https://issuer.example.com/oauth/authorize",
			TokenURL: "https://issuer.example.com/oauth/token",
		},
	}
}

// Safe: localhost over http is allowed for local development.
func localDevToken() (*http.Response, error) {
	// ok: auth.go.oauth.insecure-token-endpoint
	return http.Post("http://localhost:8080/oauth/token", "application/x-www-form-urlencoded", nil)
}

// Safe trap: a generic cleartext http URL with no OAuth marker is not an
// OAuth endpoint and must not be flagged.
func fetchHealth() (*http.Response, error) {
	// ok: auth.go.oauth.insecure-token-endpoint
	return http.Get("http://issuer.example.com/healthz")
}

func main() {}

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.oauth.insecure-token-endpoint -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc6749#section-3.1 ↗https://datatracker.ietf.org/doc/html/rfc6749#section-10.9 ↗https://cwe.mitre.org/data/definitions/319.html ↗