generic.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package rules
  2. import (
  3. "github.com/zricethezav/gitleaks/v8/cmd/generate/config/utils"
  4. "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets"
  5. "github.com/zricethezav/gitleaks/v8/config"
  6. "regexp"
  7. )
  8. func GenericCredential() *config.Rule {
  9. // define rule
  10. r := config.Rule{
  11. RuleID: "generic-api-key",
  12. Description: "Detected a Generic API Key, potentially exposing access to various services and sensitive operations.",
  13. Regex: utils.GenerateSemiGenericRegex([]string{
  14. "access",
  15. "auth",
  16. `(?-i:[Aa]pi|API)`,
  17. "credential",
  18. "creds",
  19. "key",
  20. "passwd",
  21. "password",
  22. "secret",
  23. "token",
  24. }, `[\w.=-]{10,150}`, true),
  25. Keywords: []string{
  26. "access",
  27. "api",
  28. "auth",
  29. "key",
  30. "credential",
  31. "creds",
  32. "passwd",
  33. "password",
  34. "secret",
  35. "token",
  36. },
  37. Entropy: 3.5,
  38. Allowlists: []config.Allowlist{
  39. {
  40. Description: "Allowlist for Generic API Keys",
  41. MatchCondition: config.AllowlistMatchOr,
  42. Regexes: []*regexp.Regexp{
  43. regexp.MustCompile(`(?i)(` +
  44. // Access
  45. `accessor` +
  46. // API
  47. `|api[_.-]?(version|id)` + // version/id -> not a secret
  48. `|rapid|capital` + // common words containing "api"
  49. // Auth
  50. `|author` +
  51. // Credentials
  52. `|(?-i:(?:c|jobC)redentials?Id|withCredentials)` + // Jenkins plugins
  53. // Key
  54. `|key[_.-]?(alias|board|code|ring|stone|storetype|word|up|down|left|right)` +
  55. `|issuerkeyhash` + // part of ssl cert
  56. `|(bucket|primary|foreign|natural|hot)[_.-]?key` +
  57. `|(?-i:[DdMm]onkey|[DM]ONKEY)|keying` + // common words containing "key"
  58. // Secret
  59. `|(secret)[_.-]?name` + // name of e.g. env variable
  60. // Token
  61. // General
  62. `|public[_.-]?(key|token)` + // public key -> not a secret
  63. `|(key|token)[_.-]?file` +
  64. `)`),
  65. },
  66. RegexTarget: "match",
  67. StopWords: DefaultStopWords,
  68. },
  69. },
  70. }
  71. // validate
  72. tps := []string{
  73. // Access
  74. `'access_token': 'eyJ0eXAioiJKV1slS3oASx=='`,
  75. // API
  76. `some_api_token_123 = "` + newPlausibleSecret(`[a-zA-Z0-9]{60}`) + `"`,
  77. // Auth
  78. // Credentials
  79. `"credentials" : "0afae57f3ccfd9d7f5767067bc48b30f719e271ba470488056e37ab35d4b6506"`,
  80. `creds = ` + newPlausibleSecret(`[a-zA-Z0-9]{30}`),
  81. // Key
  82. `private-key: ` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{100}`),
  83. // Password
  84. `passwd = ` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  85. // Secret
  86. `"client_secret" : "6da89121079f83b2eb6acccf8219ea982c3d79bccc3e9c6a85856480661f8fde",`,
  87. `mySecretString=` + newPlausibleSecret(`[a-zA-Z0-9]{30}`),
  88. `todo_secret_do_not_commit = ` + newPlausibleSecret(`[a-zA-Z0-9]{30}`),
  89. // Token
  90. utils.GenerateSampleSecret("generic", "CLOJARS_34bf0e88955ff5a1c328d6a7491acc4f48e865a7b8dd4d70a70749037443"), //gitleaks:allow
  91. utils.GenerateSampleSecret("generic", "Zf3D0LXCM3EIMbgJpUNnkRtOfOueHznB"),
  92. }
  93. fps := []string{
  94. // Access
  95. `"accessor":"rA1wk0Y45YCufyfq",`,
  96. // API
  97. `this.ultraPictureBox1.Name = "ultraPictureBox1";`,
  98. `rapidstring:marm64-uwp=fail`,
  99. `event-bus-message-api:rc0.15.0_20231217_1420-SNAPSHOT'`,
  100. `COMMUNICATION_API_VERSION=rc0.13.0_20230412_0712-SNAPSHOT`,
  101. `MantleAPI_version=9a038989604e8da62ecddbe2094b16ce1b778be1`,
  102. // Auth
  103. `author = "james.fake@ymail.com",`,
  104. // Credentials
  105. `withCredentials([usernamePassword(credentialsId: '29f63271-dc2f-4734-8221-5b31b5169bac', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {`,
  106. `credentialsId: 'ff083f76-7804-4ef1-80e4-fe975bb9141b'`,
  107. `jobCredentialsId: 'f4aeb6bc-2a25-458a-8111-9be9e502c0e7'`,
  108. ` "credentialId": "B9mTcFSck2LzJO2S3ols63",`,
  109. // Key
  110. `keyword: "Befaehigung_P2"`,
  111. `public_key = "9Cnzj4p4WGeKLs1Pt8QuKUpRKfFLfRYC9AIKjbJTWit"`,
  112. `monkeys-audio:mx64-uwp=fail`,
  113. `primaryKey=` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  114. `foreignKey=` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  115. `key_down_event=` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  116. `issuerKeyHash=` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  117. `<entry key="jetbrains.mps.v8_elimination" value="executed" />`,
  118. `minisat-master-keying:x64-uwp=fail`,
  119. `IceSSL.KeyFile=s_rsa1024_priv.pem`,
  120. `"bucket_key": "SalesResults-1.2"`,
  121. //`<TAR key="REF_ID_923.properties" value="/opts/config/alias/"/>`,
  122. `<key tag="SecurityIdentifier" name="SecurityIdentifier" type="STRING" />`,
  123. //`packageKey":` + newPlausibleSecret(`[a-zA-Z0-9\-_.=]{30}`),
  124. // Password
  125. `password combination.
  126. R5: Regulatory--21`,
  127. `PuttyPassword=0`,
  128. // Secret
  129. `LLM_SECRET_NAME = "NEXUS-GPT4-API-KEY"`,
  130. // Token
  131. `publicToken = "9Cnzj4p4WGeKLs1Pt8QuKUpRKfFLfRYC9AIKjbJTWit"`,
  132. `<SourceFile SourceLocation="F:\Extracts\" TokenFile="RTL_INST_CODE.cer">`,
  133. // General
  134. `clientId = "73082700-1f09-405b-80d0-3131bfd6272d"`,
  135. }
  136. return utils.Validate(r, tps, fps)
  137. }
  138. func newPlausibleSecret(regex string) string {
  139. allowList := config.Allowlist{StopWords: DefaultStopWords}
  140. // attempt to generate a random secret,
  141. // retrying until it contains at least one digit and no stop words
  142. // TODO: currently the DefaultStopWords list contains many short words,
  143. // so there is a significant chance of generating a secret that contains a stop word
  144. for {
  145. secret := secrets.NewSecret(regex)
  146. if !regexp.MustCompile(`[1-9]`).MatchString(secret) {
  147. continue
  148. }
  149. if allowList.ContainsStopWord(secret) {
  150. continue
  151. }
  152. return secret
  153. }
  154. }