sentry.go 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package rules
  2. import (
  3. "encoding/base64"
  4. "github.com/zricethezav/gitleaks/v8/cmd/generate/config/utils"
  5. "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets"
  6. "github.com/zricethezav/gitleaks/v8/config"
  7. "github.com/zricethezav/gitleaks/v8/regexp"
  8. )
  9. func SentryAccessToken() *config.Rule {
  10. // define rule
  11. r := config.Rule{
  12. RuleID: "sentry-access-token",
  13. Description: "Found a Sentry.io Access Token (old format), risking unauthorized access to error tracking services and sensitive application data.",
  14. Regex: utils.GenerateSemiGenericRegex([]string{"sentry"}, utils.Hex("64"), true),
  15. Entropy: 3,
  16. Keywords: []string{
  17. "sentry",
  18. },
  19. }
  20. // validate
  21. tps := utils.GenerateSampleSecrets("sentry", secrets.NewSecret(utils.Hex("64")))
  22. return utils.Validate(r, tps, nil)
  23. }
  24. func SentryOrgToken() *config.Rule {
  25. // format: sntrys_[base64_json]_[base64_secret]
  26. // the json contains the following fields : {"iat": ,"url": ,"region_url": ,"org": }
  27. // Specification: https://github.com/getsentry/rfcs/blob/main/text/0091-ci-upload-tokens.md
  28. // Some test cases from official parser:
  29. // https://github.com/getsentry/sentry-cli/blob/693d62167041846e2da823b7f3b0f21b673b5b1f/src/utils/auth_token/test.rs
  30. // To detect the token, this rule checks for the following base64-encoded json fragments :
  31. // eyJpYXQiO = `{"iat":`,
  32. // LCJyZWdpb25fdXJs = `,"region_url`
  33. // InJlZ2lvbl91cmwi = `"region_url"`
  34. // cmVnaW9uX3VybCI6 = `region_url":`
  35. // define rule
  36. r := config.Rule{
  37. RuleID: "sentry-org-token",
  38. Description: "Found a Sentry.io Organization Token, risking unauthorized access to error tracking services and sensitive application data.",
  39. 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}(?:[^a-zA-Z0-9+/]|\z)`),
  40. Entropy: 4.5,
  41. Keywords: []string{"sntrys_eyJpYXQiO"},
  42. }
  43. // validate
  44. tps := utils.GenerateSampleSecrets("sentry",
  45. `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`, // gitleaks:allow
  46. )
  47. tps = append(tps, utils.GenerateSampleSecrets("sentry",
  48. `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`, // gitleaks:allow
  49. )...)
  50. tps = append(tps,
  51. ` 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`, // gitleaks:allow
  52. )
  53. encodedJson := base64.StdEncoding.EncodeToString([]byte(secrets.NewSecret(
  54. `\{"iat":[\d\.]{3,6},"url":"https://\w{10,20}","region_url":"https://\w{20,30}","org":"\w{5,10}"\}`)))
  55. generatedToken := `sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9+/]{43}`)
  56. tps = append(tps,
  57. generatedToken,
  58. "<token>"+generatedToken+"</token>",
  59. "https://example.com?token="+generatedToken+"&other=stuff",
  60. )
  61. fps := []string{
  62. secrets.NewSecret(`sntrys_[a-zA-Z0-9]{90}_[a-zA-Z0-9]{43}`), // does not contain encoded json
  63. `sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9]{42}`), // too short
  64. `sntrys_` + encodedJson + `_` + secrets.NewSecret(`[a-zA-Z0-9]{44}`), // too long
  65. }
  66. return utils.Validate(r, tps, fps)
  67. }
  68. func SentryUserToken() *config.Rule {
  69. // define rule
  70. r := config.Rule{
  71. RuleID: "sentry-user-token",
  72. Description: "Found a Sentry.io User Token, risking unauthorized access to error tracking services and sensitive application data.",
  73. Regex: utils.GenerateUniqueTokenRegex(`sntryu_[a-f0-9]{64}`, false),
  74. Entropy: 3.5,
  75. Keywords: []string{"sntryu_"},
  76. }
  77. // validate
  78. tps := utils.GenerateSampleSecrets("sentry", secrets.NewSecret(`sntryu_[a-f0-9]{64}`))
  79. fps := []string{
  80. secrets.NewSecret(`sntryu_[a-f0-9]{63}`), // too short
  81. secrets.NewSecret(`sntryu_[a-f0-9]{65}`), // too long
  82. secrets.NewSecret(`sntryu_[a]{64}`), // low entropy
  83. }
  84. return utils.Validate(r, tps, fps)
  85. }