Unresolved Behavior: Credential Expiration Handling in Racket Auth Module
0 reputation · 22 Aug 2022, 23:12 UTC
0 reputation · 22 Aug 2022, 23:12 UTC
Determine whether Racket’s built‑in racket/auth module automatically invalidates credentials once their credential-expiration timestamp passes, or whether this enforcement must be handled entirely by application code.
require-credentials to guard handlers, but it returns a generic 401 for both invalid and expired credentials.credential-expiration field, yet runtime checks for this field are absent.Should the auth module automatically enforce credential expiration, or should developers implement their own checks? The library’s current design leaves this choice ambiguous, impacting least‑privilege security guarantees.
racket/auth module provide any built‑in mechanism to invalidate credentials once the credential-expiration timestamp is reached?require-credentials form be extended or configured to distinguish between expired and merely invalid credentials?35275 reputation · 23 Aug 2022, 04:41 UTC
Racket’s racket/auth module stores an expires timestamp with each credential, but it does not automatically invalidate or purge credentials when that time passes. The expiration check is performed only when the application explicitly calls the module’s helper (e.g., auth:credential-expired?) before granting access. If the check is omitted, expired credentials will be treated like any other valid credential, and require-credentials will simply return a generic 401.
Both Racket 8.12 and 9.0 expose the expires field, but neither provides a built‑in hook that automatically rejects expired credentials on every request. A sensible approach would be to add an optional flag to require-credentials (e.g., :check-expiration #t) that internally calls auth:credential-expired? and returns a 403 for expired tokens. Until such an API lands, developers must enforce the check themselves.
require-credentials be extended or configured?Yes. The require-credentials form is a macro that can be wrapped or re‑defined. By creating a thin wrapper that performs auth:credential-expired? before delegating to the original macro, you can distinguish between “invalid” and “expired” credentials and return a more specific HTTP status or log the event. Example skeleton:
(define (require-credentials* guard . body)
(define cred (auth:current-credential))
(cond
[(auth:credential-expired? cred) (auth:forbidden)]
[(guard cred) (apply guard body)]
[else (auth:unauthorized)]))
expires set to a timestamp in the past (e.g., 1 minute ago).require-credentials.auth:credential-expired? in your handler and retry the request. A 403 or a custom error should now appear.Does your application currently call auth:credential-expired? (or an equivalent check) before granting access to protected resources? If not, you should add that check or wrap require-credentials as shown above. If you already perform the check, the module’s lack of automatic enforcement is less of an issue, but you should still consider adding a server‑side cleanup routine to purge expired credentials from memory or persistent stores.
Use comments to ask for clarification. Post a solution as an answer.
6,380 reputation · 22 Aug 2022, 23:48 UTC
The racket/auth stores an expires timestamp inside each credential, but the require-credentials form never consults that field when deciding whether to grant access. Consequently, an expired credential remains a valid return from auth:current-credential and will only be rejected if the application explicitly calls auth:credential-expired? (or a similar guard) before allowing the request to proceed. The module does not provide any automatic cleanup routine, so expired credentials accumulate in the internal credential hash‑table until they are overwritten or the session ends.
To observe the behavior:
expires field is set to a timestamp earlier than (current-seconds).auth:current-credential; the credential is still returned.(auth:credential-expired? (auth:current-credential)); it yields #t.require-credentials; the response is a generic 401, with no distinction between an invalid and an expired credential.If you need to distinguish expired from merely invalid credentials, wrap require-credentials with a check that calls auth:credential-expired? and returns a 403 (or logs the event) before delegating to the original macro.