Skip to content

Commit 013aaf0

Browse files
Ignore known common prefix matches for Github V1 detector
1 parent eb908bd commit 013aaf0

File tree

2 files changed

+74
-30
lines changed

2 files changed

+74
-30
lines changed

pkg/detectors/github/v1/github_old.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ func (Scanner) CloudEndpoint() string { return "https://api.github.com" }
2828
var (
2929
// Oauth token
3030
// https://developer.github.com/v3/#oauth2-token-sent-in-a-header
31-
// the middle regex `\b[a-zA-Z0-9.\/?=&]{0,40}` is to match the prefix of token match to avoid processing common known patterns
32-
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"github", "gh", "pat", "token"}) + `\b[a-zA-Z0-9.\/?=&]{0,40}` + `\b([a-f0-9]{40})\b`)
31+
// the middle regex `(?:[a-zA-Z0-9.\/?=&:-]{0,40})` is to match the prefix of token match to avoid processing common known patterns
32+
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"github", "gh", "pat", "token"}) + `\b(?:[a-zA-Z0-9.\/?=&:-]{0,40})([a-f0-9]{40})\b`)
3333

3434
// TODO: Oauth2 client_id and client_secret
3535
// https://developer.github.com/v3/#oauth2-keysecret
@@ -73,7 +73,15 @@ var ghFalsePositives = map[detectors.FalsePositive]struct{}{
7373
}
7474

7575
var ghKnownNonSensitivePrefixes = []string{
76-
"avatars.githubusercontent.com", // github avatar urls prefix
76+
"avatars.githubusercontent.com", // GitHub avatar URLs
77+
"actions/", // GitHub Actions paths
78+
"raw.githubusercontent.com/", // Raw file URLs from GitHub
79+
"api.github.com/repos/", // GitHub API repository endpoints
80+
"gist.github.com/", // GitHub Gist URLs
81+
"sha256:", // SHA256 hash prefix
82+
"github.com/", // General GitHub repo URLs
83+
"pipelines.actions.githubusercontent.com/", // GitHub Actions infrastructure
84+
"ghcr.io/", // GitHub Container Registry
7785
}
7886

7987
// FromData will find and optionally verify GitHub secrets in a given set of bytes.
@@ -93,11 +101,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
93101
continue
94102
}
95103

96-
// to avoid false positives
97-
if isKnownNonSensitiveCommonPrefix(matchPrefix) {
98-
continue
99-
}
100-
101104
if detectors.StringShannonEntropy(token) < 3.5 {
102105
continue
103106
}
@@ -116,6 +119,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
116119
client := common.SaneHttpClient()
117120

118121
isVerified, userResponse, headers, err := s.VerifyGithub(ctx, client, token)
122+
123+
if !isVerified {
124+
// to avoid false positives for unverified findings
125+
if isKnownNonSensitiveCommonPrefix(matchPrefix) {
126+
continue
127+
}
128+
}
129+
119130
s1.Verified = isVerified
120131
s1.SetVerificationError(err, token)
121132

pkg/detectors/github/v1/github_old_test.go

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,10 @@ import (
55
"testing"
66

77
"github.com/google/go-cmp/cmp"
8-
98
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
109
"github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick"
1110
)
1211

13-
var (
14-
validPattern = `[{
15-
"_id": "1a8d0cca-e1a9-4318-bc2f-f5658ab2dcb5",
16-
"name": "Github",
17-
"type": "Detector",
18-
"api": true,
19-
"authentication_type": "",
20-
"verification_url": "https://api.example.com/example",
21-
"test_secrets": {
22-
"github_secret": "abc123def4567890abcdef1234567890abcdef12"
23-
},
24-
"expected_response": "200",
25-
"method": "GET",
26-
"deprecated": false
27-
}]`
28-
secret = "abc123def4567890abcdef1234567890abcdef12"
29-
)
30-
3112
func TestGithub_Pattern(t *testing.T) {
3213
d := Scanner{}
3314
ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d})
@@ -38,9 +19,22 @@ func TestGithub_Pattern(t *testing.T) {
3819
want []string
3920
}{
4021
{
41-
name: "valid pattern",
42-
input: validPattern,
43-
want: []string{secret},
22+
name: "valid pattern",
23+
input: `[{
24+
"_id": "1a8d0cca-e1a9-4318-bc2f-f5658ab2dcb5",
25+
"name": "Github",
26+
"type": "Detector",
27+
"api": true,
28+
"authentication_type": "",
29+
"verification_url": "https://api.example.com/example",
30+
"test_secrets": {
31+
"github_secret": "abc123def4567890abcdef1234567890abcdef12"
32+
},
33+
"expected_response": "200",
34+
"method": "GET",
35+
"deprecated": false
36+
}]`,
37+
want: []string{"abc123def4567890abcdef1234567890abcdef12"},
4438
},
4539
}
4640

@@ -86,3 +80,42 @@ func TestGithub_Pattern(t *testing.T) {
8680
})
8781
}
8882
}
83+
84+
func Test_isKnownNonSensitiveCommonPrefix(t *testing.T) {
85+
type args struct {
86+
matchPrefix string
87+
}
88+
tests := []struct {
89+
name string
90+
args args
91+
isKnownPrefix bool
92+
}{
93+
{
94+
name: "repo url",
95+
args: args{matchPrefix: "github.com/repos/symfony/monolog-bridge/zipball/9d14621e59f22c2b6d030d92d37ffe5ae1e60452"},
96+
isKnownPrefix: true,
97+
},
98+
{
99+
name: "sha256 hash",
100+
args: args{matchPrefix: "Digest: sha256:f9a92af4d46ca171bffa5c00509414a19d9887c9ed4fe98d1f43757b52600e39"},
101+
isKnownPrefix: true,
102+
},
103+
{
104+
name: "real looking token",
105+
args: args{matchPrefix: "github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e"},
106+
isKnownPrefix: false,
107+
},
108+
{
109+
name: "github url",
110+
args: args{matchPrefix: "github.com/wrandelshofer/FastDoubleParser/blob/39e123b15b71f29a38a087d16a0bc620fc879aa6/bigint-LICENSE"},
111+
isKnownPrefix: true,
112+
},
113+
}
114+
for _, tt := range tests {
115+
t.Run(tt.name, func(t *testing.T) {
116+
if got := isKnownNonSensitiveCommonPrefix(tt.args.matchPrefix); got != tt.isKnownPrefix {
117+
t.Errorf("isKnownNonSensitiveCommonPrefix() = %v, want %v", got, tt.isKnownPrefix)
118+
}
119+
})
120+
}
121+
}

0 commit comments

Comments
 (0)