Skip to content

Harden JWTProvider device-flow token poll against non-JSON responses#1697

Open
BorisTyshkevich wants to merge 2 commits intoantalya-26.1from
pr2-jwt-token-poll-hardening
Open

Harden JWTProvider device-flow token poll against non-JSON responses#1697
BorisTyshkevich wants to merge 2 commits intoantalya-26.1from
pr2-jwt-token-poll-hardening

Conversation

@BorisTyshkevich
Copy link
Copy Markdown
Collaborator

Summary

JWTProvider::deviceCodeLogin parsed each token-endpoint response with Poco::JSON::Parser().parse(...).extract<Object::Ptr>() unconditionally. When the IdP (or a CDN in front of it) returned a non-JSON body — an HTML error page, an empty body on transient TCP/TLS failure, a non-object JSON value — the extract() call threw std::bad_cast and aborted the whole device flow with no useful diagnostic, even though the underlying problem was transient.

Wrap parse + extract in try/catch and treat any parse failure as "transient — keep polling". The device flow is by design tolerant of intermittent token-endpoint errors (RFC 8628 §3.5 lists slow_down / authorization_pending as expected during the polling window), and the outer expires_in clamp bounds total retry time, so a missed poll has no worse impact than a slow_down. Emit a warning naming the status code and a body excerpt so operators can debug systemic IdP issues without losing the login.

Test plan

  • Build clean against antalya-26.1
  • Existing happy-path device flow still completes and obtains a token
  • Reviewer: simulate non-JSON token response (e.g., 502 from a proxy) and confirm the loop continues to next interval rather than aborting

🤖 Generated with Claude Code

JWTProvider::deviceCodeLogin parsed each token-endpoint response with
Poco::JSON::Parser().parse(...).extract<Object::Ptr>() unconditionally.
When the IdP (or a CDN in front of it) returned a non-JSON body — an
HTML error page, an empty body on transient TCP/TLS failure, a non-
object JSON value — the extract() call threw std::bad_cast and aborted
the whole device flow with no useful diagnostic, even though the
problem was transient.

Wrap parse + extract in try/catch and treat any parse failure as
"transient — keep polling". The device flow is by design tolerant of
intermittent token-endpoint errors (RFC 8628 §3.5 lists slow_down /
authorization_pending as expected during the polling window), and the
outer expires_in clamp bounds total retry time, so a missed poll has
no worse impact than a slow_down. Emit a warning naming the status
code and a body excerpt so operators can debug systemic IdP issues
without losing the login.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Signed-off-by: Boris Tyshkevich <btyshkevich@altinity.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Workflow [PR], commit [346a381]

Signed-off-by: Boris Tyshkevich <btyshkevich@altinity.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants