Skip to content
This repository was archived by the owner on May 21, 2022. It is now read-only.

Commit 63de7be

Browse files
committed
Fix sec vuln with list of claims
Signed-off-by: Alistair Hey <[email protected]>
1 parent dc14462 commit 63de7be

File tree

4 files changed

+89
-8
lines changed

4 files changed

+89
-8
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
22
bin
3+
.idea/
34

45

claims.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Claims interface {
1616
// https://tools.ietf.org/html/rfc7519#section-4.1
1717
// See examples for how to use this with your own claim types
1818
type StandardClaims struct {
19-
Audience string `json:"aud,omitempty"`
19+
Audience []string `json:"aud,omitempty"`
2020
ExpiresAt int64 `json:"exp,omitempty"`
2121
Id string `json:"jti,omitempty"`
2222
IssuedAt int64 `json:"iat,omitempty"`
@@ -90,15 +90,17 @@ func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
9090

9191
// ----- helpers
9292

93-
func verifyAud(aud string, cmp string, required bool) bool {
94-
if aud == "" {
93+
func verifyAud(aud []string, cmp string, required bool) bool {
94+
if len(aud) == 0 {
9595
return !required
9696
}
97-
if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
98-
return true
99-
} else {
100-
return false
97+
98+
for _, a := range aud {
99+
if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
100+
return true
101+
}
101102
}
103+
return false
102104
}
103105

104106
func verifyExp(exp int64, now int64, required bool) bool {

map_claims.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ type MapClaims map[string]interface{}
1313
// Compares the aud claim against cmp.
1414
// If required is false, this method will return true if the value matches or is unset
1515
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
16-
aud, _ := m["aud"].(string)
16+
aud, _ := m["aud"].([]string)
17+
18+
// special case where aud is a single string not list of strings
19+
if aud == nil {
20+
strAud, _ := m["aud"].(string)
21+
aud = append(aud, strAud)
22+
}
1723
return verifyAud(aud, cmp, req)
1824
}
1925

map_claims_test.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package jwt
2+
3+
import "testing"
4+
5+
func Test_mapClaims_list_aud(t *testing.T){
6+
mapClaims := MapClaims{
7+
"aud": []string{"foo"},
8+
}
9+
want := true
10+
got := mapClaims.VerifyAudience("foo", true)
11+
12+
if want != got {
13+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
14+
}
15+
}
16+
func Test_mapClaims_string_aud(t *testing.T){
17+
mapClaims := MapClaims{
18+
"aud": "foo",
19+
}
20+
want := true
21+
got := mapClaims.VerifyAudience("foo", true)
22+
23+
if want != got {
24+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
25+
}
26+
}
27+
28+
func Test_mapClaims_list_aud_no_match(t *testing.T){
29+
mapClaims := MapClaims{
30+
"aud": []string{"bar"},
31+
}
32+
want := false
33+
got := mapClaims.VerifyAudience("foo", true)
34+
35+
if want != got {
36+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
37+
}
38+
}
39+
func Test_mapClaims_string_aud_fail(t *testing.T){
40+
mapClaims := MapClaims{
41+
"aud": "bar",
42+
}
43+
want := false
44+
got := mapClaims.VerifyAudience("foo", true)
45+
46+
if want != got {
47+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
48+
}
49+
}
50+
51+
func Test_mapClaims_string_aud_no_claim(t *testing.T){
52+
mapClaims := MapClaims{
53+
}
54+
want := false
55+
got := mapClaims.VerifyAudience("foo", true)
56+
57+
if want != got {
58+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
59+
}
60+
}
61+
62+
func Test_mapClaims_string_aud_no_claim_not_required(t *testing.T){
63+
mapClaims := MapClaims{
64+
//"aud": "",
65+
}
66+
want := false
67+
got := mapClaims.VerifyAudience("foo", false)
68+
69+
if want != got {
70+
t.Fatalf("Failed to verify claims, wanted: %v got %v", want, got)
71+
}
72+
}

0 commit comments

Comments
 (0)