Revision history for Punk-OAuth2
0.05 2026-08-20
- FIX: change abi version checks from == to <=
0.04 2026-08-18
- SECURITY fix CVE-2026-75866: the authorization server issued access tokens outside
a client's registration, reported by cpansec.
- grant_types and scopes are now enforced, deny by default.
- SECURITY: client_credentials is refused to a public client with
invalid_client (RFC 6749 4.4).
- COMPATIBILITY: a client registered without scopes now gets no
scope, and one registered without grant_types can use no grant.
0.03 2026-08-18
- SECURITY: fix an open redirect in same_origin_path
(CVE-2026-75628) reported by cpansec. The guard rejected a leading "//" and any
CR/LF, but a browser removes TAB/CR/LF from a URL before it
parses it and treats "\" as "/" under a special scheme, so
"/\evil.example" and "/<TAB>/evil.example" both survived the
check and then resolved to another host. A ?return= destination
that a user controls could therefore redirect off-site after a
successful login.
- same_origin_path now rejects every C0 control byte and DEL, and
rejects a backslash anywhere in the path, rather than trying to
enumerate the bytes a URL parser might drop. Paths that need a
backslash must percent-encode it as %5C.
0.02 2026-08-16
Fix stack corruption in the DBI-backed server store: SvIV(POPs)
in pox_dbi_do (and SvTRUE(POPs) in pox_await) evaluate POPs
twice, walking the stack pointer back into the caller's
arguments.
0.01 2026-08-15
First version.
- the client side of OAuth2 and OpenID Connect for Punk:
authorization-code flow with PKCE (S256), signed single-use
state, OIDC nonce, id_token verification through Crypt::JWS and
a cached JWKS, normalized identities
- oauth2 and oauth2_login keywords (both plugin/keyword orderings
valid, to_app tripwire); presets google, github, generic oidc
with RFC 8414/OIDC discovery (issuer-checked, SSRF-guarded)
- context helpers oauth2_authurl, oauth2_refresh, oauth2_provider
- implemented in XS over the house C ABIs (jws_abi, frj_abi,
fetch_abi), with an xs/ directory of fragments like Punk: the
Provider and JWKS objects, Tokens, presets, the whole login
flow (state/nonce/PKCE mint, session flow records, the
callback's state/iss/code validation, token exchange, identity
normalization), id_token verification, form/URL/base_url/
safe_url/await all run in C; the only Perl is the plugin's Punk
registration wiring (install_kw/route/helper) and POD-only
module loaders
- identity-only session default: provider tokens are handed to
on_login and discarded (nothing token-shaped in the 4KB
signed-cookie session)
- authorization server (oauth2_server keyword): /authorize,
/token, /revoke, /introspect, /jwks.json and RFC 8414
metadata; grants authorization_code + PKCE (S256), refresh
with rotation and family revocation on reuse, and
client_credentials; ES256 JWT access tokens (RFC 9068 at+jwt)
the resource-server checker validates statelessly; client auth
(basic or body, constant-time on digests); authenticate and
consent hooks; a pluggable DBI store (SQLite, digest-only,
auto_migrate) - all protocol logic in XS
- resource-server checkers (Punk::OAuth2::Checker): jwt (local
JWT validation via JWKS or a static key - allowlist, signature,
iss/aud/exp/nbf, scope) and introspect (RFC 7662, cached by
token SHA-256), matching the OpenAPI security-map contract,
plus a guard wrapper emitting RFC 6750 WWW-Authenticate
(401 invalid_token / 403 insufficient_scope); all validation
in XS