From 6d1f439253c78d8fe972b680e8f95b34151e8270 Mon Sep 17 00:00:00 2001 From: Phil Porada Date: Thu, 20 Jun 2024 12:28:40 -0400 Subject: [PATCH] WFE: Normalize SANs in NewOrder request (#7554) In #7530, `wfe.NewOrder` [began constructing a rate limit transaction](https://github.com/letsencrypt/boulder/pull/7530/files#diff-3f950e720c205ce9fa8dea12c6fd7fd44272c2671f19d0e06962abfbea00d491R2340-R2344) with a precondition that all names must be lower-cased, however the actual implementation of the precondition was accidentally overlooked. This fix corrects that and adds a unit test to prevent a future regression. Other changes: - Only normalized names count towards max names limit - Only normalized names will be logged in the web.RequestEvent --------- Co-authored-by: Samantha Frank --- wfe2/wfe.go | 1 + wfe2/wfe_test.go | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/wfe2/wfe.go b/wfe2/wfe.go index 756cef2f2f3..1b3cc0b1559 100644 --- a/wfe2/wfe.go +++ b/wfe2/wfe.go @@ -2337,6 +2337,7 @@ func (wfe *WebFrontEndImpl) NewOrder( names[i] = ident.Value } + names = core.UniqueLowerNames(names) err = policy.WellFormedDomainNames(names) if err != nil { wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "Invalid identifiers requested"), nil) diff --git a/wfe2/wfe_test.go b/wfe2/wfe_test.go index 6c125319648..05036987b8d 100644 --- a/wfe2/wfe_test.go +++ b/wfe2/wfe_test.go @@ -2467,7 +2467,7 @@ func TestNewOrder(t *testing.T) { nonDNSIdentifierBody := ` { "Identifiers": [ - {"type": "dns", "value": "not-example.com"}, + {"type": "dns", "value": "not-example.com"}, {"type": "dns", "value": "www.not-example.com"}, {"type": "fakeID", "value": "www.i-am-21.com"} ] @@ -2477,11 +2477,19 @@ func TestNewOrder(t *testing.T) { validOrderBody := ` { "Identifiers": [ - {"type": "dns", "value": "not-example.com"}, + {"type": "dns", "value": "not-example.com"}, {"type": "dns", "value": "www.not-example.com"} ] }` + validOrderBodyWithMixedCaseIdentifiers := ` + { + "Identifiers": [ + {"type": "dns", "value": "Not-Example.com"}, + {"type": "dns", "value": "WWW.Not-example.com"} + ] + }` + // Body with a SAN that is longer than 64 bytes. This one is 65 bytes. tooLongCNBody := ` { @@ -2583,8 +2591,8 @@ func TestNewOrder(t *testing.T) { "status": "pending", "expires": "2021-02-01T01:01:01Z", "identifiers": [ - { "type": "dns", "value": "thisreallylongexampledomainisabytelongerthanthemaxcnbytelimit.com"}, - { "type": "dns", "value": "not-example.com"} + { "type": "dns", "value": "not-example.com"}, + { "type": "dns", "value": "thisreallylongexampledomainisabytelongerthanthemaxcnbytelimit.com"} ], "authorizations": [ "http://localhost/acme/authz-v3/1" @@ -2609,6 +2617,23 @@ func TestNewOrder(t *testing.T) { "finalize": "http://localhost/acme/finalize/1/1" }`, }, + { + Name: "POST, good payload, but when the input had mixed case", + Request: signAndPost(signer, targetPath, signedURL, validOrderBodyWithMixedCaseIdentifiers), + ExpectedBody: ` + { + "status": "pending", + "expires": "2021-02-01T01:01:01Z", + "identifiers": [ + { "type": "dns", "value": "not-example.com"}, + { "type": "dns", "value": "www.not-example.com"} + ], + "authorizations": [ + "http://localhost/acme/authz-v3/1" + ], + "finalize": "http://localhost/acme/finalize/1/1" + }`, + }, } for _, tc := range testCases {