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 →
MEDIUM AI PREVALENCE: LOW auth.kotlin.android.pkce-disabled

An AppAuth AuthorizationRequest.Builder explicitly disables PKCE with .setCodeVerifier(null).

Why AI tools produce this: AI coding tools rarely emit this on their own, but it still slips into assisted edits.

Why this matters

PKCE (RFC 7636) is what stops a malicious app that has registered the same redirect URI, or an attacker who intercepts the authorization code on a mobile device, from exchanging that code for tokens. Turning it off on a public Android client re-opens the authorization-code interception attack (CWE-345). AI samples pass null after seeing the "disable PKCE if the server does not support it" comment in the AppAuth docs.

Leave PKCE on: simply do not call setCodeVerifier, and AppAuth's Builder generates a code verifier automatically. Only pass an explicit verifier you generated yourself, never null.

VULNERABLE
vulnerable.kt
import net.openid.appauth.AuthorizationRequest
import net.openid.appauth.ResponseTypeValues
import android.net.Uri

fun buildRequest(config: Any, redirect: Uri): AuthorizationRequest {
    // ruleid: auth.kotlin.android.pkce-disabled
    return AuthorizationRequest.Builder(config, "client-id", ResponseTypeValues.CODE, redirect)
        .setScope("openid profile")
        .setCodeVerifier(null)
        .build()
}
SAFE
safe.kt
import net.openid.appauth.AuthorizationRequest
import net.openid.appauth.ResponseTypeValues
import android.net.Uri

// PKCE left on (Builder auto-generates the verifier): safe
fun buildRequest(config: Any, redirect: Uri): AuthorizationRequest {
    return AuthorizationRequest.Builder(config, "client-id", ResponseTypeValues.CODE, redirect)
        .setScope("openid profile")
        .build()
}

// explicit, self-generated verifier: safe
fun buildWithVerifier(config: Any, redirect: Uri, verifier: String): AuthorizationRequest {
    return AuthorizationRequest.Builder(config, "client-id", ResponseTypeValues.CODE, redirect)
        .setCodeVerifier(verifier)
        .build()
}

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.kotlin.android.pkce-disabled -- <reason>

References

https://github.com/openid/AppAuth-Android ↗https://datatracker.ietf.org/doc/html/rfc7636 ↗https://cwe.mitre.org/data/definitions/345.html ↗