Skip to content

Commit faf458d

Browse files
committed
Do not sign conditional request headers
1 parent 9f5337a commit faf458d

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,13 @@ Note that, if you use the `$host` configuration, you must configure a [Route](ht
102102

103103
### Restricting Signed HTTP Headers in the Upstream Request
104104

105-
By default, all HTTP headers in the downstream request from the client are signed and included in the upstream request to Backlaze B2, except the following:
105+
By default, all HTTP headers in the downstream request from the client are signed and included in the upstream request to Backblaze B2, except the following:
106106

107107
* Cloudflare headers with the prefix `cf-`, plus `x-forwarded-proto` and `x-real-ip`: these are set in the downstream request by Cloudflare, rather than by the client. In addition, `x-real-ip` is removed from the upstream request.
108108
* `accept-encoding`: No matter what the client passes, Cloudflare sets `accept-encoding` in the incoming request to `gzip, br` and then modifies the outgoing request, setting `accept-encoding` to `gzip`. This breaks the AWS v4 signature.
109+
* Conditional headers such as `if-match` and `if-modified-since` may be sent by the client but Cloudflare does not forward them in the upstream request if it does not have the resource in its cache, since Cloudflare needs the resource unconditionally.
109110

110-
If you wish to further restrict the set of headers that will be signed and included, you can configure `ALLOWED_HEADERS` in `wrangler.toml`. If `ALLOWED_HEADERS` is set, then the listed headers will be included in the signed upstream request alongside the minimal set of headers required for an AWS v4 signature: `authorization`, `x-amz-content-sha256` and `x-amz-date`.
111+
If you wish to further restrict the set of headers that will be signed and included, you can configure `ALLOWED_HEADERS` in `wrangler.toml`. If `ALLOWED_HEADERS` is set, then the listed headers will be included in the signed upstream request alongside the minimal set of headers required for an AWS v4 signature: `authorization`, `x-amz-content-sha256` and `x-amz-date`.
111112

112113
Note that, if `x-amz-content-sha256` is not included in `ALLOWED_HEADERS`, then any value supplied in the incoming request will be discarded and `x-amz-content-sha256` will be set to `UNSIGNED-PAYLOAD` in the outgoing request.
113114

@@ -118,10 +119,6 @@ ALLOWED_HEADERS = [
118119
"content-type",
119120
"date",
120121
"host",
121-
"if-match",
122-
"if-modified-since",
123-
"if-none-match",
124-
"if-unmodified-since",
125122
"range",
126123
"x-amz-content-sha256",
127124
"x-amz-date",

index.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66
import { AwsClient } from 'aws4fetch'
77

88
const UNSIGNABLE_HEADERS = [
9-
// These headers appear in the request, but are not passed upstream
9+
// These headers appear in the request, but are never passed upstream
1010
'x-forwarded-proto',
1111
'x-real-ip',
1212
// We can't include accept-encoding in the signature because Cloudflare
1313
// sets the incoming accept-encoding header to "gzip, br", then modifies
1414
// the outgoing request to set accept-encoding to "gzip".
1515
// Not cool, Cloudflare!
1616
'accept-encoding',
17-
// Not consistently passed upstream, causing flaky errors
17+
// Conditional headers are not consistently passed upstream
18+
'if-match',
1819
'if-modified-since',
20+
'if-none-match',
21+
'if-range',
22+
'if-unmodified-since',
1923
];
2024

2125
// URL needs colon suffix on protocol, and port as a string
@@ -30,11 +34,12 @@ function filterHeaders(headers, env) {
3034
// Suppress irrelevant IntelliJ warning
3135
// noinspection JSCheckFunctionSignatures
3236
return new Headers(Array.from(headers.entries())
33-
.filter(pair =>
34-
!UNSIGNABLE_HEADERS.includes(pair[0])
35-
&& !pair[0].startsWith('cf-')
36-
&& !('ALLOWED_HEADERS' in env && !env['ALLOWED_HEADERS'].includes(pair[0]))
37-
));
37+
.filter(pair => !(
38+
UNSIGNABLE_HEADERS.includes(pair[0])
39+
|| pair[0].startsWith('cf-')
40+
|| ('ALLOWED_HEADERS' in env && !env['ALLOWED_HEADERS'].includes(pair[0]))
41+
))
42+
);
3843
}
3944

4045
function createHeadResponse(response) {

0 commit comments

Comments
 (0)