Skip to content

Commit af9d240

Browse files
froodianabustany
andauthored
Fix #27: Panic on large notification payloads (revised) (#34)
* Fix #27: Panic on large notification payloads This commit fixes a case where, with large notification payloads, pad would call make with a negative length, triggering a panic. * Address pull request comments Co-authored-by: Adrien Bustany <[email protected]>
1 parent 358c5ab commit af9d240

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

webpush.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020

2121
const MaxRecordSize uint32 = 4096
2222

23+
var ErrMaxPadExceeded = errors.New("payload has exceeded the maximum length")
24+
2325
// saltFunc generates a salt of 16 bytes
2426
var saltFunc = func() ([]byte, error) {
2527
salt := make([]byte, 16)
@@ -166,7 +168,9 @@ func SendNotification(message []byte, s *Subscription, options *Options) (*http.
166168
// Pad content to max record size - 16 - header
167169
// Padding ending delimeter
168170
dataBuf.Write([]byte("\x02"))
169-
pad(dataBuf, recordLength-recordBuf.Len())
171+
if err := pad(dataBuf, recordLength-recordBuf.Len()); err != nil {
172+
return nil, err
173+
}
170174

171175
// Compose the ciphertext
172176
ciphertext := gcm.Seal([]byte{}, nonce, dataBuf.Bytes(), nil)
@@ -244,10 +248,16 @@ func getHKDFKey(hkdf io.Reader, length int) ([]byte, error) {
244248
return key, nil
245249
}
246250

247-
func pad(payload *bytes.Buffer, maxPadLen int) {
251+
func pad(payload *bytes.Buffer, maxPadLen int) error {
248252
payloadLen := payload.Len()
253+
if payloadLen > maxPadLen {
254+
return ErrMaxPadExceeded
255+
}
256+
249257
padLen := maxPadLen - payloadLen
250258

251259
padding := make([]byte, padLen)
252260
payload.Write(padding)
261+
262+
return nil
253263
}

webpush_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package webpush
22

33
import (
44
"net/http"
5+
"strings"
56
"testing"
67
)
78

@@ -76,3 +77,17 @@ func TestSendNotificationToStandardEncodedSubscription(t *testing.T) {
7677
)
7778
}
7879
}
80+
81+
func TestSendTooLargeNotification(t *testing.T) {
82+
_, err := SendNotification([]byte(strings.Repeat("Test", int(MaxRecordSize))), getStandardEncodedTestSubscription(), &Options{
83+
HTTPClient: &testHTTPClient{},
84+
Subscriber: "<[email protected]>",
85+
Topic: "test_topic",
86+
TTL: 0,
87+
Urgency: "low",
88+
VAPIDPrivateKey: "testKey",
89+
})
90+
if err == nil {
91+
t.Fatalf("Error is nil, expected=%s", ErrMaxPadExceeded)
92+
}
93+
}

0 commit comments

Comments
 (0)