Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wfe: Handle empty JSON to /acme/acct like POST-as-GET #7844

Merged
merged 8 commits into from
Dec 7, 2024

Conversation

jprenken
Copy link
Contributor

@jprenken jprenken commented Nov 23, 2024

Early drafts of the ACME spec said that clients should retrieve their existing account information by POSTing the empty JSON object {} to their account URL. This instruction was removed in the final version of ACME, replaced by the concept of POST-as-GET, which uses a wholly empty body to accomplish the same goal. However, Boulder has continued to incidentally support this behavior: when we receive an empty JSON object, our updateAccount code in the RA applies their desired diff (none) on top of their current account, writes it back to the database, and returns the updated account object...which hasn't actually changed. This behavior is also half-tested by TestEmptyAccount, but that test is actually testing that the MockRA implements the same behavior as the real RA; it's not truly testing the WFE's behavior.

This PR changes the WFE to explicitly treat receiving the empty JSON object as a request to retrieve the account data unchanged, rather than implicitly relying on internal details of the RA's account-update logic, which are expected to change in #7827.

ACME clients can make an empty request to /acme/acct for their reg object. wfe.Account handles a truly empty request correctly, but has routed empty JSON objects to updateAccount, even though an update is not appropriate. This only happened to work because UpdateRegistration's impl takes an entire Registration and returns it even if unchanged.

This preserves ACMEv1 backwards compatibility when UpdateRegistration is simplified.
aarongable
aarongable previously approved these changes Nov 25, 2024
Copy link
Contributor

@aarongable aarongable left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rephrase the PR description to more fully describe this behavior. Something like:

Early drafts of the ACME spec said that clients should retrieve their existing account information by POSTing the empty JSON object {} to their account URL. This instruction was removed in the final version of ACME, replaced by the concept of POST-as-GET which uses a wholly empty body to accomplish the same goal. However, Boulder has continued to incidentally support this behavior: when we receive an empty JSON object, our updateAccount code in the RA applies their desired diff (none) on top of their current account, writes it back to the database, and returns the updated account object... which hasn't actually changed. This behavior is also half-tested by TestEmptyAccount, but that test is actually testing that the MockRA implements the same behavior as the real RA; it's not truly testing the WFE's behavior.

This PR changes the WFE to explicitly treat receiving the empty JSON object as a request to retrieve the account data unchanged, rather than implicitly relying on internal details of the RA's account-update logic.

Copy link
Contributor

@jsha jsha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a prerequisite for #7827, right? Would be good to link that in the description for ease of understanding ("when the updateAccount flow is simplified" was only enough for me to find it because I have the context paged in right now, but pull requests are used in the future to understand why changes were made).

Otherwise looks good. Nice to break out this improvement on its own. Oh, which reminds me - do we already have a test for the "{}" case?

wfe2/wfe.go Outdated Show resolved Hide resolved
Co-authored-by: Jacob Hoffman-Andrews <jsha+github@letsencrypt.org>
@jprenken
Copy link
Contributor Author

jprenken commented Dec 3, 2024

Oh, which reminds me - do we already have a test for the "{}" case?

We did, but not for the empty string "" case, oddly enough. I just hacked that case into TestEmptyAccount.

@jprenken jprenken requested review from jsha and aarongable December 3, 2024 07:38
aarongable
aarongable previously approved these changes Dec 3, 2024
wfe2/wfe_test.go Outdated Show resolved Hide resolved
jsha
jsha previously approved these changes Dec 3, 2024
@jprenken jprenken dismissed stale reviews from jsha and aarongable via 3dcc148 December 6, 2024 05:35
@jprenken jprenken requested review from aarongable and jsha December 6, 2024 05:35
@jprenken jprenken merged commit 071b8c5 into main Dec 7, 2024
12 checks passed
@jprenken jprenken deleted the unexpected-journey branch December 7, 2024 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants