Skip to content

feat(cas-auth): sign request URI cookie and tighten cookie attributes#13331

Open
shreemaan-abhishek wants to merge 3 commits intoapache:masterfrom
shreemaan-abhishek:feat/cas-auth-cookie-integrity
Open

feat(cas-auth): sign request URI cookie and tighten cookie attributes#13331
shreemaan-abhishek wants to merge 3 commits intoapache:masterfrom
shreemaan-abhishek:feat/cas-auth-cookie-integrity

Conversation

@shreemaan-abhishek
Copy link
Copy Markdown
Contributor

@shreemaan-abhishek shreemaan-abhishek commented May 5, 2026

Description

This change updates the cas-auth plugin so that the CAS_REQUEST_URI cookie — which the plugin uses to remember where the user was headed before being bounced to the CAS IdP — is signed with HMAC-SHA256 and verified on the IdP callback using a constant-time comparison.

After successful CAS ticket validation, the recovered redirect target is also validated as a same-origin path before being applied; if the cookie is missing, malformed, fails signature verification, or carries something that is not a relative path, the plugin falls back to / instead of using the cookie value verbatim.

A new required cookie object is added to the plugin schema:

  • cookie.secret (string, required, minLength 32) — HMAC-signing key. Must match across all APISIX nodes so cookies issued on one node remain verifiable on another. Encrypted at rest via schema.encrypt_fields.
  • cookie.secure (boolean, default true) — whether to set the Secure attribute on issued cookies. Set to false only for deployments where the protected route is not served over HTTPS.
  • cookie.samesite (string, default "Lax", enum "Lax"/"None") — value for the SameSite cookie attribute. "Strict" is intentionally not exposed because it suppresses the cookie on the IdP→SP top-level redirect when the IdP is on a different site.

HttpOnly continues to be set unconditionally on the issued cookies. t/lib/keycloak_cas.lua is updated so existing integration tests continue to pass; new tests in t/plugin/cas-auth.t exercise the schema constraints, the safe-redirect predicate, and the HMAC sign/verify roundtrip including tampering, wrong-secret, and malformed-cookie cases.

Which issue(s) this PR fixes:

N/A

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

The CAS_REQUEST_URI cookie used by the plugin to remember the
pre-login URL is now signed with HMAC-SHA256 and verified on the
IdP callback using a constant-time comparison. The recovered
redirect target is also validated as a same-origin path before
being applied; on mismatch the plugin falls back to /.

Cookie attributes are tightened to include Secure; SameSite=Lax.

Adds a required cookie_secret field (minLength 32) to the plugin
schema. The same value must be configured on every APISIX node.
- Move cookie options under a nested cookie object: cookie.secret,
  cookie.secure (default true), cookie.samesite (default Lax, enum
  Lax|None). Strict is intentionally omitted because it breaks the
  IdP->SP cross-site redirect.
- Mark cookie.secret as encrypt_fields so it is encrypted at rest in
  etcd, matching how other plugins protect plugin secrets.
- Guard first_access against sign_value returning nil so a transient
  HMAC failure cannot crash the request with a Lua concatenation
  error; fall through and let the safe-redirect fallback take over.
- Capture and log the error from compute_hmac in verify_value rather
  than dropping it.
- Build cookie attributes per-config so deployments that legitimately
  run over HTTP can disable Secure without giving up SameSite.
- Strip session identifiers, ticket values, and full request URIs
  from info-level logs; demote raw SLO LogoutRequest body to debug.
- Update t/lib/keycloak_cas.lua and t/plugin/security-warning.t for
  the new schema; add unit-style tests for the schema, the safe
  redirect predicate, and the HMAC sign/verify roundtrip with
  tampering, wrong-secret, and malformed-input cases.
@shreemaan-abhishek shreemaan-abhishek marked this pull request as ready for review May 7, 2026 11:11
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels May 7, 2026
- Move encrypt_fields = {"cookie.secret"} from the plugin module
  table into the schema table. The framework's encryption pipeline
  reads schema.encrypt_fields (apisix/plugin.lua); declaring it on
  _M was silently a no-op and meant cookie.secret was being stored
  in plaintext at rest in etcd despite the previous claim. Other
  plugins (basic-auth, openid-connect, etc.) place it on the schema
  table for the same reason.
- Drop the debug-level log of the raw SLO LogoutRequest body. Even
  at debug level, the body contains the SAML SessionIndex (the
  ticket value the plugin reuses as a session id), which is
  authentication material that should not be written to logs at any
  level. The "SLO request received from IdP" info log already
  captures the operational signal; raw-body inspection can be done
  via packet capture if ever needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant