Skip to content

Commit 5c4a101

Browse files
Add test and fix for malformed/truncated header
1 parent 18c1c89 commit 5c4a101

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

headerv2.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,24 @@ func parseV2(r *bufio.Reader) (*HeaderV2, error) {
5050
}
5151

5252
// highest 4 indicate address family
53-
if (rawHdr.FamProto >> 4) > 3 {
53+
switch rawHdr.FamProto >> 4 {
54+
case 0: // local
55+
if rawHdr.Len != 0 {
56+
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid length")}
57+
}
58+
case 1: // ipv4
59+
if rawHdr.Len != 12 {
60+
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid length")}
61+
}
62+
case 2: // ipv6
63+
if rawHdr.Len != 36 {
64+
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid length")}
65+
}
66+
case 3: // unix
67+
if rawHdr.Len != 216 {
68+
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid length")}
69+
}
70+
default:
5471
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid v2 address family")}
5572
}
5673

@@ -59,13 +76,7 @@ func parseV2(r *bufio.Reader) (*HeaderV2, error) {
5976
return nil, &InvalidHeaderErr{Read: buf[:16], error: errors.New("invalid v2 transport protocol")}
6077
}
6178

62-
if 16+int(rawHdr.Len) > len(buf) {
63-
newBuf := make([]byte, 16+int(rawHdr.Len))
64-
copy(newBuf, buf[:16])
65-
buf = newBuf
66-
} else {
67-
buf = buf[:16+int(rawHdr.Len)]
68-
}
79+
buf = buf[:16+int(rawHdr.Len)]
6980

7081
n, err = io.ReadFull(r, buf[16:])
7182
if err != nil {

headerv2_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ func TestHeaderV2(t *testing.T) {
3333
buf.Write(s.value)
3434
}
3535
hdr, err := Parse(bufio.NewReader(&buf))
36-
assert.NoError(t, err)
36+
if !assert.NoError(t, err) {
37+
return
38+
}
3739
assert.IsType(t, &HeaderV2{}, hdr, "Header Type")
3840
p := hdr.(*HeaderV2)
3941
assert.Equal(t, h.Command, p.Command, "Command")

parse_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package proxyprotocol
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestParse_Malformed(t *testing.T) {
12+
data := []byte{
13+
// PROXY protocol v2 magic header
14+
0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A,
15+
// v2 version, PROXY cmd
16+
0x21,
17+
// TCP, IPv4 (also works with 0x13,0x21,0x22,0x31,0x32)
18+
0x12,
19+
// Length
20+
0x00, 0x00,
21+
// src/dest address data _should_ be here but is omitted.
22+
}
23+
24+
_, err := Parse(
25+
bufio.NewReader(
26+
bytes.NewReader(data)))
27+
assert.Error(t, err)
28+
}

0 commit comments

Comments
 (0)