From: Emmanuel T Odeke
Date: Wed, 2 Sep 2020 08:08:02 +0000 (-0700)
Subject: net/http: reject negative suffix-length Range:bytes=--N with 416 status code
X-Git-Tag: go1.16beta1~1137
X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ef20f76b8bc4e082d5f81fd818890d707751475b;p=gostls13.git
net/http: reject negative suffix-length Range:bytes=--N with 416 status code
Fixes the file server to reject requests of the form:
"Range": "bytes=--N"
where "-N" is a negative suffix-length as designated by the
grammar in RFC 7233 Section 2.1, "Byte-Ranges", which specifies
that suffix-length MUST be of the form 1*DIGIT aka a non-negative digit.
Thus requests such as:
"Range": "bytes=--2"
will be rejected with a "416 Range Not Satisfiable" response.
Fixes #40940
Change-Id: I3e89f8326c14af30d8bdb126998a50e02ba002d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/252497
Run-TryBot: Emmanuel Odeke
TryBot-Result: Gobot Gobot
Reviewed-by: Bryan C. Mills
---
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 7738cbdada..8dd806e9f2 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -167,3 +167,9 @@ Do not send CLs removing the interior tags from such phrases.
handler serves a 404 instead of its previous behavior of invoking the
underlying handler with a mismatched Path
/RawPath
pair.
+
+
+ The net/http
package now rejects HTTP range requests
+ of the form "Range": "bytes=--N"
where "-N"
is a negative suffix length, for
+ example "Range": "bytes=--2"
. It now replies with a 416 "Range Not Satisfiable"
response.
+
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 922706ada1..d718fffba0 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -771,9 +771,15 @@ func parseRange(s string, size int64) ([]httpRange, error) {
var r httpRange
if start == "" {
// If no start is specified, end specifies the
- // range start relative to the end of the file.
+ // range start relative to the end of the file,
+ // and we are dealing with
+ // which has to be a non-negative integer as per
+ // RFC 7233 Section 2.1 "Byte-Ranges".
+ if end == "" || end[0] == '-' {
+ return nil, errors.New("invalid range")
+ }
i, err := strconv.ParseInt(end, 10, 64)
- if err != nil {
+ if i < 0 || err != nil {
return nil, errors.New("invalid range")
}
if i > size {
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index 245d9ce65c..4ac73b728f 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -1316,3 +1316,61 @@ func Test_scanETag(t *testing.T) {
}
}
}
+
+// Issue 40940: Ensure that we only accept non-negative suffix-lengths
+// in "Range": "bytes=-N", and should reject "bytes=--2".
+func TestServeFileRejectsInvalidSuffixLengths_h1(t *testing.T) {
+ testServeFileRejectsInvalidSuffixLengths(t, h1Mode)
+}
+func TestServeFileRejectsInvalidSuffixLengths_h2(t *testing.T) {
+ testServeFileRejectsInvalidSuffixLengths(t, h2Mode)
+}
+
+func testServeFileRejectsInvalidSuffixLengths(t *testing.T, h2 bool) {
+ defer afterTest(t)
+ cst := httptest.NewUnstartedServer(FileServer(Dir("testdata")))
+ cst.EnableHTTP2 = h2
+ cst.StartTLS()
+ defer cst.Close()
+
+ tests := []struct {
+ r string
+ wantCode int
+ wantBody string
+ }{
+ {"bytes=--6", 416, "invalid range\n"},
+ {"bytes=--0", 416, "invalid range\n"},
+ {"bytes=---0", 416, "invalid range\n"},
+ {"bytes=-6", 206, "hello\n"},
+ {"bytes=6-", 206, "html says hello\n"},
+ {"bytes=-6-", 416, "invalid range\n"},
+ {"bytes=-0", 206, ""},
+ {"bytes=", 200, "index.html says hello\n"},
+ }
+
+ for _, tt := range tests {
+ tt := tt
+ t.Run(tt.r, func(t *testing.T) {
+ req, err := NewRequest("GET", cst.URL+"/index.html", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ req.Header.Set("Range", tt.r)
+ res, err := cst.Client().Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if g, w := res.StatusCode, tt.wantCode; g != w {
+ t.Errorf("StatusCode mismatch: got %d want %d", g, w)
+ }
+ slurp, err := ioutil.ReadAll(res.Body)
+ res.Body.Close()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if g, w := string(slurp), tt.wantBody; g != w {
+ t.Fatalf("Content mismatch:\nGot: %q\nWant: %q", g, w)
+ }
+ })
+ }
+}