fix(web-bot-auth): fail closed on expired signatures in Rust verify - #125
Conversation
WebBotAuthVerifier::verify previously accepted cryptographically valid signatures after expires. SignatureIsExpired existed but was unused, and the TypeScript http-message-sig verifier already rejects expired inputs. Enforce the expires window before crypto verify and update the sample.
verify keeps the fail-closed default (SignatureIsExpired before crypto).
The new verify_with_advisory runs full cryptographic verification and
returns AdvisoryVerification { timing, advisory } so callers that must
parse expired-but-valid signatures get the SecurityAdvisory as a warning
instead of an error, per maintainer review on cloudflare#125. Also fixes an
unclosed paren in the rust example and demonstrates the opt-in there.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
I am torn about this one. Fail-closed sounds intuitive and in line with offering fewer footguns, but it is actually not mandated by either the HTTP message signature IETF RFC or the web bot auth IETF RFC. In fact, https://www.rfc-editor.org/info/rfc9421/#name-enforcing-application-requi specifically calls this behaviour out as non-normative. Further, it will almost certainly be a breaking change for consumers of the library. One of the hard parts about protocol behaviour in the wild is that once you've exposed some behaviour, people will rely on it. For verifiers, this means signatures that used to pass will break, which can affect a large swathe of users. (Whether they should have passed in the first place is another question...) While grateful for the work, I am personally leaning towards respectfully declining this PR. I think it is better to have an implementation that adheres to the baseline specifications and allows applications to define their own non-normative behaviour rather than lock in all applications to an opinionated implementation. Verifiers can't control the signatures people send, and it is more important to be able to try to parse them and know when it is likely to be a bad idea than not to be able to parse them at all. Open to others' thoughts. I recognize the Typescript variant does it differently, and interested in how much parity we want to maintain on this front. cc @thibmeu |
|
Thanks for the PR. I agree with @AkshatM that this is better as a discussion than as a PR. I'd favor rejecting the signature as invalid as well (and failing close) by default. Having full validation with a warning that the signature is expired seems to be an option that needs to be passed, but not something that should be exposed by default. I agree that neither RFC 9421 or the web-bot-auth draft clearly specify that application pattern. For the later, that's probably worth having a short text. |
I like this option, and, if implemented this way , I would be happy to approve and merge. Feel it addresses all components. @SashaMIT - could you implement an optional behaviour to parse with warnings in addition to this change? |
|
Done, thanks both. On the normativity point: agreed that RFC 9421 leaves this to application requirements, which is why enforcement stays opt-out rather than removed. The default keeps parity with Tests: |
| /// RFC 9421 leaves enforcement of application requirements such as expiry | ||
| /// to the application; this opt-in serves verifiers that need to parse and | ||
| /// judge such signatures themselves rather than reject them up front. | ||
| pub fn verify_with_advisory( |
There was a problem hiding this comment.
nit: change function name to verify_ignore_expiry. More clear about what this does.
Matches maintainer naming: the opt-in path ignores the expires window and still runs full cryptographic verification.
|
Renamed to |
…erify (#127) * fix(web-bot-auth): fail closed on future created timestamps in Rust verify WebBotAuthVerifier::verify already rejects expired signatures after #125, but still accepted cryptographically valid signatures with created in the future. The TypeScript web-bot-auth verifier rejects those before crypto verify. Enforce the created window the same way, before expires, and surface SignatureCreatedInFuture. verify_ignore_expiry still runs crypto and reports the new advisory flag. * docs(web-bot-auth): drop still from created-in-future comment
Summary
WebBotAuthVerifier::verifyaccepted cryptographically valid signatures afterexpires, even thoughWebBotAuthError::SignatureIsExpiredalready exists and the TypeScripthttp-message-sigverifier rejects expired inputs before crypto verify.This makes the Rust Web Bot Auth verifier fail closed on an expired (or unparsable)
expireswindow, then proceeds to cryptographic verification only when the window is still valid. The sample underexamples/rust/verify.rsis updated to match.Advisory inspection via
possibly_insecureremains available throughget_parsed_label()for callers that want the soft check separately. GenericMessageVerifier::verifyis unchanged.Test plan
cargo test -p web-bot-auth --lib(29 passed)cargo run -p rust-examples --bin verifyMade with Cursor