Skip to content

feat: add PKCE (S256) to installed-app auth flow #693

@RedSlowpoke

Description

@RedSlowpoke

Why

RFC 7636 / RFC 8252 recommend PKCE for native/installed apps. Without it, a local malicious process that wins the race to bind the loopback port before gog can receive the authorization code and exchange it for a token — PKCE binds the exchange to the original authorization request, making the stolen code useless.

Google's OAuth 2.0 endpoint supports S256 for Desktop app clients.

Current state

The current OAuth flow in internal/googleauth/oauth_flow.go uses cfg.AuthCodeURL(state, ...) and cfg.Exchange(ctx, code) without PKCE. The project already depends on golang.org/x/oauth2 which ships PKCE support since v0.17.0 (pkce.go: GenerateVerifier, S256ChallengeOption, VerifierOption).

What's missing

// authorizeServer — before building authURL
verifier := oauth2.GenerateVerifier()

// AuthCodeURL call
authURL := cfg.AuthCodeURL(state,
    append(authURLParams(opts.ForceConsent, !opts.DisableIncludeGrantedScopes),
        oauth2.S256ChallengeOption(verifier))...)

// Exchange call
tok, exchangeErr := cfg.Exchange(ctx, code, oauth2.VerifierOption(verifier))

Same change applies to the manual redirect flow in oauth_flow_manual_redirect.go — the verifier needs to survive between step 1 (generate auth URL) and step 2 (exchange code).

Scope

~10–15 lines in oauth_flow.go, similar in oauth_flow_manual_redirect.go. No new dependencies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal priority bug or improvement with limited blast radius.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:securityThis issue is about security boundaries, credentials, authz, sandboxing, or sensitive data.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions