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.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. http://localhost is fine for local development and is not flagged.

VULNERABLE
vulnerable.ts
// OAuth/OIDC endpoints contacted over cleartext http:// — codes, secrets and
// tokens travel unencrypted.

// ruleid: auth.oauth.insecure-token-endpoint
export const authorizeUrl =
  'http://auth.example.com/authorize?response_type=code&client_id=abc&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcb';

export async function exchange(code: string) {
  // ruleid: auth.oauth.insecure-token-endpoint
  return fetch('http://idp.example.com/oauth/token', {
    method: 'POST',
    body: `grant_type=authorization_code&code=${code}&client_id=abc`,
  });
}

// IdentityServer-style discovery / token path over http.
// ruleid: auth.oauth.insecure-token-endpoint
const tokenEndpoint = 'http://login.example.com/connect/token';

export function useToken() {
  return tokenEndpoint;
}
SAFE
safe.ts
// All OAuth/OIDC endpoints use TLS; the only http:// URL is a loopback dev
// host, which is explicitly allowed.

// ok: auth.oauth.insecure-token-endpoint
export const authorizeUrl =
  'https://auth.example.com/authorize?response_type=code&client_id=abc&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcb';

export async function exchange(code: string) {
  // ok: auth.oauth.insecure-token-endpoint
  return fetch('https://idp.example.com/oauth/token', {
    method: 'POST',
    body: `grant_type=authorization_code&code=${code}&client_id=abc`,
  });
}

// Local development against a loopback IdP — not flagged.
// ok: auth.oauth.insecure-token-endpoint
const devTokenEndpoint = 'http://localhost:8080/connect/token';

// A plain http URL with no OAuth markers is out of scope for this rule.
// ok: auth.oauth.insecure-token-endpoint
const healthCheck = 'http://status.example.com/healthz';

export function endpoints() {
  return [devTokenEndpoint, healthCheck];
}

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.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 ↗