Skip to content

Commit

Permalink
jws/jwe: split token into fixed number of parts (#1308)
Browse files Browse the repository at this point in the history
this avoid to use eccessive memory when processing maliciously
crafted tokens with a large number of '.' characters

Signed-off-by: Nicola Murino <[email protected]>
  • Loading branch information
drakkan authored Feb 26, 2025
1 parent 0076496 commit d0bb461
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 7 deletions.
7 changes: 4 additions & 3 deletions jwe/jwe.go
Original file line number Diff line number Diff line change
Expand Up @@ -886,10 +886,11 @@ func parseJSON(buf []byte, storeProtectedHeaders bool) (*Message, error) {
}

func parseCompact(buf []byte, storeProtectedHeaders bool) (*Message, error) {
parts := bytes.Split(buf, []byte{'.'})
if len(parts) != 5 {
return nil, fmt.Errorf(`compact JWE format must have five parts (%d)`, len(parts))
// Five parts is four separators
if count := bytes.Count(buf, []byte{'.'}); count != 4 {
return nil, fmt.Errorf(`compact JWE format must have five parts (%d)`, count)
}
parts := bytes.SplitN(buf, []byte{'.'}, 5)

hdrbuf, err := base64.Decode(parts[0])
if err != nil {
Expand Down
10 changes: 6 additions & 4 deletions jws/jws.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,10 +625,11 @@ func parseJSON(data []byte) (result *Message, err error) {
//
// On error, returns a jws.ParseError.
func SplitCompact(src []byte) ([]byte, []byte, []byte, error) {
parts := bytes.Split(src, []byte("."))
if len(parts) < 3 {
// Three parts is two separators
if bytes.Count(src, []byte(".")) != 2 {
return nil, nil, nil, parseerr(`invalid number of segments`)
}
parts := bytes.SplitN(src, []byte("."), 3)
return parts[0], parts[1], parts[2], nil
}

Expand All @@ -637,10 +638,11 @@ func SplitCompact(src []byte) ([]byte, []byte, []byte, error) {
//
// On error, returns a jws.ParseError.
func SplitCompactString(src string) ([]byte, []byte, []byte, error) {
parts := strings.Split(src, ".")
if len(parts) < 3 {
// Three parts is two separators
if strings.Count(src, ".") != 2 {
return nil, nil, nil, parseerr(`invalid number of segments`)
}
parts := strings.SplitN(src, ".", 3)
return []byte(parts[0]), []byte(parts[1]), []byte(parts[2]), nil
}

Expand Down

0 comments on commit d0bb461

Please sign in to comment.