Skip to content

Commit d6dadbf

Browse files
Merge branch 'main' into fix/oss-208
2 parents 8f19f9a + 5fca163 commit d6dadbf

File tree

2 files changed

+183
-31
lines changed

2 files changed

+183
-31
lines changed

pkg/detectors/jiratoken/v2/jiratoken_v2.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ var (
3030

3131
// https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/
3232
// Tokens created after Jan 18 2023 use a variable length
33-
tokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"atlassian", "confluence", "jira"}) + `\b(ATATT[A-Za-z0-9+/=_-]+=[A-Za-z0-9]{8})\b`)
34-
domainPat = regexp.MustCompile(detectors.PrefixRegex([]string{"atlassian", "confluence", "jira"}) + `\b((?:[a-zA-Z0-9-]{1,24}\.)+[a-zA-Z0-9-]{2,24}\.[a-zA-Z0-9-]{2,16})\b`)
35-
emailPat = regexp.MustCompile(detectors.PrefixRegex([]string{"atlassian", "confluence", "jira"}) + common.EmailPattern)
33+
tokenPat = regexp.MustCompile(`\b(ATATT[A-Za-z0-9+/=_-]+=[A-Za-z0-9]{8})\b`)
34+
domainPat = regexp.MustCompile(`\b((?:[a-zA-Z0-9-]{1,24}\.)+[a-zA-Z0-9-]{2,24}\.[a-zA-Z0-9-]{2,16})\b`)
35+
emailPat = regexp.MustCompile(common.EmailPattern)
3636
)
3737

3838
func (s Scanner) getClient() *http.Client {

pkg/detectors/jiratoken/v2/jiratoken_v2_test.go

Lines changed: 180 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package jiratoken
22

33
import (
44
"context"
5-
"fmt"
6-
"strings"
75
"testing"
86

97
"github.com/google/go-cmp/cmp"
@@ -12,51 +10,205 @@ import (
1210
"github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick"
1311
)
1412

15-
var (
16-
validTokenPattern = "ATATT9nsCADa7812Z7VoIsYJ0K4rFWLBfk=1rhOsLAW"
17-
invalidTokenPattern = "9nsCA?a7812Z7VoI%YJ0K4rFWLBfk91rhOsLAW"
18-
validDomainPattern = "hereisavalidsubdomain.heresalongdomain.com"
19-
validDomainPattern2 = "jira.hereisavalidsubdomain.heresalongdomain.com"
20-
invalidDomainPattern = "?y4r3fs1ewqec12v1e3tl.5Hcsrcehic89saXd.ro@"
21-
validEmailPattern = "[email protected]"
22-
invalidEmailPattern = "xfKF_BZq7/grum.com"
23-
keyword = "jira"
24-
)
25-
2613
func TestJiraToken_Pattern(t *testing.T) {
2714
d := Scanner{}
2815
ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d})
2916
tests := []struct {
30-
name string
31-
input string
32-
want []string
17+
name string
18+
input string
19+
want []string
20+
noKeywords bool
3321
}{
3422
{
35-
name: "valid pattern - with keyword jira",
36-
input: fmt.Sprintf("%s %s \n%s %s\n%s %s", keyword, validTokenPattern, keyword, validDomainPattern, keyword, validEmailPattern),
37-
want: []string{strings.ToLower(validEmailPattern) + ":" + validTokenPattern + ":" + validDomainPattern},
23+
name: "valid pattern",
24+
input: `
25+
{
26+
"expand": "schema,names",
27+
"startAt": 0,
28+
"maxResults": 50,
29+
"total": 1,
30+
"issues": [
31+
{
32+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
33+
"id": "fake454",
34+
"self": "https://example.atlassian.net/rest/api/2/issue/fake454",
35+
"key": "ESI-5555",
36+
"fields": {
37+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
38+
"issuetype": {
39+
"self": "https://example.atlassian.net/rest/api/2/issuetype/09090",
40+
"id": "09090",
41+
"description": "This is an example ticket. Here's the token to test JIRA APIs: ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC",
42+
"name": "Example Pattern test",
43+
"subtask": false,
44+
"avatarId": 1298,
45+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
46+
"hierarchyLevel": 0,
47+
"emailAddress": "[email protected]",
48+
},
49+
}
50+
]}`,
51+
want: []string{"[email protected]" + ":" + "ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC" + ":" + "example.atlassian.net"},
52+
},
53+
{
54+
name: "valid pattern - without domain",
55+
input: `
56+
{
57+
"expand": "schema,names",
58+
"startAt": 0,
59+
"maxResults": 50,
60+
"total": 1,
61+
"issues": [
62+
{
63+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
64+
"id": "fake454",
65+
"key": "ESI-5555",
66+
"fields": {
67+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
68+
"issuetype": {
69+
"id": "09090",
70+
"description": "This is an example ticket. Here's the token to test JIRA APIs: ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC",
71+
"name": "Example Pattern test 2",
72+
"subtask": false,
73+
"avatarId": 1298,
74+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
75+
"hierarchyLevel": 0,
76+
"emailAddress": "[email protected]",
77+
},
78+
}
79+
]}`,
80+
want: []string{"[email protected]" + ":" + "ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC" + ":" + "api.atlassian.com"},
3881
},
3982
{
40-
name: "valid pattern - with multiple subdomains",
41-
input: fmt.Sprintf("%s %s \n%s %s\n%s %s", keyword, validTokenPattern, keyword, validDomainPattern2, keyword, validEmailPattern),
42-
want: []string{strings.ToLower(validEmailPattern) + ":" + validTokenPattern + ":" + validDomainPattern2},
83+
name: "valid pattern - without token",
84+
input: `
85+
{
86+
"expand": "schema,names",
87+
"startAt": 0,
88+
"maxResults": 50,
89+
"total": 1,
90+
"issues": [
91+
{
92+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
93+
"id": "fake454",
94+
"key": "ESI-5555",
95+
"fields": {
96+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
97+
"issuetype": {
98+
"id": "09090",
99+
"self": "https://example.atlassian.net/rest/api/2/issuetype/09090",
100+
"description": "This is an example ticket",
101+
"name": "Example Pattern test 2",
102+
"subtask": false,
103+
"avatarId": 1298,
104+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
105+
"hierarchyLevel": 0,
106+
"emailAddress": "[email protected]",
107+
},
108+
}
109+
]}`,
110+
want: []string{},
43111
},
44112
{
45-
name: "valid pattern - key out of prefix range",
46-
input: fmt.Sprintf("%s keyword is not close to the real key in the data\n = '%s' domain = '%s' email = '%s'", keyword, validTokenPattern, validDomainPattern, validEmailPattern),
47-
want: []string{},
113+
name: "valid pattern - without email",
114+
input: `
115+
{
116+
"expand": "schema,names",
117+
"startAt": 0,
118+
"maxResults": 50,
119+
"total": 1,
120+
"issues": [
121+
{
122+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
123+
"id": "fake454",
124+
"key": "ESI-5555",
125+
"fields": {
126+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
127+
"issuetype": {
128+
"id": "09090",
129+
"self": "https://example.atlassian.net/rest/api/2/issuetype/09090",
130+
"description": "This is an example ticket. Here's the token to test JIRA APIs: ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC",
131+
"name": "Example Pattern test 2",
132+
"subtask": false,
133+
"avatarId": 1298,
134+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
135+
"hierarchyLevel": 0,
136+
"emailAddress": "",
137+
},
138+
}
139+
]}`,
140+
want: []string{},
48141
},
49142
{
50-
name: "invalid pattern",
51-
input: fmt.Sprintf("%s key = '%s' domain = '%s' email = '%s'", keyword, invalidTokenPattern, invalidDomainPattern, invalidEmailPattern),
52-
want: []string{},
143+
name: "valid pattern - without keywords",
144+
input: `
145+
{
146+
"expand": "schema,names",
147+
"startAt": 0,
148+
"maxResults": 50,
149+
"total": 1,
150+
"issues": [
151+
{
152+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
153+
"id": "fake454",
154+
"key": "ESI-5555",
155+
"fields": {
156+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
157+
"issuetype": {
158+
"id": "09090",
159+
"description": "ATATThktLkSzzcXi1xt19IlU6gAchV1TS83w11YOqAXqFUeA2=Yx3ssoNC",
160+
"name": "Example Pattern test 2",
161+
"subtask": false,
162+
"avatarId": 1298,
163+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
164+
"hierarchyLevel": 0,
165+
"emailAddress": "[email protected]",
166+
},
167+
}
168+
]}`,
169+
want: []string{},
170+
noKeywords: true,
171+
},
172+
{
173+
name: "invalid pattern",
174+
input: `
175+
{
176+
"expand": "schema,names",
177+
"startAt": 0,
178+
"maxResults": 50,
179+
"total": 1,
180+
"issues": [
181+
{
182+
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
183+
"id": "fake454",
184+
"key": "ESI-5555",
185+
"fields": {
186+
"statuscategorychangedate": "2016-06-01T01:25:35.807-0700",
187+
"issuetype": {
188+
"id": "09090",
189+
"description": "This is an example ticket. Here's the token to test JIRA APIs: ATATTA9nsCA?a7812Z7VoI%YJ0K4rFWLBfk91rhOsLAW=Yx3ssoNC",
190+
"name": "Example Pattern test 2",
191+
"subtask": false,
192+
"avatarId": 1298,
193+
"entityId": "93a51c1d-fake-4673-a71d-0889fake1238",
194+
"hierarchyLevel": 0,
195+
"emailAddress": "?y4r3fs1ewqec12v1e3tl.5Hcsrcehic89saXd.ro@",
196+
},
197+
}
198+
]}`,
199+
want: []string{},
53200
},
54201
}
55202

56203
for _, test := range tests {
57204
t.Run(test.name, func(t *testing.T) {
58205
matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input))
59206
if len(matchedDetectors) == 0 {
207+
// if intentionally no keywords are passed
208+
if test.noKeywords {
209+
return
210+
}
211+
60212
t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input)
61213
return
62214
}

0 commit comments

Comments
 (0)