Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
G
golang-github-golang-jwt-jwt-v5
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Debian Go Packaging Team
packages
golang-github-golang-jwt-jwt-v5
Commits
2f0e9add
Commit
2f0e9add
authored
3 months ago
by
Michael Fridman
Committed by
Christian Banse
3 months ago
Browse files
Options
Downloads
Patches
Plain Diff
Backporting
0951d184
to v4
parent
7b1c1c00
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
jwt_test.go
+89
-0
89 additions, 0 deletions
jwt_test.go
parser.go
+33
-3
33 additions, 3 deletions
parser.go
with
122 additions
and
3 deletions
jwt_test.go
0 → 100644
+
89
−
0
View file @
2f0e9add
package
jwt
import
(
"testing"
)
func
TestSplitToken
(
t
*
testing
.
T
)
{
t
.
Parallel
()
tests
:=
[]
struct
{
name
string
input
string
expected
[]
string
isValid
bool
}{
{
name
:
"valid token with three parts"
,
input
:
"header.claims.signature"
,
expected
:
[]
string
{
"header"
,
"claims"
,
"signature"
},
isValid
:
true
,
},
{
name
:
"invalid token with two parts only"
,
input
:
"header.claims"
,
expected
:
nil
,
isValid
:
false
,
},
{
name
:
"invalid token with one part only"
,
input
:
"header"
,
expected
:
nil
,
isValid
:
false
,
},
{
name
:
"invalid token with extra delimiter"
,
input
:
"header.claims.signature.extra"
,
expected
:
nil
,
isValid
:
false
,
},
{
name
:
"invalid empty token"
,
input
:
""
,
expected
:
nil
,
isValid
:
false
,
},
{
name
:
"valid token with empty parts"
,
input
:
"..signature"
,
expected
:
[]
string
{
""
,
""
,
"signature"
},
isValid
:
true
,
},
{
// We are just splitting the token into parts, so we don't care about the actual values.
// It is up to the caller to validate the parts.
name
:
"valid token with all parts empty"
,
input
:
".."
,
expected
:
[]
string
{
""
,
""
,
""
},
isValid
:
true
,
},
{
name
:
"invalid token with just delimiters and extra part"
,
input
:
"..."
,
expected
:
nil
,
isValid
:
false
,
},
{
name
:
"invalid token with many delimiters"
,
input
:
"header.claims.signature.................."
,
expected
:
nil
,
isValid
:
false
,
},
}
for
_
,
tt
:=
range
tests
{
t
.
Run
(
tt
.
name
,
func
(
t
*
testing
.
T
)
{
parts
,
ok
:=
splitToken
(
tt
.
input
)
if
ok
!=
tt
.
isValid
{
t
.
Errorf
(
"expected %t, got %t"
,
tt
.
isValid
,
ok
)
}
if
ok
{
for
i
,
part
:=
range
tt
.
expected
{
if
parts
[
i
]
!=
part
{
t
.
Errorf
(
"expected %s, got %s"
,
part
,
parts
[
i
])
}
}
}
})
}
}
This diff is collapsed.
Click to expand it.
parser.go
+
33
−
3
View file @
2f0e9add
...
...
@@ -7,6 +7,8 @@ import (
"strings"
)
const
tokenDelimiter
=
"."
type
Parser
struct
{
// If populated, only these methods will be considered valid.
//
...
...
@@ -122,9 +124,10 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
// It's only ever useful in cases where you know the signature is valid (because it has
// been checked previously in the stack) and you want to extract values from it.
func
(
p
*
Parser
)
ParseUnverified
(
tokenString
string
,
claims
Claims
)
(
token
*
Token
,
parts
[]
string
,
err
error
)
{
parts
=
strings
.
Split
(
tokenString
,
"."
)
if
len
(
parts
)
!=
3
{
return
nil
,
parts
,
NewValidationError
(
"token contains an invalid number of segments"
,
ValidationErrorMalformed
)
var
ok
bool
parts
,
ok
=
splitToken
(
tokenString
)
if
!
ok
{
return
nil
,
nil
,
NewValidationError
(
"token contains an invalid number of segments"
,
ValidationErrorMalformed
)
}
token
=
&
Token
{
Raw
:
tokenString
}
...
...
@@ -174,3 +177,30 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke
return
token
,
parts
,
nil
}
// splitToken splits a token string into three parts: header, claims, and signature. It will only
// return true if the token contains exactly two delimiters and three parts. In all other cases, it
// will return nil parts and false.
func
splitToken
(
token
string
)
([]
string
,
bool
)
{
parts
:=
make
([]
string
,
3
)
header
,
remain
,
ok
:=
strings
.
Cut
(
token
,
tokenDelimiter
)
if
!
ok
{
return
nil
,
false
}
parts
[
0
]
=
header
claims
,
remain
,
ok
:=
strings
.
Cut
(
remain
,
tokenDelimiter
)
if
!
ok
{
return
nil
,
false
}
parts
[
1
]
=
claims
// One more cut to ensure the signature is the last part of the token and there are no more
// delimiters. This avoids an issue where malicious input could contain additional delimiters
// causing unecessary overhead parsing tokens.
signature
,
_
,
unexpected
:=
strings
.
Cut
(
remain
,
tokenDelimiter
)
if
unexpected
{
return
nil
,
false
}
parts
[
2
]
=
signature
return
parts
,
true
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment