Просмотр исходного кода

feat: detect sentry.io tokens in the new format (#1640)

sntrys_..., sntryu_...
Ben-grmbl 1 год назад
Родитель
Сommit
7f77987d91
3 измененных файлов с 90 добавлено и 3 удалено
  1. 2 0
      cmd/generate/config/main.go
  2. 72 2
      cmd/generate/config/rules/sentry.go
  3. 16 1
      config/gitleaks.toml

+ 2 - 0
cmd/generate/config/main.go

@@ -182,6 +182,8 @@ func main() {
 		rules.SendGridAPIToken(),
 		rules.SendInBlueAPIToken(),
 		rules.SentryAccessToken(),
+		rules.SentryOrgToken(),
+		rules.SentryUserToken(),
 		rules.ShippoAPIToken(),
 		rules.ShopifyAccessToken(),
 		rules.ShopifyCustomAccessToken(),

+ 72 - 2
cmd/generate/config/rules/sentry.go

@@ -1,18 +1,20 @@
 package rules
 
 import (
+	"encoding/base64"
 	"github.com/zricethezav/gitleaks/v8/cmd/generate/config/utils"
 	"github.com/zricethezav/gitleaks/v8/cmd/generate/secrets"
 	"github.com/zricethezav/gitleaks/v8/config"
+	"regexp"
 )
 
 func SentryAccessToken() *config.Rule {
 	// define rule
 	r := config.Rule{
 		RuleID:      "sentry-access-token",
-		Description: "Found a Sentry Access Token, risking unauthorized access to error tracking services and sensitive application data.",
+		Description: "Found a Sentry.io Access Token (old format), risking unauthorized access to error tracking services and sensitive application data.",
 		Regex:       utils.GenerateSemiGenericRegex([]string{"sentry"}, utils.Hex("64"), true),
-
+		Entropy:     3,
 		Keywords: []string{
 			"sentry",
 		},
@@ -22,3 +24,71 @@ func SentryAccessToken() *config.Rule {
 	tps := utils.GenerateSampleSecrets("sentry", secrets.NewSecret(utils.Hex("64")))
 	return utils.Validate(r, tps, nil)
 }
+
+func SentryOrgToken() *config.Rule {
+
+	// format: sntrys_[base64_json]_[base64_secret]
+	// the json contains the following fields : {"iat": ,"url": ,"region_url": ,"org": }
+	// Specification: https://github.com/getsentry/rfcs/blob/main/text/0091-ci-upload-tokens.md
+	// Some test cases from official parser:
+	// https://github.com/getsentry/sentry-cli/blob/693d62167041846e2da823b7f3b0f21b673b5b1f/src/utils/auth_token/test.rs
+	// To detect the token, this rule checks for the following base64-encoded json fragments :
+	// eyJpYXQiO = `{"iat":`,
+	// LCJyZWdpb25fdXJs = `,"region_url`
+	// InJlZ2lvbl91cmwi = `"region_url"`
+	// cmVnaW9uX3VybCI6 = `region_url":`
+
+	// define rule
+	r := config.Rule{
+		RuleID:      "sentry-org-token",
+		Description: "Found a Sentry.io Organization Token, risking unauthorized access to error tracking services and sensitive application data.",
+		Regex:       regexp.MustCompile(`\bsntrys_eyJpYXQiO[a-zA-Z0-9+/]{10,200}(?:LCJyZWdpb25fdXJs|InJlZ2lvbl91cmwi|cmVnaW9uX3VybCI6)[a-zA-Z0-9+/]{10,200}={0,2}_[a-zA-Z0-9+/]{43}\b`),
+		Entropy:     4.5,
+		Keywords:    []string{"sntrys_eyJpYXQiO"},
+	}
+
+	// validate
+	tps := utils.GenerateSampleSecrets("sentry",
+		`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`, // gitleaks:allow
+	)
+	tps = append(tps,
+		` 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`, // gitleaks:allow
+	)
+
+	encodedJson := base64.StdEncoding.EncodeToString([]byte(secrets.NewSecret(
+		`\{"iat":[\d\.]{3,6},"url":"https://\w{10,20}","region_url":"https://\w{20,30}","org":"\w{5,10}"\}`)))
+	generatedToken := `sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9+/]{43}`)
+	tps = append(tps,
+		generatedToken,
+		"<token>"+generatedToken+"</token>",
+		"https://example.com?token="+generatedToken+"&other=stuff",
+	)
+
+	fps := []string{
+		secrets.NewSecret(`sntrys_[a-zA-Z0-9]{90}_[a-zA-Z0-9]{43}`),          // does not contain encoded json
+		`sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9]{42}`), // too short
+		`sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9]{44}`), // too long
+	}
+
+	return utils.Validate(r, tps, fps)
+}
+
+func SentryUserToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "sentry-user-token",
+		Description: "Found a Sentry.io User Token, risking unauthorized access to error tracking services and sensitive application data.",
+		Regex:       utils.GenerateUniqueTokenRegex(`sntryu_[a-f0-9]{64}`, false),
+		Entropy:     3.5,
+		Keywords:    []string{"sntryu_"},
+	}
+
+	// validate
+	tps := utils.GenerateSampleSecrets("sentry", secrets.NewSecret(`sntryu_[a-f0-9]{64}`))
+	fps := []string{
+		secrets.NewSecret(`sntryu_[a-f0-9]{63}`), // too short
+		secrets.NewSecret(`sntryu_[a-f0-9]{65}`), // too long
+		secrets.NewSecret(`sntryu_[a]{64}`),      // low entropy
+	}
+	return utils.Validate(r, tps, fps)
+}

+ 16 - 1
config/gitleaks.toml

@@ -2713,10 +2713,25 @@ keywords = ["xkeysib-"]
 
 [[rules]]
 id = "sentry-access-token"
-description = "Found a Sentry Access Token, risking unauthorized access to error tracking services and sensitive application data."
+description = "Found a Sentry.io Access Token (old format), risking unauthorized access to error tracking services and sensitive application data."
 regex = '''(?i)[\w.-]{0,50}?(?:sentry)(?:[ \t\w.-]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)'''
+entropy = 3
 keywords = ["sentry"]
 
+[[rules]]
+id = "sentry-org-token"
+description = "Found a Sentry.io Organization Token, risking unauthorized access to error tracking services and sensitive application data."
+regex = '''\bsntrys_eyJpYXQiO[a-zA-Z0-9+/]{10,200}(?:LCJyZWdpb25fdXJs|InJlZ2lvbl91cmwi|cmVnaW9uX3VybCI6)[a-zA-Z0-9+/]{10,200}={0,2}_[a-zA-Z0-9+/]{43}\b'''
+entropy = 4.5
+keywords = ["sntrys_eyjpyxqio"]
+
+[[rules]]
+id = "sentry-user-token"
+description = "Found a Sentry.io User Token, risking unauthorized access to error tracking services and sensitive application data."
+regex = '''\b(sntryu_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)'''
+entropy = 3.5
+keywords = ["sntryu_"]
+
 [[rules]]
 id = "shippo-api-token"
 description = "Discovered a Shippo API token, potentially compromising shipping services and customer order data."