Skip to content

Commit

Permalink
fix issue #875
Browse files Browse the repository at this point in the history
Signed-off-by: Kirill Danshin <kirill@danshin.pro>
  • Loading branch information
kirillDanshin committed Nov 8, 2020
1 parent c2542e5 commit 61f1899
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
8 changes: 7 additions & 1 deletion header.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"strings"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -2167,9 +2168,14 @@ func nextLine(b []byte) ([]byte, []byte, error) {
return b[:n], b[nNext+1:], nil
}

var (
foldReplacer = strings.NewReplacer("\r\n", " ", "\r", " ", "\n", " ")
)

func initHeaderKV(kv *argsKV, key, value string, disableNormalizing bool) {
kv.key = getHeaderKeyBytes(kv, key, disableNormalizing)
kv.value = append(kv.value[:0], value...)
// https://tools.ietf.org/html/rfc7230#section-3.2.4
kv.value = append(kv.value[:0], foldReplacer.Replace(value)...)
}

func getHeaderKeyBytes(kv *argsKV, key string, disableNormalizing bool) []byte {
Expand Down
48 changes: 48 additions & 0 deletions http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/ioutil"
"mime/multipart"
"reflect"
"strconv"
"strings"
"testing"
"time"
Expand All @@ -30,6 +31,53 @@ func TestFragmentInURIRequest(t *testing.T) {
}
}

func TestIssue875(t *testing.T) {
type testcase struct {
uri string
expectedRedirect string
expectedLocation string
}

var testcases = []testcase{
{
uri: `http://localhost:3000/?redirect=foo%0d%0aSet-Cookie:%20SESSIONID=MaliciousValue%0d%0a`,
expectedRedirect: "foo\r\nSet-Cookie: SESSIONID=MaliciousValue\r\n",
expectedLocation: "Location: foo Set-Cookie: SESSIONID=MaliciousValue",
},
{
uri: `http://localhost:3000/?redirect=foo%0dSet-Cookie:%20SESSIONID=MaliciousValue%0d%0a`,
expectedRedirect: "foo\rSet-Cookie: SESSIONID=MaliciousValue\r\n",
expectedLocation: "Location: foo Set-Cookie: SESSIONID=MaliciousValue",
},
{
uri: `http://localhost:3000/?redirect=foo%0aSet-Cookie:%20SESSIONID=MaliciousValue%0d%0a`,
expectedRedirect: "foo\nSet-Cookie: SESSIONID=MaliciousValue\r\n",
expectedLocation: "Location: foo Set-Cookie: SESSIONID=MaliciousValue",
},
}

for i, tcase := range testcases {
caseName := strconv.FormatInt(int64(i), 10)
t.Run(caseName, func(subT *testing.T) {
ctx := &RequestCtx{
Request: Request{},
Response: Response{},
}
ctx.Request.SetRequestURI(tcase.uri)

q := string(ctx.QueryArgs().Peek("redirect"))
if q != tcase.expectedRedirect {
subT.Errorf("unexpected redirect query value, got: %+v", q)
}
ctx.Response.Header.Set("Location", q)

if !strings.Contains(ctx.Response.String(), tcase.expectedLocation) {
subT.Errorf("invalid escaping, got\n%s", ctx.Response.String())
}
})
}
}

func TestRequestCopyTo(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 61f1899

Please sign in to comment.