Преглед на файлове

Merge branch 'master' of github.com:gitleaks/gitleaks

Zach преди 8 месеца
родител
ревизия
aba4d752b9
променени са 9 файла, в които са добавени 155 реда и са изтрити 14 реда
  1. 1 0
      cmd/generate/config/main.go
  2. 10 7
      cmd/generate/config/rules/atlassian.go
  3. 19 0
      cmd/generate/config/rules/heroku.go
  4. 8 0
      cmd/scm/scm.go
  5. 8 1
      config/gitleaks.toml
  6. 28 0
      detect/utils.go
  7. 68 0
      detect/utils_test.go
  8. 9 6
      sources/file.go
  9. 4 0
      sources/git.go

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

@@ -125,6 +125,7 @@ func main() {
 		rules.HashiCorpTerraform(),
 		rules.HashicorpField(),
 		rules.Heroku(),
+		rules.HerokuV2(),
 		rules.HubSpot(),
 		rules.HuggingFaceAccessToken(),
 		rules.HuggingFaceOrganizationApiToken(),

+ 10 - 7
cmd/generate/config/rules/atlassian.go

@@ -13,9 +13,9 @@ func Atlassian() *config.Rule {
 		RuleID:      "atlassian-api-token",
 		Regex: utils.MergeRegexps(
 			utils.GenerateSemiGenericRegex(
-				[]string{"atlassian", "confluence", "jira"},
-				`[a-zA-Z0-9]{24}`,
-				false,
+				[]string{"(?-i:ATLASSIAN|[Aa]tlassian)", "(?-i:CONFLUENCE|[Cc]onfluence)", "(?-i:JIRA|[Jj]ira)"},
+				`[a-z0-9]{20}[a-f0-9]{4}`, // The last 4 characters are an MD5 hash.
+				true,
 			),
 			utils.GenerateUniqueTokenRegex(`ATATT3[A-Za-z0-9_\-=]{186}`, false),
 		),
@@ -24,10 +24,13 @@ func Atlassian() *config.Rule {
 	}
 
 	// validate
-	tps := utils.GenerateSampleSecrets("atlassian", secrets.NewSecret(utils.AlphaNumeric("24")))
-	tps = append(tps, utils.GenerateSampleSecrets("confluence", secrets.NewSecret(utils.AlphaNumeric("24")))...)
-	tps = append(tps, utils.GenerateSampleSecrets("jira", secrets.NewSecret(utils.AlphaNumeric("24")))...)
+	tps := utils.GenerateSampleSecrets("atlassian", secrets.NewSecret(utils.AlphaNumeric("20")+"[a-f0-9]{4}"))
+	tps = append(tps, utils.GenerateSampleSecrets("confluence", secrets.NewSecret(utils.AlphaNumeric("20")+"[a-f0-9]{4}"))...)
+	tps = append(tps, utils.GenerateSampleSecrets("jira", secrets.NewSecret(utils.AlphaNumeric("20")+"[a-f0-9]{4}"))...)
+	tps = append(tps, `JIRA_API_TOKEN=HXe8DGg1iJd2AopzyxkFB7F2`)
 	tps = append(tps, utils.GenerateSampleSecrets("jira", "ATATT3xFfGF0K3irG5tKKi-6u-wwaXQFeGwZ-IHR-hQ3CulkKtMSuteRQFfLZ6jihHThzZCg_UjnDt-4Wl_gIRf4zrZJs5JqaeuBhsfJ4W5GD6yGg3W7903gbvaxZPBjxIQQ7BgFDSkPS8oPispw4KLz56mdK-G6CIvLO6hHRrZHY0Q3tvJ6JxE=C63992E6")...)
 
-	return utils.Validate(r, tps, nil)
+	fps := []string{"getPagesInConfluenceSpace,searchConfluenceUsingCql"}
+
+	return utils.Validate(r, tps, fps)
 }

+ 19 - 0
cmd/generate/config/rules/heroku.go

@@ -24,3 +24,22 @@ func Heroku() *config.Rule {
 	)
 	return utils.Validate(r, tps, nil)
 }
+
+func HerokuV2() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Detected a Heroku API Key, potentially compromising cloud application deployments and operational security.",
+		RuleID:      "heroku-api-key-v2",
+		Regex:       utils.GenerateUniqueTokenRegex(`(HRKU-AA[0-9a-zA-Z_-]{58})`, false),
+		Entropy:     4,
+		Keywords:    []string{"HRKU-AA"},
+	}
+
+	// validate
+	tps := utils.GenerateSampleSecrets("heroku", secrets.NewSecret(`\b(HRKU-AA[0-9a-zA-Z_-]{58})\b`))
+	tps = append(tps,
+		`const KEY = "HRKU-AAlQ1aVoHDujJ9QsDHdHlHO0hbzhoERRSO45ZQusSYHg_____w4_hLrAym_u""`,
+		`API_Key = "HRKU-AAy9Ppr_HD2pPuTyIiTYInO0hbzhoERRSO93ZQusSYHgaD7_WQ07FnF7L9FX"`,
+	)
+	return utils.Validate(r, tps, nil)
+}

+ 8 - 0
cmd/scm/scm.go

@@ -13,6 +13,8 @@ const (
 	GitHubPlatform
 	GitLabPlatform
 	AzureDevOpsPlatform
+	GiteaPlatform
+	BitbucketPlatform
 	// TODO: Add others.
 )
 
@@ -23,6 +25,8 @@ func (p Platform) String() string {
 		"github",
 		"gitlab",
 		"azuredevops",
+		"gitea",
+		"bitbucket",
 	}[p]
 }
 
@@ -38,6 +42,10 @@ func PlatformFromString(s string) (Platform, error) {
 		return GitLabPlatform, nil
 	case "azuredevops":
 		return AzureDevOpsPlatform, nil
+	case "gitea":
+		return GiteaPlatform, nil
+	case "bitbucket":
+		return BitbucketPlatform, nil
 	default:
 		return UnknownPlatform, fmt.Errorf("invalid scm platform value: %s", s)
 	}

+ 8 - 1
config/gitleaks.toml

@@ -144,7 +144,7 @@ keywords = ["asana"]
 [[rules]]
 id = "atlassian-api-token"
 description = "Detected an Atlassian API token, posing a threat to project management and collaboration tool security and data confidentiality."
-regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:atlassian|confluence|jira)(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-zA-Z0-9]{24})(?:[\x60'"\s;]|\\[nr]|$)|\b(ATATT3[A-Za-z0-9_\-=]{186})(?:[\x60'"\s;]|\\[nr]|$)'''
+regex = '''(?i)[\w.-]{0,50}?(?:(?-i:ATLASSIAN|[Aa]tlassian)|(?-i:CONFLUENCE|[Cc]onfluence)|(?-i:JIRA|[Jj]ira))(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{20}[a-f0-9]{4})(?:[\x60'"\s;]|\\[nr]|$)|\b(ATATT3[A-Za-z0-9_\-=]{186})(?:[\x60'"\s;]|\\[nr]|$)'''
 entropy = 3.5
 keywords = [
     "atlassian",
@@ -2296,6 +2296,13 @@ description = "Detected a Heroku API Key, potentially compromising cloud applica
 regex = '''(?i)[\w.-]{0,50}?(?:heroku)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)'''
 keywords = ["heroku"]
 
+[[rules]]
+id = "heroku-api-key-v2"
+description = "Detected a Heroku API Key, potentially compromising cloud application deployments and operational security."
+regex = '''\b((HRKU-AA[0-9a-zA-Z_-]{58}))(?:[\x60'"\s;]|\\[nr]|$)'''
+entropy = 4
+keywords = ["hrku-aa"]
+
 [[rules]]
 id = "hubspot-api-key"
 description = "Found a HubSpot API Token, posing a risk to CRM data integrity and unauthorized marketing operations."

+ 28 - 0
detect/utils.go

@@ -75,6 +75,34 @@ func createScmLink(remote *sources.RemoteInfo, finding report.Finding) string {
 		// This is a bit dirty, but Azure DevOps does not highlight the line when the lineStartColumn and lineEndColumn are not provided
 		link += "&lineStartColumn=1&lineEndColumn=10000000&type=2&lineStyle=plain&_a=files"
 		return link
+	case scm.GiteaPlatform:
+		link := fmt.Sprintf("%s/src/commit/%s/%s", remote.Url, finding.Commit, filePath)
+		if hasInnerPath {
+			return link
+		}
+		ext := strings.ToLower(filepath.Ext(filePath))
+		if ext == ".ipynb" || ext == ".md" {
+			link += "?display=source"
+		}
+		if finding.StartLine != 0 {
+			link += fmt.Sprintf("#L%d", finding.StartLine)
+		}
+		if finding.EndLine != finding.StartLine {
+			link += fmt.Sprintf("-L%d", finding.EndLine)
+		}
+		return link
+	case scm.BitbucketPlatform:
+		link := fmt.Sprintf("%s/src/%s/%s", remote.Url, finding.Commit, filePath)
+		if hasInnerPath {
+			return link
+		}
+		if finding.StartLine != 0 {
+			link += fmt.Sprintf("#lines-%d", finding.StartLine)
+		}
+		if finding.EndLine != finding.StartLine {
+			link += fmt.Sprintf(":%d", finding.EndLine)
+		}
+		return link
 	default:
 		// This should never happen.
 		return ""

+ 68 - 0
detect/utils_test.go

@@ -136,6 +136,74 @@ func Test_createScmLink(t *testing.T) {
 			},
 			want: "https://dev.azure.com/exampleorganisation/exampleproject/_git/exampleRepository/commit/20553ad96a4a080c94a54d677db97eed8ce2560d?path=/examplefile.json&line=25&lineEnd=30&lineStartColumn=1&lineEndColumn=10000000&type=2&lineStyle=plain&_a=files",
 		},
+
+		// Gitea
+		"gitea - single line": {
+			remote: &sources.RemoteInfo{
+				Platform: scm.GiteaPlatform,
+				Url:      "https://gitea.com/exampleorganisation/exampleproject",
+			},
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   25,
+			},
+			want: "https://gitea.com/exampleorganisation/exampleproject/src/commit/20553ad96a4a080c94a54d677db97eed8ce2560d/examplefile.json#L25",
+		},
+		"gitea- multi line": {
+			remote: &sources.RemoteInfo{
+				Platform: scm.GiteaPlatform,
+				Url:      "https://gitea.com/exampleorganisation/exampleproject",
+			},
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   30,
+			},
+			want: "https://gitea.com/exampleorganisation/exampleproject/src/commit/20553ad96a4a080c94a54d677db97eed8ce2560d/examplefile.json#L25-L30",
+		},
+		"gitea - markdown": {
+			remote: &sources.RemoteInfo{
+				Platform: scm.GiteaPlatform,
+				Url:      "https://gitea.com/exampleorganisation/exampleproject",
+			},
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "Readme.md",
+				StartLine: 34,
+				EndLine:   34,
+			},
+			want: "https://gitea.com/exampleorganisation/exampleproject/src/commit/20553ad96a4a080c94a54d677db97eed8ce2560d/Readme.md?display=source#L34",
+		},
+		// bitbucket
+		"bitbucket - single line": {
+			remote: &sources.RemoteInfo{
+				Platform: scm.BitbucketPlatform,
+				Url:      "https://bitbucket.org/exampleorganisation/exampleproject",
+			},
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   25,
+			},
+			want: "https://bitbucket.org/exampleorganisation/exampleproject/src/20553ad96a4a080c94a54d677db97eed8ce2560d/examplefile.json#lines-25",
+		},
+		"bitbucket- multi line": {
+			remote: &sources.RemoteInfo{
+				Platform: scm.BitbucketPlatform,
+				Url:      "https://bitbucket.org/exampleorganisation/exampleproject",
+			},
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   30,
+			},
+			want: "https://bitbucket.org/exampleorganisation/exampleproject/src/20553ad96a4a080c94a54d677db97eed8ce2560d/examplefile.json#lines-25:30",
+		},
 	}
 	for name, tt := range tests {
 		t.Run(name, func(t *testing.T) {

+ 9 - 6
sources/file.go

@@ -55,12 +55,15 @@ func (s *File) Fragments(ctx context.Context, yield FragmentsFunc) error {
 	// and fall back on treating it like a normal file and let fileFragments
 	// decide what to do with it.
 	if err == nil && format != nil {
-		if (s.archiveDepth+1 > s.MaxArchiveDepth) && s.MaxArchiveDepth != 0 {
-			logging.Warn().Str(
-				"path", s.FullPath(),
-			).Int(
-				"max_archive_depth", s.MaxArchiveDepth,
-			).Msg("skipping archive: exceeds max archive depth")
+		if s.archiveDepth+1 > s.MaxArchiveDepth {
+			// Only warn when the feature is enabled
+			if s.MaxArchiveDepth != 0 {
+				logging.Warn().Str(
+					"path", s.FullPath(),
+				).Int(
+					"max_archive_depth", s.MaxArchiveDepth,
+				).Msg("skipping archive: exceeds max archive depth")
+			}
 			return nil
 		}
 		if extractor, ok := format.(archives.Extractor); ok {

+ 4 - 0
sources/git.go

@@ -482,6 +482,10 @@ func platformFromHost(u *url.URL) scm.Platform {
 		return scm.GitLabPlatform
 	case "dev.azure.com", "visualstudio.com":
 		return scm.AzureDevOpsPlatform
+	case "gitea.com", "code.forgejo.org", "codeberg.org":
+		return scm.GiteaPlatform
+	case "bitbucket.org":
+		return scm.BitbucketPlatform
 	default:
 		return scm.UnknownPlatform
 	}