Skip to content

Commit

Permalink
Allow Content-Type header in V2 CORS. (#3559)
Browse files Browse the repository at this point in the history
We are soon enforcing that V2 POST requests have a `Content-Type` of
`application/jose+json` to match ACME specification requirement. For
CORS this requires adding the `Content-Type` to the
`Access-Control-Allow-Headers` CORS field because the JOSE content type
is not one that can be used by a "simple header" whitelisted by default.

This commit adds `Access-Control-Allow-Headers: Content-Type` where
required and updates unit tests accordingly.
  • Loading branch information
cpu authored and jsha committed Mar 14, 2018
1 parent 700604d commit 7e5f22d
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
8 changes: 8 additions & 0 deletions wfe2/wfe.go
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,14 @@ func (wfe *WebFrontEndImpl) setCORSHeaders(response http.ResponseWriter, request
// For an OPTIONS request: allow all methods handled at this URL.
response.Header().Set("Access-Control-Allow-Methods", allowMethods)
}
// NOTE(@cpu): "Content-Type" is considered a 'simple header' that doesn't
// need to be explicitly allowed in 'access-control-allow-headers', but only
// when the value is one of: `application/x-www-form-urlencoded`,
// `multipart/form-data`, or `text/plain`. Since `application/jose+json` is
// not one of these values we must be explicit in saying that `Content-Type`
// is an allowed header. See MDN for more details:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
response.Header().Set("Access-Control-Allow-Headers", "Content-Type")
response.Header().Set("Access-Control-Expose-Headers", "Link, Replay-Nonce, Location")
response.Header().Set("Access-Control-Max-Age", "86400")
}
Expand Down
7 changes: 7 additions & 0 deletions wfe2/wfe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ func TestHandleFunc(t *testing.T) {
test.AssertEquals(t, rw.Code, http.StatusOK)
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Methods"), "")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "*")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "Content-Type")
test.AssertEquals(t, sortHeader(rw.Header().Get("Access-Control-Expose-Headers")), "Link, Location, Replay-Nonce")

// CORS preflight request for disallowed method
Expand All @@ -524,6 +525,7 @@ func TestHandleFunc(t *testing.T) {
test.AssertEquals(t, rw.Code, http.StatusOK)
test.AssertEquals(t, rw.Header().Get("Allow"), "GET, HEAD")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "")

// CORS preflight request for allowed method
runWrappedHandler(&http.Request{
Expand All @@ -536,6 +538,7 @@ func TestHandleFunc(t *testing.T) {
}, "/test", "GET", "POST")
test.AssertEquals(t, rw.Code, http.StatusOK)
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "*")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "Content-Type")
test.AssertEquals(t, rw.Header().Get("Access-Control-Max-Age"), "86400")
test.AssertEquals(t, sortHeader(rw.Header().Get("Access-Control-Allow-Methods")), "GET, HEAD, POST")
test.AssertEquals(t, sortHeader(rw.Header().Get("Access-Control-Expose-Headers")), "Link, Location, Replay-Nonce")
Expand All @@ -550,6 +553,7 @@ func TestHandleFunc(t *testing.T) {
}, "/test", "GET", "POST")
test.AssertEquals(t, rw.Code, http.StatusOK)
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "")
test.AssertEquals(t, sortHeader(rw.Header().Get("Allow")), "GET, HEAD, POST")

// CORS preflight request missing optional Request-Method
Expand All @@ -564,9 +568,11 @@ func TestHandleFunc(t *testing.T) {
test.AssertEquals(t, rw.Code, http.StatusOK)
if allowedMethod == "GET" {
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "*")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "Content-Type")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Methods"), "GET, HEAD")
} else {
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Origin"), "")
test.AssertEquals(t, rw.Header().Get("Access-Control-Allow-Headers"), "")
}
}

Expand All @@ -588,6 +594,7 @@ func TestHandleFunc(t *testing.T) {
for _, h := range []string{
"Access-Control-Allow-Methods",
"Access-Control-Allow-Origin",
"Access-Control-Allow-Headers",
"Access-Control-Expose-Headers",
"Access-Control-Request-Headers",
} {
Expand Down

0 comments on commit 7e5f22d

Please sign in to comment.