diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5de42d831..c9e8d9176 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,3 @@ # These are supported funding model platforms github: [zricethezav] -custom: ["https://www.paypal.me/zricethezav"] diff --git a/.github/ISSUE_TEMPLATE/maintenance.md b/.github/ISSUE_TEMPLATE/maintenance.md new file mode 100644 index 000000000..7f42bb96d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/maintenance.md @@ -0,0 +1,16 @@ +--- +name: Maintenance request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Additional context** +Add any other context or screenshots about the feature request here. + +cc @zricethezav diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml new file mode 100644 index 000000000..baca755c6 --- /dev/null +++ b/.github/workflows/gitleaks.yml @@ -0,0 +1,13 @@ +name: gitleaks +on: [pull_request, push, workflow_dispatch] +jobs: + scan: + name: gitleaks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..432c070b1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Create and publish a Docker image + +on: + release: + types: [published] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@8b122486cedac8393e77aa9734c3528886e4a1a8 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@dc7b9719a96d48369863986a06765841d7ea23f6 + + - name: Log in to Docker Hub + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + username: ${{ github.actor }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to the Container registry + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: | + zricethezav/gitleaks + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@e551b19e49efd4e98792db7592c17c09b89db8d8 + with: + platforms: linux/amd64,linux/arm64 + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..23043bf67 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Test + +on: + pull_request: + branches: + - "*" + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.19 + + - name: Build + run: go build -v ./... + + - name: Test + run: make test + + - name: Validate Config + run: cd cmd/generate/config && go run main.go diff --git a/.gitignore b/.gitignore index ddf01fd2a..49abd80e2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,15 @@ *.dylib *.DS_STORE *.idea +*.got gitleaks build +# configs +.gitleaks.toml +cmd/generate/config/gitleaks.toml + # Test binary *.out + +dist/ diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 000000000..f763c3af3 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,744 @@ +418edf165dbb63d6f46993ae8f8818ffd87ea582:cmd/generate/config/rules/jwt.go:jwt:17 +418edf165dbb63d6f46993ae8f8818ffd87ea582:cmd/generate/config/rules/jwt.go:jwt:19 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:46 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:48 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:50 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:52 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:54 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:55 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:56 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:57 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:22 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:24 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:28 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:29 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-sensitive-url:164 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-sensitive-url:170 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:120 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:126 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:142 +31650f01e76858ce7a0490943426e84a0824bbc8:config/config_test.go:aws-access-token:31 +5ed010c944ccc715cb9245abafd4e97d98d75e9f:config/config_test.go:aws-access-token:31 +ad7509e3b47331ce9586743ace635422843b695b:cmd/generate/config/rules/privatekey.go:private-key:22 +717cf1b10be1625875199eca8cdf48883348985f:README.md:aws-access-token:23 +3474c58c9e25fe2b1cee855a35bd1bf8a8c0fae8:cmd/generate/config/rules/generic.go:clojars-api-token:38 +a42b32bdf11b6f4ea5c32ec76a1731b4b0c5e52a:cmd/generate/config/rules/generic.go:generic-api-key:40 +a42b32bdf11b6f4ea5c32ec76a1731b4b0c5e52a:cmd/generate/config/rules/generic.go:generic-api-key:41 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:50 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:60 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:61 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:pypi-upload-token:29 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:51 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:73 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:81 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:89 +33082a996774ba4c8ad4ba26fd219d77497eb960:README.md:sidekiq-secret:43 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:98 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:235 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:236 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:253 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:254 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:278 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:279 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:343 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:344 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:362 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:363 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:pypi-upload-token:27 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:49 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:71 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:79 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:87 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:120 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:96 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:128 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:118 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:150 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:126 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:166 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:175 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:183 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:238 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:239 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:256 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:257 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:281 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:282 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:356 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:357 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:375 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:376 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:148 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:27 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:32 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:33 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:164 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:173 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:181 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:43 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:60 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:85 +b8141713e89f5acec500c7a62415f0f1cb7234dc:README.md:discord-client-secret:273 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:aws-access-token:130 +b8141713e89f5acec500c7a62415f0f1cb7234dc:README.md:discord-client-secret:289 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:discord-client-secret:251 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:discord-client-secret:267 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/detect_test.go:aws-access-token:33 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/files_test.go:aws-access-token:32 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/files_test.go:aws-access-token:50 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:config/config_test.go:generic-api-key:133 +80d29764a0bc0f269607d3eb7b2774a0f31e5da3:detect/detect_test.go:aws-access-token:123 +80d29764a0bc0f269607d3eb7b2774a0f31e5da3:testdata/config/allow_global_aws_re.toml:aws-access-token:8 +4acd7a3c8d20b7116a32f9bbade6a3cf15f741e4:detect/detect_test.go:aws-access-token:117 +f0b8d26c9988af725132c100dda5051586a3026e:README.md:discord-client-secret:225 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:config/config_test.go:generic-api-key:144 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:121 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:122 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:157 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:aws-access-token:31 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:32 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:33 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:50 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:51 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:42 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:44 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:58 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:60 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:82 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:83 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:generic-api-key:133 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/config/allow_aws_re.toml:aws-access-token:9 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:generic-api-key:144 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small-branch-foo.txt:aws-access-token:15 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/repos/nogit/main.go:aws-access-token:20 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small.txt:aws-access-token:15 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small.txt:aws-access-token:44 +3a3e13c3b5f85b0116cf2a0cd92529baf22d0ac9:testdata/repos/with_square_and_google/env:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:scan/unstaged_test.go:aws-access-token:38 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_ae8db4a2_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_ae8db4a2_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_depth_1.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_depth_1.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:5 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:26 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:31 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:40 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:46 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:52 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:59 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:74 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:80 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:95 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:109 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_unstaged.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:generic-api-key:6 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:aws-access-token:9 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:aws-access-token:13 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:54 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:56 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:aws-access-token:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:aws-access-token:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:aws-access-token:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:aws-access-token:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:generic-api-key:6 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:aws-access-token:9 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:aws-access-token:13 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_repos/test_dir_2/env:generic-api-key:1 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_repos/test_dir_2/env:generic-api-key:3 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_dir_one_google_leak_and_square_leak.json:generic-api-key:3 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_dir_one_google_leak_and_square_leak.json:generic-api-key:20 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:35 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:37 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:259 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:261 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:339 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:51 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:83 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:85 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:131 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:133 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:147 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:149 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:179 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:227 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:229 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:323 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:355 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:357 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_file1_aws_leak.json:aws-access-token:3 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_file1_aws_leak.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:3 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:17 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:19 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_repos/test_dir_1/server.test.py:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_repos/test_dir_1/server.test2.py:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:99 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:101 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:115 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:117 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:131 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:133 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:147 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:149 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:163 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:165 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:179 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:181 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:195 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:197 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:213 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:83 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:85 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:99 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:101 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:115 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:117 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:131 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:133 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:147 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:149 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:163 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:165 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:179 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:259 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:261 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:181 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:195 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:197 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:339 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:341 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:3 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:5 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:18 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:20 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:33 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:35 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:259 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:261 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_to_from.json:aws-access-token:3 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_to_from.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:323 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:325 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:18 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:20 +fae366a404357fa6c6611756a11e61546ebec4e0:examples/simple_regex_and_allowlist_config.toml:aws-access-token:12 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:3 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:5 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:18 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:20 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_configs/aws_key_aws_allowlisted.toml:aws-access-token:7 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:185 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_repo_nine_aws_leak.json:aws-access-token:3 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_repo_nine_aws_leak.json:aws-access-token:5 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:78 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:80 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:138 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:140 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:153 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:155 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:168 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:170 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:138 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:140 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:153 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:155 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:168 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:170 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:3 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:5 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:18 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:20 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:33 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:35 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_repos/test_repo_8/dummy.txt:aws-access-token:2 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_repos/test_repo_8/dummy.txt:aws-access-token:6 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:33 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak.json:aws-access-token:93 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:78 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:18 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_three_leaks.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:78 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks.json:aws-access-token:33 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:3 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:4 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:16 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:17 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_since_date.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_since_date.json:aws-access-token:4 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_until_date.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_until_date.json:aws-access-token:4 +0d7c18cb39c60efb62a6c7b351f95d46ebe1f63e:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:172 +0d7c18cb39c60efb62a6c7b351f95d46ebe1f63e:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:173 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:4 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:16 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:17 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:29 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:30 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:42 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:43 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:55 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:56 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:3 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:4 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:16 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:17 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:29 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:30 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:42 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:43 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:55 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:56 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:68 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:69 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_local_repo_seven_aws_leak_uncommitted.json:aws-access-token:3 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_local_repo_seven_aws_leak_uncommitted.json:aws-access-token:4 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_repos/test_repo_7/file:aws-access-token:5 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:134 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:160 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:133 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:134 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:172 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:173 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:3 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:4 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:16 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:17 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:29 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:30 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:42 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:43 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:55 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:56 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:68 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:69 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:81 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:82 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:94 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:95 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:107 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:108 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:120 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:121 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:133 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:134 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:146 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:147 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:159 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:160 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:172 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:173 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:186 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:29 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:30 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:42 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:224 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:225 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:212 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:263 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:264 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:237 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:238 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:276 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:277 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:316 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:342 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:121 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:3 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:4 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:29 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:30 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:42 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:146 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:147 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:380 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:381 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:406 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:407 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:445 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:446 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:68 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:69 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:172 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:173 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:68 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:69 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:95 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_owner_aws_leak.json:aws-access-token:120 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_owner_aws_leak.json:aws-access-token:121 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks.json:aws-access-token:107 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks.json:aws-access-token:108 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:95 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_three_leaks.json:aws-access-token:81 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_three_leaks.json:aws-access-token:82 +c4b07f5113bf39019374579a64d83959236295e4:audit/util.go:aws-access-token:66 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:55 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:56 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:55 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:56 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak.json:aws-access-token:276 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak.json:aws-access-token:277 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:16 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:17 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:146 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:147 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six.json:aws-access-token:31 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six.json:aws-access-token:33 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_filepath.json:aws-access-token:3 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_filepath.json:aws-access-token:4 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_path_globally_whitelisted.json:aws-access-token:3 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_path_globally_whitelisted.json:aws-access-token:4 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_repos/test_repo_6/server.test.py:aws-access-token:5 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:55 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:56 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:68 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:69 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_repos/test_repo_6/config/application.properties:aws-access-token:3 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:133 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:134 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:250 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:251 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:263 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:264 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:3 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:4 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:16 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:17 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:3 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:4 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:16 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:17 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:42 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:43 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:68 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:69 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:94 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_repos/test_repo_5/secrets.py:aws-access-token:1 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_repos/test_repo_5/secrets.py:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:16 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:17 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:42 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:43 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:16 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:17 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:42 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:43 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:55 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:56 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:68 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:69 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:81 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:82 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:107 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:108 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:94 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:95 +6e1c41b536a514e1d17768eb42ebf5d87e61247d:examples/simple_regex_and_whitelist_config.toml:aws-access-token:4 +6e1c41b536a514e1d17768eb42ebf5d87e61247d:examples/simple_regex_and_whitelist_config.toml:aws-access-token:12 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:212 +275232f8c8f3ae4936667602a06a46caa156580b:audit/util.go:aws-access-token:90 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:237 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:238 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_configs/aws_key_aws_whitelisted.toml:aws-access-token:6 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_regex_whitelist.json.got:aws-access-token:3 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_regex_whitelist.json.got:aws-access-token:4 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:315 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:316 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:341 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:342 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:445 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:446 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:471 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:472 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:549 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:550 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:575 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:576 +e446ba073804cf714316c5dc00d0ac41917b31f7:test_data/test_regex_entropy.json:aws-access-token:3 +e446ba073804cf714316c5dc00d0ac41917b31f7:test_data/test_regex_entropy.json:aws-access-token:4 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:241 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:242 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:255 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:256 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:269 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:270 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:283 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:284 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:297 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:298 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:311 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:312 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:325 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:326 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:339 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:340 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:353 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:354 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:367 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:368 +b55d88dc151f7022901cda41a03d43e0e508f2b7:audit/audit_test.go:aws-access-token:207 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_entropy.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:87 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:88 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:101 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:102 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_repos/test_repo_1/server.test.py:aws-access-token:5 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:87 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:88 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:101 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:102 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:115 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:116 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:129 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:130 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:143 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:144 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:157 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:158 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:171 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:172 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:186 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:199 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:200 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:213 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:214 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:227 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:228 +7bd55e33b504f76fc2aec27f4f479a5fb2606480:src/constants.go:private-key:32 +e79ffc6ae8f66931d687407e07bc0632fb262091:src/constants.go:private-key:23 +2b995fda446e03b7660c327fec41265f03199c71:config.go:private-key:28 +1f80d14f3f069118a2e578d83bbc8440495fc906:main.go:private-key:118 +fe977ea8577b739c34a0071ba34e98cf6b6fad38:checks_test.go:aws-access-token:52 +4b4fa00b69a9a2e5f7619b1ff1dd6d160f588aec:README.md:aws-access-token:25 +4b4fa00b69a9a2e5f7619b1ff1dd6d160f588aec:README.md:aws-access-token:27 +2186f2299990290e4e19cf3b28906e2ec369d01e:main.go:private-key:44 +9f694531b203663588c68c82dbbfb34d4f71863f:main.go:private-key:44 +1e250f1a14eab6f457d61f5d7650b47c6ff43334:checks_test.go:aws-access-token:19 +1e250f1a14eab6f457d61f5d7650b47c6ff43334:config.yml:private-key:2 +bc26e979c5911cf647c1bede0b3700ebaaa454c8:checks_test.go:aws-access-token:36 +8f352bd840f028b481dc725b77d2f4904b77913b:checks_test.go:aws-access-token:34 +ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29:checks_test.go:aws-access-token:37 +06c9e824d5985c8e8789321ae70de7ace3b093dc:main.go:aws-access-token:15 + +README.md:aws-access-token:204 +README.md:aws-access-token:205 +README.md:aws-access-token:244 +cmd/generate/config/rules/privatekey.go:private-key:19 +cmd/generate/config/rules/generic.go:clojars-api-token:43 +cmd/generate/config/rules/generic.go:generic-api-key:45 +cmd/generate/config/rules/generic.go:generic-api-key:46 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:22 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:24 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:28 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:29 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:46 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:48 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:50 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:52 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:54 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:55 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:56 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:57 +config/config_test.go:aws-access-token:31 +detect/detect_test.go:sidekiq-secret:120 +detect/detect_test.go:sidekiq-secret:126 +detect/detect_test.go:sidekiq-secret:142 +detect/detect_test.go:aws-access-token:50 +detect/detect_test.go:aws-access-token:60 +detect/detect_test.go:aws-access-token:61 +detect/detect_test.go:aws-access-token:98 +detect/detect_test.go:aws-access-token:104 +detect/detect_test.go:aws-access-token:105 +detect/detect_test.go:aws-access-token:186 +detect/detect_test.go:aws-access-token:194 +detect/detect_test.go:aws-access-token:202 +detect/detect_test.go:aws-access-token:288 +detect/detect_test.go:aws-access-token:296 +detect/detect_test.go:aws-access-token:359 +detect/detect_test.go:aws-access-token:360 +detect/detect_test.go:aws-access-token:378 +detect/detect_test.go:aws-access-token:379 +detect/detect_test.go:aws-access-token:404 +detect/detect_test.go:aws-access-token:405 +detect/detect_test.go:aws-access-token:480 +detect/detect_test.go:aws-access-token:481 +detect/detect_test.go:aws-access-token:499 +detect/detect_test.go:aws-access-token:500 +detect/detect_test.go:sidekiq-sensitive-url:164 +detect/detect_test.go:sidekiq-sensitive-url:170 +detect/detect_test.go:pypi-upload-token:76 +detect/detect_test.go:pypi-upload-token:82 +detect/detect_test.go:pypi-upload-token:83 +detect/detect_test.go:discord-api-token:211 +detect/detect_test.go:discord-api-token:233 +detect/detect_test.go:discord-api-token:241 +detect/detect_test.go:discord-api-token:263 +detect/detect_test.go:discord-api-token:279 +testdata/config/allow_aws_re.toml:aws-access-token:9 +testdata/config/allow_global_aws_re.toml:aws-access-token:8 +testdata/expected/git/small-branch-foo.txt:aws-access-token:15 +testdata/expected/git/small.txt:aws-access-token:15 +testdata/expected/git/small.txt:aws-access-token:44 +testdata/repos/nogit/main.go:aws-access-token:20 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:513 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:492 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:414 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:388 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:366 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:discord-api-token:255 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:discord-api-token:224 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-sensitive-url:177 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-secret:154 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-secret:130 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:107 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:pypi-upload-token:84 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:62 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:62 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:pypi-upload-token:84 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:107 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-secret:130 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-secret:154 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-sensitive-url:177 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:discord-api-token:224 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:discord-api-token:255 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:366 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:388 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:414 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:492 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:513 +bfbc39eb185a217ead81a7174026f1c55f963660:cmd/generate/config/rules/jwt.go:jwt:17 +bfbc39eb185a217ead81a7174026f1c55f963660:cmd/generate/config/rules/jwt.go:jwt:19 diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..94ad5762c --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,29 @@ +project_name: gitleaks + +builds: + - main: main.go + binary: gitleaks + goos: + - darwin + - linux + - windows + goarch: + - amd64 + - "386" + - arm + - arm64 + goarm: + - "6" + - "7" + ldflags: + - -s -w -X=github.com/zricethezav/gitleaks/v8/cmd.Version={{.Version}} +archives: + - builds: [gitleaks] + format_overrides: + - goos: windows + format: zip + replacements: + amd64: x64 + 386: x32 +release: + prerelease: true diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 000000000..c8aba5b73 --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,11 @@ +- id: gitleaks + name: Detect hardcoded secrets + description: Detect hardcoded secrets using Gitleaks + entry: gitleaks protect --verbose --redact --staged + language: golang + pass_filenames: false +- id: gitleaks-docker + name: Detect hardcoded secrets + description: Detect hardcoded secrets using Gitleaks + entry: zricethezav/gitleaks protect --verbose --redact --staged + language: docker_image diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 97a1b6f42..000000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: -- 1.14.x -services: -- docker -script: -- make test -- make security-scan diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..6d2ce277b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,103 @@ +# Contribution guidelines + +## General + +### Issues + +If you have a feature or bug fix you would like to contribute please check if +there are any open issues describing your proposed addition. If there are open +issues, make a comment stating you are working on fixing or implementing said +issue. If not, then please open an issue describing your addition. Make sure to +link your PR to an issue. + +### Pull Requests + +Fill out the template as best you can. Make sure your tests pass. If you see a +PR that isn't one you opened and want it introduced in the next release, +give it a :thumbsup: on the PR description. + +## Adding new Gitleaks rules + +If you want to add a new rule to the [default Gitleaks configuration](https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml) then follow these steps. + +1. Create a `cmd/generate/config/rules/{provider}.go` file. + This file is used to generate a new Gitleaks rule. + Let's look at `beamer.go` for example. Comments have been added for context. + + ```golang + func Beamer() *config.Rule { + // Define Rule + r := config.Rule{ + // Human redable description of the rule + Description: "Beamer API token", + + // Unique ID for the rule + RuleID: "beamer-api-token", + + // Regex capture group for the actual secret + SecretGroup: 1, + + + // Regex used for detecting secrets. See regex section below for more details + Regex: generateSemiGenericRegex([]string{"beamer"}, `b_[a-z0-9=_\-]{44}`), + + // Keywords used for string matching on fragments (think of this as a prefilter) + Keywords: []string{"beamer"}, + } + + // validate + tps := []string{ + generateSampleSecret("beamer", "b_"+secrets.NewSecret(alphaNumericExtended("44"))), + } + return validate(r, tps, nil) + } + ``` + + Feel free to use this example as a template when writing new rules. + This file should be fairly self-explanatory except for a few items; + regex and secret generation. To help with maintence, _most_ rules should + be uniform. The functions, + [`generateSemiGenericRegex`](https://github.com/zricethezav/gitleaks/blob/master/cmd/generate/config/rules/rule.go#L31) and [`generateUniqueTokenRegex`](https://github.com/zricethezav/gitleaks/blob/master/cmd/generate/config/rules/rule.go#L44) will generate rules + that follow defined patterns. + + The function signatures look like this: + + ```golang + func generateSemiGenericRegex(identifiers []string, secretRegex string) *regexp.Regexp + + func generateUniqueTokenRegex(secretRegex string) *regexp.Regexp + ``` + + `generateSemiGenericRegex` accepts a list of identifiers and a regex. + The list of identifiers _should_ match the list of `Keywords` in the rule + definition above. Both `identifiers` in the `generateSemiGenericRegex` + function _and_ `Keywords` act as filters for Gitleaks telling the program + "_at least one of these strings must be present to be considered a leak_" + + `generateUniqueToken` just accepts a regex. If you are writing a rule for a + token that is unique enough not to require an identifier then you can use + this function. For example, Pulumi's API Token has the prefix `pul-` which is + unique enough to use `generateUniqueToken`. But something like Beamer's API + token that has a `b_` prefix is not unqiue enough to use `generateUniqueToken`, + so instead we use `generateSemiGenericRegex` and require a `beamer` + identifier is part of the rule. + If a token's prefix has more than `3` characters then you could + probably get away with using `generateUniqueToken`. + + Last thing you'll want to hit before we move on from this file is the + validation part. You can use `generateSampleSecret` to create a secret for the + true positives (`tps` in the example above) used in `validate`. + +1. Update `cmd/generate/config/main.go`. Add a line like + `configRules = append(configRules, rules.Beamer())` in `main()`. Try and keep + this alphabetically pretty please. + +1. Change directories into `cmd/generate/config` and run `go run main.go` + + ``` + cd cmd/generate/config && go run main.go + ``` + +1. Check out your new rules in `config/gitleaks.toml` and see if everything looks good. + +1. Open a PR diff --git a/Dockerfile b/Dockerfile index 3227f579b..cbee1ad32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,15 @@ -FROM golang:1.14.1 AS build +FROM golang:1.19 AS build WORKDIR /go/src/github.com/zricethezav/gitleaks -ARG ldflags COPY . . -RUN GO111MODULE=on CGO_ENABLED=0 go build -o bin/gitleaks -ldflags "-X="${ldflags} *.go +RUN VERSION=$(git describe --tags --abbrev=0) && \ +CGO_ENABLED=0 go build -o bin/gitleaks -ldflags "-X="github.com/zricethezav/gitleaks/v8/cmd.Version=${VERSION} -FROM alpine:3.11 -RUN apk add --no-cache bash git openssh +FROM alpine:3.16 +RUN adduser -D gitleaks && \ + apk add --no-cache bash git openssh-client COPY --from=build /go/src/github.com/zricethezav/gitleaks/bin/* /usr/bin/ -ENTRYPOINT ["gitleaks"] - -# How to use me : +USER gitleaks -# docker build -t gitleaks . -# docker run --rm --name=gitleaks gitleaks --repo=https://github.com/zricethezav/gitleaks +RUN git config --global --add safe.directory '*' -# This will check for secrets in https://github.com/zricethezav/gitleaks +ENTRYPOINT ["gitleaks"] diff --git a/Makefile b/Makefile index a6f6ec81a..f53e37964 100644 --- a/Makefile +++ b/Makefile @@ -1,52 +1,26 @@ -.PHONY: test test-cover build release-builds +.PHONY: test test-cover -VERSION := `git fetch --tags && git tag | sort -V | tail -1` PKG=github.com/zricethezav/gitleaks -LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks/v6/version.Version=$(VERSION)" -_LDFLAGS="github.com/zricethezav/gitleaks/v6/version.Version=$(VERSION)" +VERSION := `git fetch --tags && git tag | sort -V | tail -1` +LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks/v8/cmd.Version=$(VERSION)" COVER=--cover --coverprofile=cover.out test-cover: - go test ./... --race $(COVER) $(PKG) -v + go test -v ./... --race $(COVER) $(PKG) go tool cover -html=cover.out -test: - go get golang.org/x/lint/golint +format: go fmt ./... - go vet ./... - golint ./... - go test ./... --race $(PKG) -v -test-integration: - go test github.com/zricethezav/gitleaks/hosts -v -integration +test: format + go vet ./... + go test -v ./... --race $(PKG) -build: - go fmt ./... - golint ./... +build: format go vet ./... go mod tidy go build $(LDFLAGS) -security-scan: - go get github.com/securego/gosec/cmd/gosec - gosec -no-fail ./... - -release-builds: - rm -rf build - mkdir build - env GOOS="windows" GOARCH="amd64" go build -o "build/gitleaks-windows-amd64.exe" $(LDFLAGS) - env GOOS="windows" GOARCH="386" go build -o "build/gitleaks-windows-386.exe" $(LDFLAGS) - env GOOS="linux" GOARCH="amd64" go build -o "build/gitleaks-linux-amd64" $(LDFLAGS) - env GOOS="linux" GOARCH="arm" go build -o "build/gitleaks-linux-arm" $(LDFLAGS) - env GOOS="linux" GOARCH="mips" go build -o "build/gitleaks-linux-mips" $(LDFLAGS) - env GOOS="linux" GOARCH="mips" go build -o "build/gitleaks-linux-mips" $(LDFLAGS) - env GOOS="darwin" GOARCH="amd64" go build -o "build/gitleaks-darwin-amd64" $(LDFLAGS) - -deploy: - @echo "$(DOCKER_PASSWORD)" | docker login -u "$(DOCKER_USERNAME)" --password-stdin - docker build --build-arg ldflags=$(_LDFLAGS) -f Dockerfile -t zricethezav/gitleaks:latest -t zricethezav/gitleaks:$(VERSION) . - echo "Pushing zricethezav/gitleaks:$(VERSION) and zricethezav/gitleaks:latest" - docker push zricethezav/gitleaks - -dockerbuild: - docker build --build-arg ldflags=$(_LDFLAGS) -f Dockerfile -t zricethezav/gitleaks:latest -t zricethezav/gitleaks:$(VERSION) . +clean: + find . -type f -name '*.got.*' -delete + find . -type f -name '*.out' -delete diff --git a/README.md b/README.md index 672036af0..ad6ad1d52 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,415 @@ -

- gitleaks -

- Travis +# Gitleaks + +``` +┌─○───┐ +│ │╲ │ +│ │ ○ │ +│ ○ ░ │ +└─░───┘ +``` + +

+

+ + Github Test + + + + + + + + + gitleaks badge + + + Follow @zricethezav +

-Gitleaks is a SAST tool for detecting hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks aims to be the **easy-to-use, all-in-one solution** for finding secrets, past or present, in your code. - -### Features: -- Scans for [commited](https://github.com/zricethezav/gitleaks/wiki/Scanning) secrets -- Scans for [uncommitted](https://github.com/zricethezav/gitleaks/wiki/Scanning#uncommitted-changes-scan) secrets as part of shifting security left -- Available [Github Action](https://github.com/marketplace/actions/gitleaks) -- Gitlab and Github API support which allows scans of whole organizations, users, and pull/merge requests -- [Custom rules](https://github.com/zricethezav/gitleaks/wiki/Configuration) via toml configuration -- High performance using [go-git](https://github.com/go-git/go-git) -- JSON and CSV reporting -- Private repo scans using key or password based authentication +Gitleaks is a SAST tool for **detecting** and **preventing** hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an **easy-to-use, all-in-one solution** for detecting secrets, past or present, in your code. + +``` +➜ ~/code(master) gitleaks detect --source . -v + + ○ + │╲ + │ ○ + ○ ░ + ░ gitleaks + + +Finding: "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef", +Secret: cafebabe:deadbeef +RuleID: sidekiq-secret +Entropy: 2.609850 +File: cmd/generate/config/rules/sidekiq.go +Line: 23 +Commit: cd5226711335c68be1e720b318b7bc3135a30eb2 +Author: John +Email: john@users.noreply.github.com +Date: 2022-08-03T12:31:40Z +Fingerprint: cd5226711335c68be1e720b318b7bc3135a30eb2:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23 +``` + +## Getting Started + +Gitleaks can be installed using Homebrew, Docker, or Go. Gitleaks is also available in binary form for many popular platforms and OS types on the [releases page](https://github.com/zricethezav/gitleaks/releases). In addition, Gitleaks can be implemented as a pre-commit hook directly in your repo or as a GitHub action using [Gitleaks-Action](https://github.com/gitleaks/gitleaks-action). + +### Installing + +```bash +# MacOS +brew install gitleaks + +# Docker (DockerHub) +docker pull zricethezav/gitleaks:latest +docker run -v ${path_to_host_folder_to_scan}:/path zricethezav/gitleaks:latest [COMMAND] --source="/path" [OPTIONS] + +# Docker (ghcr.io) +docker pull ghcr.io/zricethezav/gitleaks:latest +docker run -v ${path_to_host_folder_to_scan}:/path zricethezav/gitleaks:latest [COMMAND] --source="/path" [OPTIONS] + +# From Source +git clone https://github.com/zricethezav/gitleaks.git +cd gitleaks +make build +``` + +### Github Action + +Check out the official [Gitleaks GitHub Action](https://github.com/gitleaks/gitleaks-action) + +``` +name: gitleaks +on: [pull_request, push, workflow_dispatch] +jobs: + scan: + name: gitleaks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE}} # Only required for Organizations, not personal accounts. +``` + +### Pre-Commit + +1. Install pre-commit from https://pre-commit.com/#install +2. Create a `.pre-commit-config.yaml` file at the root of your repository with the following content: + + ``` + repos: + - repo: https://github.com/zricethezav/gitleaks + rev: v8.12.0 + hooks: + - id: gitleaks + ``` + + for a [native execution of GitLeaks](https://github.com/zricethezav/gitleaks/releases) or use the [`gitleaks-docker` pre-commit ID](https://github.com/zricethezav/gitleaks/blob/master/.pre-commit-hooks.yaml) for executing GitLeaks using the [official Docker images](#docker) + +3. Auto-update the config to the latest repos' versions by executing `pre-commit autoupdate` +4. Install with `pre-commit install` +5. Now you're all set! + +``` +➜ git commit -m "this commit contains a secret" +Detect hardcoded secrets.................................................Failed +``` + +Note: to disable the gitleaks pre-commit hook you can prepend `SKIP=gitleaks` to the commit command +and it will skip running gitleaks + +``` +➜ SKIP=gitleaks git commit -m "skip gitleaks check" +Detect hardcoded secrets................................................Skipped +``` + +## Usage + +``` +Usage: + gitleaks [command] + +Available Commands: + completion generate the autocompletion script for the specified shell + detect Detect secrets in code + help Help about any command + protect Protect secrets in code + version Display gitleaks version + +Flags: + -c, --config string config file path + order of precedence: + 1. --config/-c + 2. env var GITLEAKS_CONFIG + 3. (--source/-s)/.gitleaks.toml + If none of the three options are used, then gitleaks will use the default config + --exit-code string exit code when leaks have been encountered (default: 1) + -h, --help help for gitleaks + -l, --log-level string log level (debug, info, warn, error, fatal) (default "info") + --no-banner suppress banner + --redact redact secrets from logs and stdout + -f, --report-format string output format (json, csv, sarif) + -r, --report-path string report file + -b, --baseline-path path to a previously generated report with known issues that gitleaks should ignore + -s, --source string path to source (git repo, directory, file) + -v, --verbose show verbose output from scan + +Use "gitleaks [command] --help" for more information about a command. +``` + +### Commands + +There are two commands you will use to detect secrets; `detect` and `protect`. + +#### Detect + +The `detect` command is used to scan repos, directories, and files. This command can be used on developer machines and in CI environments. + +When running `detect` on a git repository, gitleaks will parse the output of a `git log -p` command (you can see how this executed +[here](https://github.com/zricethezav/gitleaks/blob/7240e16769b92d2a1b137c17d6bf9d55a8562899/git/git.go#L17-L25)). +[`git log -p` generates patches](https://git-scm.com/docs/git-log#_generating_patch_text_with_p) which gitleaks will use to detect secrets. +You can configure what commits `git log` will range over by using the `--log-opts` flag. `--log-opts` accepts any option for `git log -p`. +For example, if you wanted to run gitleaks on a range of commits you could use the following command: `gitleaks detect --source . --log-opts="--all commitA..commitB"`. +See the `git log` [documentation](https://git-scm.com/docs/git-log) for more information. + +You can scan files and directories by using the `--no-git` option. + +#### Protect + +The `protect` command is used to uncommitted changes in a git repo. This command should be used on developer machines in accordance with +[shifting left on security](https://cloud.google.com/architecture/devops/devops-tech-shifting-left-on-security). +When running `protect` on a git repository, gitleaks will parse the output of a `git diff` command (you can see how this executed +[here](https://github.com/zricethezav/gitleaks/blob/7240e16769b92d2a1b137c17d6bf9d55a8562899/git/git.go#L48-L49)). You can set the +`--staged` flag to check for changes in commits that have been `git add`ed. The `--staged` flag should be used when running Gitleaks +as a pre-commit. + +**NOTE**: the `protect` command can only be used on git repos, running `protect` on files or directories will result in an error message. + +### Creating a baseline + +When scanning large repositories or repositories with a long history, it can be convenient to use a baseline. When using a baseline, +gitleaks will ignore any old findings that are present in the baseline. A baseline can be any gitleaks report. To create a gitleaks report, run gitleaks with the `--report-path` parameter. +``` +gitleaks detect --report-path gitleaks-report.json # This will save the report in a file called gitleaks-report.json +``` -## Installation, Documentation and Examples -This project is documented [here](https://github.com/zricethezav/gitleaks/wiki) +Once as baseline is created it can be applied when running the detect command again: +``` +gitleaks detect --baseline-path gitleaks-report.json --report-path findings.json +``` -### Sponsors ❤️ -#### Corporate Sponsors -[![gammanet](https://gammanet.com/assets/images/new-design/gamma-logo.png)](https://gammanet.com/?utm_source=gitleaks&utm_medium=homepage&utm_campaign=gitleaks_promotion) +After running the detect command with the --baseline-path parameter, report output (findings.json) will only contain new issues. -Gamma proactively detects and remediates data leaks across cloud apps. Scan your public repos for secret leaks with [Gamma](https://gammanet.com/github-demo?utm_source=gitleaks&utm_medium=homepage&utm_campaign=gitleaks_promotion) +### Verify Findings + +You can verify a finding found by gitleaks using a `git log` command. +Example output: + +``` +{ + "Description": "AWS", + "StartLine": 37, + "EndLine": 37, + "StartColumn": 19, + "EndColumn": 38, + "Match": "\t\t\"aws_secret= \\\"AKIAIMNOJVGFDXXXE4OA\\\"\": true,", + "Secret": "AKIAIMNOJVGFDXXXE4OA", + "File": "checks_test.go", + "Commit": "ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29", + "Entropy": 0, + "Author": "zricethezav", + "Email": "thisispublicanyways@gmail.com", + "Date": "2018-01-28 17:39:00 -0500 -0500", + "Message": "[update] entropy check", + "Tags": [], + "RuleID": "aws-access-token" +} + +``` + +We can use the following format to verify the leak: + +``` +git log -L {StartLine,EndLine}:{File} {Commit} +``` + +So in this example it would look like: + +``` +git log -L 37,37:checks_test.go ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29 +``` + +Which gives us: + +``` +commit ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29 +Author: zricethezav +Date: Sun Jan 28 17:39:00 2018 -0500 + + [update] entropy check + +diff --git a/checks_test.go b/checks_test.go +--- a/checks_test.go ++++ b/checks_test.go +@@ -28,0 +37,1 @@ ++ "aws_secret= \"AKIAIMNOJVGFDXXXE4OA\"": true, + +``` + +## Pre-Commit hook + +You can run Gitleaks as a pre-commit hook by copying the example `pre-commit.py` script into +your `.git/hooks/` directory. + +## Configuration + +Gitleaks offers a configuration format you can follow to write your own secret detection rules: + +```toml +# Title for the gitleaks configuration file. +title = "Gitleaks title" + +# Extend the base (this) configuration. When you extend a configuration +# the base rules take precendence over the extended rules. I.e, if there are +# duplicate rules in both the base configuration and the extended configuration +# the base rules will override the extended rules. +# Another thing to know with extending configurations is you can chain together +# multiple configuration files to a depth of 2. Allowlist arrays are appended +# and can contain duplicates. +# useDefault and path can NOT be used at the same time. Choose one. +[extend] +# useDefault will extend the base configuration with the default gitleaks config: +# https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml +useDefault = true +# or you can supply a path to a configuration. Path is relative to where gitleaks +# was invoked, not the location of the base config. +path = "common_config.toml" + +# An array of tables that contain information that define instructions +# on how to detect secrets +[[rules]] + +# Unique identifier for this rule +id = "awesome-rule-1" + +# Short human readable description of the rule. +description = "awesome rule 1" + +# Golang regular expression used to detect secrets. Note Golang's regex engine +# does not support lookaheads. +regex = '''one-go-style-regex-for-this-rule''' + +# Golang regular expression used to match paths. This can be used as a standalone rule or it can be used +# in conjunction with a valid `regex` entry. +path = '''a-file-path-regex''' + +# Array of strings used for metadata and reporting purposes. +tags = ["tag","another tag"] + +# Int used to extract secret from regex match and used as the group that will have +# its entropy checked if `entropy` is set. +secretGroup = 3 + +# Float representing the minimum shannon entropy a regex group must have to be considered a secret. +entropy = 3.5 + +# Keywords are used for pre-regex check filtering. Rules that contain +# keywords will perform a quick string compare check to make sure the +# keyword(s) are in the content being scanned. Ideally these values should +# either be part of the idenitifer or unique strings specific to the rule's regex +# (introduced in v8.6.0) +keywords = [ + "auth", + "password", + "token", +] + +# You can include an allowlist table for a single rule to reduce false positives or ignore commits +# with known/rotated secrets +[rules.allowlist] +description = "ignore commit A" +commits = [ "commit-A", "commit-B"] +paths = [ + '''go\.mod''', + '''go\.sum''' +] +regexes = [ + '''process''', + '''getenv''', +] +# note: stopwords targets the extracted secret, not the entire regex match +# like 'regexes' does. (stopwords introduced in 8.8.0) +stopwords = [ + '''client''', + '''endpoint''', +] + + +# This is a global allowlist which has a higher order of precedence than rule-specific allowlists. +# If a commit listed in the `commits` field below is encountered then that commit will be skipped and no +# secrets will be detected for said commit. The same logic applies for regexes and paths. +[allowlist] +description = "global allow list" +commits = [ "commit-A", "commit-B", "commit-C"] +paths = [ + '''gitleaks\.toml''', + '''(.*?)(jpg|gif|doc)''' +] +regexes = [ + '''219-09-9999''', + '''078-05-1120''', + '''(9[0-9]{2}|666)-\d{2}-\d{4}''', +] +# note: stopwords targets the extracted secret, not the entire regex match +# like 'regexes' does. (stopwords introduced in 8.8.0) +stopwords = [ + '''client''', + '''endpoint''', +] +``` +Refer to the default [gitleaks config](https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml) for examples or follow the [contributing guidelines](https://github.com/zricethezav/gitleaks/blob/master/README.md). + +### Additional Configuration +#### gitleaks:allow +If you are knowingly committing a test secret that gitleaks will catch you can add a `gitleaks:allow` comment to that line which will instruct gitleaks +to ignore that secret. Ex: +``` +class CustomClass: + discord_client_secret = '8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ' #gitleaks:allow + +``` + +#### .gitleaksignore +You can ignore specific findings by creating a `.gitleaksignore` file at the root of your repo. In release v8.10.0 Gitleaks added a `Fingerprint` value to the Gitleaks report. Each leak, or finding, has a Fingerprint that uniquely identifies a secret. Add this fingerprint to the `.gitleaksignore` file to ignore that specific secret. See Gitleaks' [.gitleaksignore](https://github.com/zricethezav/gitleaks/blob/master/.gitleaksignore) for an example. Note: this feature is expirmental and is subject to change in the future. + + +## Secured by Jit + +We use [Jit](https://www.jit.io/jit-open-source-gitleaks?utm_source=github&utm_medium=readme&utm_campaign=GitleaksReadme&utm_id=oss&items=item-secret-detection) to secure our codebase, to achieve fully automated, full-stack continuous security using the world's best OSS security tools. + +## Sponsorships + +

+ + Tines Sponsorship + +

-#### Individual Sponsors -These users are [sponsors](https://github.com/sponsors/zricethezav) of gitleaks: +## Exit Codes -[![Adam Shannon](https://github.com/adamdecaf.png?size=50)](https://github.com/adamdecaf) | ----| ----- -#### Logo Attribution -The Gitleaks logo uses the Git Logo created Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License. +You can always set the exit code when leaks are encountered with the --exit-code flag. Default exit codes below: +``` +0 - no leaks present +1 - leaks or error encountered +126 - unknown flag +``` diff --git a/USERS.md b/USERS.md new file mode 100644 index 000000000..2235c163b --- /dev/null +++ b/USERS.md @@ -0,0 +1,25 @@ +## Who uses Gitleaks? + +As the Gitleaks Community grows, we'd like to keep a list of our users. + +Here's a running list of some organizations using Gitleaks[^1]: + +1. [Gitleaks](https://gitleaks.io) +1. [GoReleaser](https://goreleaser.com) +2. [Trendyol](https://trendyol.com) + +Feel free to [add yours](https://github.com/zricethezav/gitleaks/edit/master/USERS.md)! + + + +[^1]: Entries were either added by the companies themselves or by the maintainers after seeing it in the wild. + You can see all public repositories using Gitleaks or Gitleaks-Action by [searching on GitHub](https://github.com/search?q=gitleaks). + + diff --git a/cmd/detect.go b/cmd/detect.go new file mode 100644 index 000000000..40124bdfc --- /dev/null +++ b/cmd/detect.go @@ -0,0 +1,181 @@ +package cmd + +import ( + "os" + "path/filepath" + "time" + + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" + "github.com/zricethezav/gitleaks/v8/report" +) + +func init() { + rootCmd.AddCommand(detectCmd) + detectCmd.Flags().String("log-opts", "", "git log options") + detectCmd.Flags().Bool("no-git", false, "treat git repo as a regular directory and scan those files, --log-opts has no effect on the scan when --no-git is set") +} + +var detectCmd = &cobra.Command{ + Use: "detect", + Short: "detect secrets in code", + Run: runDetect, +} + +func runDetect(cmd *cobra.Command, args []string) { + initConfig() + var ( + vc config.ViperConfig + findings []report.Finding + err error + ) + + // Load config + if err = viper.Unmarshal(&vc); err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg, err := vc.Translate() + if err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg.Path, _ = cmd.Flags().GetString("config") + + // start timer + start := time.Now() + + // Setup detector + detector := detect.NewDetector(cfg) + detector.Config.Path, err = cmd.Flags().GetString("config") + if err != nil { + log.Fatal().Err(err).Msg("") + } + source, err := cmd.Flags().GetString("source") + if err != nil { + log.Fatal().Err(err).Msg("") + } + // if config path is not set, then use the {source}/.gitleaks.toml path. + // note that there may not be a `{source}/.gitleaks.toml` file, this is ok. + if detector.Config.Path == "" { + detector.Config.Path = filepath.Join(source, ".gitleaks.toml") + } + // set verbose flag + if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil { + log.Fatal().Err(err).Msg("") + } + // set redact flag + if detector.Redact, err = cmd.Flags().GetBool("redact"); err != nil { + log.Fatal().Err(err).Msg("") + } + + if fileExists(filepath.Join(source, ".gitleaksignore")) { + if err = detector.AddGitleaksIgnore(filepath.Join(source, ".gitleaksignore")); err != nil { + log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore") + } + } + + // ignore findings from the baseline (an existing report in json format generated earlier) + baselinePath, _ := cmd.Flags().GetString("baseline-path") + if baselinePath != "" { + err = detector.AddBaseline(baselinePath) + if err != nil { + log.Error().Msgf("Could not load baseline. The path must point of a gitleaks report generated using the default format: %s", err) + } + } + + // set exit code + exitCode, err := cmd.Flags().GetInt("exit-code") + if err != nil { + log.Fatal().Err(err).Msg("could not get exit code") + } + + // determine what type of scan: + // - git: scan the history of the repo + // - no-git: scan files by treating the repo as a plain directory + noGit, err := cmd.Flags().GetBool("no-git") + if err != nil { + log.Fatal().Err(err).Msg("could not call GetBool() for no-git") + } + + // start the detector scan + if noGit { + findings, err = detector.DetectFiles(source) + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + + } else { + var logOpts string + logOpts, err = cmd.Flags().GetString("log-opts") + if err != nil { + log.Fatal().Err(err).Msg("") + } + findings, err = detector.DetectGit(source, logOpts, detect.DetectType) + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + } + + // log info about the scan + if err == nil { + log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("leaks found: %d", len(findings)) + } else { + log.Info().Msg("no leaks found") + } + } else { + log.Warn().Msgf("partial scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("%d leaks found in partial scan", len(findings)) + } else { + log.Warn().Msg("no leaks found in partial scan") + } + } + + // write report if desired + reportPath, _ := cmd.Flags().GetString("report-path") + ext, _ := cmd.Flags().GetString("report-format") + if reportPath != "" { + if err := report.Write(findings, cfg, ext, reportPath); err != nil { + log.Fatal().Err(err).Msg("could not write") + } + } + + if err != nil { + os.Exit(1) + } + + if len(findings) != 0 { + os.Exit(exitCode) + } +} + +func fileExists(fileName string) bool { + // check for a .gitleaksignore file + info, err := os.Stat(fileName) + if err != nil && !os.IsNotExist(err) { + return false + } + + if info != nil && err == nil { + if !info.IsDir() { + return true + } + } + return false +} + +func FormatDuration(d time.Duration) string { + scale := 100 * time.Second + // look for the max scale that is smaller than d + for scale > d { + scale = scale / 10 + } + return d.Round(scale / 100).String() +} diff --git a/cmd/generate/config/main.go b/cmd/generate/config/main.go new file mode 100644 index 000000000..7ad7755cd --- /dev/null +++ b/cmd/generate/config/main.go @@ -0,0 +1,192 @@ +package main + +import ( + "os" + "text/template" + + "github.com/rs/zerolog/log" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/config/rules" + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + templatePath = "rules/config.tmpl" +) + +func main() { + var configRules []*config.Rule + configRules = append(configRules, rules.AdafruitAPIKey()) + configRules = append(configRules, rules.AdobeClientID()) + configRules = append(configRules, rules.AdobeClientSecret()) + configRules = append(configRules, rules.AgeSecretKey()) + configRules = append(configRules, rules.Airtable()) + configRules = append(configRules, rules.AlgoliaApiKey()) + configRules = append(configRules, rules.AlibabaAccessKey()) + configRules = append(configRules, rules.AlibabaSecretKey()) + configRules = append(configRules, rules.AsanaClientID()) + configRules = append(configRules, rules.AsanaClientSecret()) + configRules = append(configRules, rules.Atlassian()) + configRules = append(configRules, rules.AWS()) + configRules = append(configRules, rules.BitBucketClientID()) + configRules = append(configRules, rules.BitBucketClientSecret()) + configRules = append(configRules, rules.BittrexAccessKey()) + configRules = append(configRules, rules.BittrexSecretKey()) + configRules = append(configRules, rules.Beamer()) + configRules = append(configRules, rules.CodecovAccessToken()) + configRules = append(configRules, rules.CoinbaseAccessToken()) + configRules = append(configRules, rules.Clojars()) + configRules = append(configRules, rules.ConfluentAccessToken()) + configRules = append(configRules, rules.ConfluentSecretKey()) + configRules = append(configRules, rules.Contentful()) + configRules = append(configRules, rules.Databricks()) + configRules = append(configRules, rules.DatadogtokenAccessToken()) + configRules = append(configRules, rules.DigitalOceanPAT()) + configRules = append(configRules, rules.DigitalOceanOAuthToken()) + configRules = append(configRules, rules.DigitalOceanRefreshToken()) + configRules = append(configRules, rules.DiscordAPIToken()) + configRules = append(configRules, rules.DiscordClientID()) + configRules = append(configRules, rules.DiscordClientSecret()) + configRules = append(configRules, rules.Doppler()) + configRules = append(configRules, rules.DropBoxAPISecret()) + configRules = append(configRules, rules.DropBoxLongLivedAPIToken()) + configRules = append(configRules, rules.DropBoxShortLivedAPIToken()) + configRules = append(configRules, rules.DroneciAccessToken()) + configRules = append(configRules, rules.Duffel()) + configRules = append(configRules, rules.Dynatrace()) + configRules = append(configRules, rules.EasyPost()) + configRules = append(configRules, rules.EasyPostTestAPI()) + configRules = append(configRules, rules.EtsyAccessToken()) + configRules = append(configRules, rules.Facebook()) + configRules = append(configRules, rules.FastlyAPIToken()) + configRules = append(configRules, rules.FinicityClientSecret()) + configRules = append(configRules, rules.FinicityAPIToken()) + configRules = append(configRules, rules.FlickrAccessToken()) + configRules = append(configRules, rules.FinnhubAccessToken()) + configRules = append(configRules, rules.FlutterwavePublicKey()) + configRules = append(configRules, rules.FlutterwaveSecretKey()) + configRules = append(configRules, rules.FlutterwaveEncKey()) + configRules = append(configRules, rules.FrameIO()) + configRules = append(configRules, rules.FreshbooksAccessToken()) + configRules = append(configRules, rules.GoCardless()) + // TODO figure out what makes sense for GCP + // configRules = append(configRules, rules.GCPServiceAccount()) + configRules = append(configRules, rules.GCPAPIKey()) + configRules = append(configRules, rules.GitHubPat()) + configRules = append(configRules, rules.GitHubOauth()) + configRules = append(configRules, rules.GitHubApp()) + configRules = append(configRules, rules.GitHubRefresh()) + configRules = append(configRules, rules.Gitlab()) + configRules = append(configRules, rules.GitterAccessToken()) + configRules = append(configRules, rules.GrafanaApiKey()) + configRules = append(configRules, rules.GrafanaCloudApiToken()) + configRules = append(configRules, rules.GrafanaServiceAccountToken()) + configRules = append(configRules, rules.Hashicorp()) + configRules = append(configRules, rules.Heroku()) + configRules = append(configRules, rules.HubSpot()) + configRules = append(configRules, rules.Intercom()) + configRules = append(configRules, rules.JWT()) + configRules = append(configRules, rules.KrakenAccessToken()) + configRules = append(configRules, rules.KucoinAccessToken()) + configRules = append(configRules, rules.KucoinSecretKey()) + configRules = append(configRules, rules.LaunchDarklyAccessToken()) + configRules = append(configRules, rules.LinearAPIToken()) + configRules = append(configRules, rules.LinearClientSecret()) + configRules = append(configRules, rules.LinkedinClientID()) + configRules = append(configRules, rules.LinkedinClientSecret()) + configRules = append(configRules, rules.LobAPIToken()) + configRules = append(configRules, rules.LobPubAPIToken()) + configRules = append(configRules, rules.MailChimp()) + configRules = append(configRules, rules.MailGunPubAPIToken()) + configRules = append(configRules, rules.MailGunPrivateAPIToken()) + configRules = append(configRules, rules.MailGunSigningKey()) + configRules = append(configRules, rules.MapBox()) + configRules = append(configRules, rules.MattermostAccessToken()) + configRules = append(configRules, rules.MessageBirdAPIToken()) + configRules = append(configRules, rules.MessageBirdClientID()) + configRules = append(configRules, rules.NetlifyAccessToken()) + configRules = append(configRules, rules.NewRelicUserID()) + configRules = append(configRules, rules.NewRelicUserKey()) + configRules = append(configRules, rules.NewRelicBrowserAPIKey()) + configRules = append(configRules, rules.NPM()) + configRules = append(configRules, rules.NytimesAccessToken()) + configRules = append(configRules, rules.OktaAccessToken()) + configRules = append(configRules, rules.PlaidAccessID()) + configRules = append(configRules, rules.PlaidSecretKey()) + configRules = append(configRules, rules.PlaidAccessToken()) + configRules = append(configRules, rules.PlanetScalePassword()) + configRules = append(configRules, rules.PlanetScaleAPIToken()) + configRules = append(configRules, rules.PlanetScaleOAuthToken()) + configRules = append(configRules, rules.PostManAPI()) + configRules = append(configRules, rules.Prefect()) + configRules = append(configRules, rules.PrivateKey()) + configRules = append(configRules, rules.PulumiAPIToken()) + configRules = append(configRules, rules.PyPiUploadToken()) + configRules = append(configRules, rules.RapidAPIAccessToken()) + configRules = append(configRules, rules.ReadMe()) + configRules = append(configRules, rules.RubyGemsAPIToken()) + configRules = append(configRules, rules.SendbirdAccessID()) + configRules = append(configRules, rules.SendbirdAccessToken()) + configRules = append(configRules, rules.SendGridAPIToken()) + configRules = append(configRules, rules.SendInBlueAPIToken()) + configRules = append(configRules, rules.SentryAccessToken()) + configRules = append(configRules, rules.ShippoAPIToken()) + configRules = append(configRules, rules.ShopifyAccessToken()) + configRules = append(configRules, rules.ShopifyCustomAccessToken()) + configRules = append(configRules, rules.ShopifyPrivateAppAccessToken()) + configRules = append(configRules, rules.ShopifySharedSecret()) + configRules = append(configRules, rules.SidekiqSecret()) + configRules = append(configRules, rules.SidekiqSensitiveUrl()) + configRules = append(configRules, rules.SlackAccessToken()) + configRules = append(configRules, rules.SlackWebHook()) + configRules = append(configRules, rules.StripeAccessToken()) + configRules = append(configRules, rules.SquareAccessToken()) + configRules = append(configRules, rules.SquareSpaceAccessToken()) + configRules = append(configRules, rules.SumoLogicAccessID()) + configRules = append(configRules, rules.SumoLogicAccessToken()) + configRules = append(configRules, rules.TeamsWebhook()) + configRules = append(configRules, rules.TelegramBotToken()) + configRules = append(configRules, rules.TravisCIAccessToken()) + configRules = append(configRules, rules.Twilio()) + configRules = append(configRules, rules.TwitchAPIToken()) + configRules = append(configRules, rules.TwitterAPIKey()) + configRules = append(configRules, rules.TwitterAPISecret()) + configRules = append(configRules, rules.TwitterAccessToken()) + configRules = append(configRules, rules.TwitterAccessSecret()) + configRules = append(configRules, rules.TwitterBearerToken()) + configRules = append(configRules, rules.Typeform()) + configRules = append(configRules, rules.VaultBatchToken()) + configRules = append(configRules, rules.VaultServiceToken()) + configRules = append(configRules, rules.YandexAPIKey()) + configRules = append(configRules, rules.YandexAWSAccessToken()) + configRules = append(configRules, rules.YandexAccessToken()) + configRules = append(configRules, rules.ZendeskSecretKey()) + configRules = append(configRules, rules.GenericCredential()) + + // ensure rules have unique ids + ruleLookUp := make(map[string]config.Rule) + for _, rule := range configRules { + // check if rule is in ruleLookUp + if _, ok := ruleLookUp[rule.RuleID]; ok { + log.Fatal().Msgf("rule id %s is not unique", rule.RuleID) + } + // TODO: eventually change all the signatures to get ride of this + // nasty dereferencing. + ruleLookUp[rule.RuleID] = *rule + } + + tmpl, err := template.ParseFiles(templatePath) + if err != nil { + log.Fatal().Err(err).Msg("Failed to parse template") + } + + f, err := os.Create("../../../config/gitleaks.toml") + if err != nil { + log.Fatal().Err(err).Msg("Failed to create rules.toml") + } + + if err = tmpl.Execute(f, config.Config{Rules: ruleLookUp}); err != nil { + log.Fatal().Err(err).Msg("could not execute template") + } + +} diff --git a/cmd/generate/config/rules/adafruit.go b/cmd/generate/config/rules/adafruit.go new file mode 100644 index 000000000..3889e6c62 --- /dev/null +++ b/cmd/generate/config/rules/adafruit.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AdafruitAPIKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adafruit API Key", + RuleID: "adafruit-api-key", + Regex: generateSemiGenericRegex([]string{"adafruit"}, alphaNumericExtendedShort("32")), + SecretGroup: 1, + Keywords: []string{"adafruit"}, + } + + // validate + tps := []string{ + generateSampleSecret("adafruit", secrets.NewSecret(alphaNumericExtendedShort("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/adobe.go b/cmd/generate/config/rules/adobe.go new file mode 100644 index 000000000..c0e9999f1 --- /dev/null +++ b/cmd/generate/config/rules/adobe.go @@ -0,0 +1,39 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AdobeClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adobe Client ID (OAuth Web)", + RuleID: "adobe-client-id", + Regex: generateSemiGenericRegex([]string{"adobe"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"adobe"}, + } + + // validate + tps := []string{ + generateSampleSecret("adobe", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func AdobeClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adobe Client Secret", + RuleID: "adobe-client-secret", + Regex: generateUniqueTokenRegex(`(p8e-)(?i)[a-z0-9]{32}`), + Keywords: []string{"p8e-"}, + } + + // validate + tps := []string{ + "adobeClient := \"p8e-" + secrets.NewSecret(hex("32")) + "\"", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/age.go b/cmd/generate/config/rules/age.go new file mode 100644 index 000000000..ccc0ca2e8 --- /dev/null +++ b/cmd/generate/config/rules/age.go @@ -0,0 +1,23 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func AgeSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Age secret key", + RuleID: "age secret key", + Regex: regexp.MustCompile(`AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}`), + Keywords: []string{"AGE-SECRET-KEY-1"}, + } + + // validate + tps := []string{ + `apiKey := "AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/airtable.go b/cmd/generate/config/rules/airtable.go new file mode 100644 index 000000000..ab31f88d7 --- /dev/null +++ b/cmd/generate/config/rules/airtable.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Airtable() *config.Rule { + // define rule + r := config.Rule{ + Description: "Airtable API Key", + RuleID: "airtable-api-key", + Regex: generateSemiGenericRegex([]string{"airtable"}, alphaNumeric("17")), + SecretGroup: 1, + Keywords: []string{"airtable"}, + } + + // validate + tps := []string{ + generateSampleSecret("airtable", secrets.NewSecret(alphaNumeric("17"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/algolia.go b/cmd/generate/config/rules/algolia.go new file mode 100644 index 000000000..4e3e30aff --- /dev/null +++ b/cmd/generate/config/rules/algolia.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AlgoliaApiKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Algolia API Key", + RuleID: "algolia-api-key", + Regex: generateSemiGenericRegex([]string{"algolia"}, `[a-z0-9]{32}`), + Keywords: []string{"algolia"}, + } + + // validate + tps := []string{ + "algolia_key := " + secrets.NewSecret(hex("32")), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/alibaba.go b/cmd/generate/config/rules/alibaba.go new file mode 100644 index 000000000..6f7085b59 --- /dev/null +++ b/cmd/generate/config/rules/alibaba.go @@ -0,0 +1,41 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AlibabaAccessKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Alibaba AccessKey ID", + RuleID: "alibaba-access-key-id", + Regex: generateUniqueTokenRegex(`(LTAI)(?i)[a-z0-9]{20}`), + Keywords: []string{"LTAI"}, + } + + // validate + tps := []string{ + "alibabaKey := \"LTAI" + secrets.NewSecret(hex("20")) + "\"", + } + return validate(r, tps, nil) +} + +// TODO +func AlibabaSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Alibaba Secret Key", + RuleID: "alibaba-secret-key", + Regex: generateSemiGenericRegex([]string{"alibaba"}, + alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{"alibaba"}, + } + + // validate + tps := []string{ + generateSampleSecret("alibaba", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/asana.go b/cmd/generate/config/rules/asana.go new file mode 100644 index 000000000..888bc6574 --- /dev/null +++ b/cmd/generate/config/rules/asana.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AsanaClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Asana Client ID", + RuleID: "asana-client-id", + Regex: generateSemiGenericRegex([]string{"asana"}, numeric("16")), + SecretGroup: 1, + Keywords: []string{"asana"}, + } + + // validate + tps := []string{ + generateSampleSecret("asana", secrets.NewSecret(numeric("16"))), + } + return validate(r, tps, nil) +} + +func AsanaClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Asana Client Secret", + RuleID: "asana-client-secret", + Regex: generateSemiGenericRegex([]string{"asana"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"asana"}, + } + + // validate + tps := []string{ + generateSampleSecret("asana", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/atlassian.go b/cmd/generate/config/rules/atlassian.go new file mode 100644 index 000000000..2da4f08df --- /dev/null +++ b/cmd/generate/config/rules/atlassian.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Atlassian() *config.Rule { + // define rule + r := config.Rule{ + Description: "Atlassian API token", + RuleID: "atlassian-api-token", + Regex: generateSemiGenericRegex([]string{ + "atlassian", "confluence", "jira"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{"atlassian", "confluence", "jira"}, + } + + // validate + tps := []string{ + generateSampleSecret("atlassian", secrets.NewSecret(alphaNumeric("24"))), + generateSampleSecret("confluence", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/aws.go b/cmd/generate/config/rules/aws.go new file mode 100644 index 000000000..a0339b741 --- /dev/null +++ b/cmd/generate/config/rules/aws.go @@ -0,0 +1,31 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func AWS() *config.Rule { + // define rule + r := config.Rule{ + Description: "AWS", + RuleID: "aws-access-token", + Regex: regexp.MustCompile( + "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Keywords: []string{ + "AKIA", + "AGPA", + "AIDA", + "AROA", + "AIPA", + "ANPA", + "ANVA", + "ASIA", + }, + } + + // validate + tps := []string{generateSampleSecret("AWS", "AKIALALEMEL33243OLIB")} // gitleaks:allow + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/beamer.go b/cmd/generate/config/rules/beamer.go new file mode 100644 index 000000000..a44239419 --- /dev/null +++ b/cmd/generate/config/rules/beamer.go @@ -0,0 +1,24 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Beamer() *config.Rule { + // define rule + r := config.Rule{ + Description: "Beamer API token", + RuleID: "beamer-api-token", + SecretGroup: 1, + Regex: generateSemiGenericRegex([]string{"beamer"}, + `b_[a-z0-9=_\-]{44}`), + Keywords: []string{"beamer"}, + } + + // validate + tps := []string{ + generateSampleSecret("beamer", "b_"+secrets.NewSecret(alphaNumericExtended("44"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/bitbucket.go b/cmd/generate/config/rules/bitbucket.go new file mode 100644 index 000000000..fe3a05298 --- /dev/null +++ b/cmd/generate/config/rules/bitbucket.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func BitBucketClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bitbucket Client ID", + RuleID: "bitbucket-client-id", + Regex: generateSemiGenericRegex([]string{"bitbucket"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bitbucket"}, + } + + // validate + tps := []string{ + generateSampleSecret("bitbucket", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func BitBucketClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bitbucket Client Secret", + RuleID: "bitbucket-client-secret", + Regex: generateSemiGenericRegex([]string{"bitbucket"}, alphaNumericExtended("64")), + SecretGroup: 1, + Keywords: []string{"bitbucket"}, + } + + // validate + tps := []string{ + generateSampleSecret("bitbucket", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/bittrex.go b/cmd/generate/config/rules/bittrex.go new file mode 100644 index 000000000..ccb9705ff --- /dev/null +++ b/cmd/generate/config/rules/bittrex.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func BittrexAccessKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bittrex Access Key", + RuleID: "bittrex-access-key", + Regex: generateSemiGenericRegex([]string{"bittrex"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bittrex"}, + } + + // validate + tps := []string{ + generateSampleSecret("bittrex", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func BittrexSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bittrex Secret Key", + RuleID: "bittrex-secret-key", + Regex: generateSemiGenericRegex([]string{"bittrex"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bittrex"}, + } + + // validate + tps := []string{ + generateSampleSecret("bittrex", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/clojars.go b/cmd/generate/config/rules/clojars.go new file mode 100644 index 000000000..b7309c64b --- /dev/null +++ b/cmd/generate/config/rules/clojars.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Clojars() *config.Rule { + // define rule + r := config.Rule{ + Description: "Clojars API token", + RuleID: "clojars-api-token", + Regex: regexp.MustCompile(`(?i)(CLOJARS_)[a-z0-9]{60}`), + Keywords: []string{"clojars"}, + } + + // validate + tps := []string{ + generateSampleSecret("clojars", "CLOJARS_"+secrets.NewSecret(alphaNumeric("60"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/codecov.go b/cmd/generate/config/rules/codecov.go new file mode 100644 index 000000000..6b1b886b4 --- /dev/null +++ b/cmd/generate/config/rules/codecov.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func CodecovAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "codecov-access-token", + Description: "Codecov Access Token", + Regex: generateSemiGenericRegex([]string{"codecov"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "codecov", + }, + } + + // validate + tps := []string{ + generateSampleSecret("codecov", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/coinbase.go b/cmd/generate/config/rules/coinbase.go new file mode 100644 index 000000000..c5598c2ad --- /dev/null +++ b/cmd/generate/config/rules/coinbase.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func CoinbaseAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "coinbase-access-token", + Description: "Coinbase Access Token", + Regex: generateSemiGenericRegex([]string{"coinbase"}, + alphaNumericExtendedShort("64")), + SecretGroup: 1, + Keywords: []string{ + "coinbase", + }, + } + + // validate + tps := []string{ + generateSampleSecret("coinbase", + secrets.NewSecret(alphaNumericExtendedShort("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/config.tmpl b/cmd/generate/config/rules/config.tmpl new file mode 100644 index 000000000..25c2ce66e --- /dev/null +++ b/cmd/generate/config/rules/config.tmpl @@ -0,0 +1,60 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md + +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''', + '''node_modules''', + '''vendor''', +] + +{{ range $i, $rule := .Rules }}[[rules]] +{{ if and $rule.SecretGroup $rule.Entropy $rule.Allowlist.StopWords }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +entropy = {{ $rule.Entropy}} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] +[rules.allowlist] +stopwords= [{{ range $j, $stopword := $rule.Allowlist.StopWords }} + "{{$stopword}}",{{end}} +] +{{ else if and $rule.SecretGroup $rule.Entropy }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +entropy = {{ $rule.Entropy}} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{ else if $rule.SecretGroup }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{ else }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{end}}{{end}} \ No newline at end of file diff --git a/cmd/generate/config/rules/confluent.go b/cmd/generate/config/rules/confluent.go new file mode 100644 index 000000000..a6d0c99a6 --- /dev/null +++ b/cmd/generate/config/rules/confluent.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ConfluentSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "confluent-secret-key", + Description: "Confluent Secret Key", + Regex: generateSemiGenericRegex([]string{"confluent"}, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "confluent", + }, + } + + // validate + tps := []string{ + generateSampleSecret("confluent", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} + +func ConfluentAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "confluent-access-token", + Description: "Confluent Access Token", + Regex: generateSemiGenericRegex([]string{"confluent"}, alphaNumeric("16")), + SecretGroup: 1, + Keywords: []string{ + "confluent", + }, + } + + // validate + tps := []string{ + generateSampleSecret("confluent", secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/contentful.go b/cmd/generate/config/rules/contentful.go new file mode 100644 index 000000000..fbf44cd15 --- /dev/null +++ b/cmd/generate/config/rules/contentful.go @@ -0,0 +1,24 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Contentful() *config.Rule { + // define rule + r := config.Rule{ + Description: "Contentful delivery API token", + RuleID: "contentful-delivery-api-token", + Regex: generateSemiGenericRegex([]string{"contentful"}, + alphaNumericExtended("43")), + SecretGroup: 1, + Keywords: []string{"contentful"}, + } + + // validate + tps := []string{ + generateSampleSecret("contentful", secrets.NewSecret(alphaNumeric("43"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/databricks.go b/cmd/generate/config/rules/databricks.go new file mode 100644 index 000000000..d7cd19d5b --- /dev/null +++ b/cmd/generate/config/rules/databricks.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Databricks() *config.Rule { + // define rule + r := config.Rule{ + Description: "Databricks API token", + RuleID: "databricks-api-token", + Regex: generateUniqueTokenRegex(`dapi[a-h0-9]{32}`), + Keywords: []string{"dapi"}, + } + + // validate + tps := []string{ + generateSampleSecret("databricks", "dapi"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/datadog.go b/cmd/generate/config/rules/datadog.go new file mode 100644 index 000000000..a39b918f2 --- /dev/null +++ b/cmd/generate/config/rules/datadog.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DatadogtokenAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "datadog-access-token", + Description: "Datadog Access Token", + Regex: generateSemiGenericRegex([]string{"datadog"}, + alphaNumeric("40")), + SecretGroup: 1, + Keywords: []string{ + "datadog", + }, + } + + // validate + tps := []string{ + generateSampleSecret("datadog", secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/digitalocean.go b/cmd/generate/config/rules/digitalocean.go new file mode 100644 index 000000000..623dcff87 --- /dev/null +++ b/cmd/generate/config/rules/digitalocean.go @@ -0,0 +1,51 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DigitalOceanPAT() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean Personal Access Token", + RuleID: "digitalocean-pat", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`dop_v1_[a-f0-9]{64}`), + Keywords: []string{"dop_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "dop_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DigitalOceanOAuthToken() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean OAuth Access Token", + RuleID: "digitalocean-access-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`doo_v1_[a-f0-9]{64}`), + Keywords: []string{"doo_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "doo_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DigitalOceanRefreshToken() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean OAuth Refresh Token", + RuleID: "digitalocean-refresh-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`dor_v1_[a-f0-9]{64}`), + Keywords: []string{"dor_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "dor_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/discord.go b/cmd/generate/config/rules/discord.go new file mode 100644 index 000000000..4d1f13602 --- /dev/null +++ b/cmd/generate/config/rules/discord.go @@ -0,0 +1,57 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DiscordAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord API key", + RuleID: "discord-api-token", + Regex: generateSemiGenericRegex([]string{"discord"}, hex("64")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DiscordClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord client ID", + RuleID: "discord-client-id", + Regex: generateSemiGenericRegex([]string{"discord"}, numeric("18")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(numeric("18"))), + } + return validate(r, tps, nil) +} + +func DiscordClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord client secret", + RuleID: "discord-client-secret", + Regex: generateSemiGenericRegex([]string{"discord"}, alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(numeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/doppler.go b/cmd/generate/config/rules/doppler.go new file mode 100644 index 000000000..b94f2e86c --- /dev/null +++ b/cmd/generate/config/rules/doppler.go @@ -0,0 +1,27 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Doppler() *config.Rule { + // define rule + r := config.Rule{ + Description: "Doppler API token", + RuleID: "doppler-api-token", + Regex: regexp.MustCompile(`(dp\.pt\.)(?i)[a-z0-9]{43}`), + Keywords: []string{"doppler"}, + } + + // validate + tps := []string{ + generateSampleSecret("doppler", "dp.pt."+secrets.NewSecret(alphaNumeric("43"))), + } + return validate(r, tps, nil) +} + +// TODO add additional doppler formats: +// https://docs.doppler.com/reference/auth-token-formats diff --git a/cmd/generate/config/rules/droneci.go b/cmd/generate/config/rules/droneci.go new file mode 100644 index 000000000..03888d523 --- /dev/null +++ b/cmd/generate/config/rules/droneci.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DroneciAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "droneci-access-token", + Description: "Droneci Access Token", + Regex: generateSemiGenericRegex([]string{"droneci"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "droneci", + }, + } + + // validate + tps := []string{ + generateSampleSecret("droneci", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/dropbox.go b/cmd/generate/config/rules/dropbox.go new file mode 100644 index 000000000..375cc2fb6 --- /dev/null +++ b/cmd/generate/config/rules/dropbox.go @@ -0,0 +1,49 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DropBoxAPISecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Dropbox API secret", + RuleID: "dropbox-api-token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, alphaNumeric("15")), + SecretGroup: 1, + Keywords: []string{"dropbox"}, + } + + // validate + tps := []string{ + generateSampleSecret("dropbox", secrets.NewSecret(alphaNumeric("15"))), + } + return validate(r, tps, nil) +} + +func DropBoxShortLivedAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "dropbox-short-lived-api-token", + Description: "Dropbox short lived API token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, `sl\.[a-z0-9\-=_]{135}`), + Keywords: []string{"dropbox"}, + } + + // validate TODO + return &r +} + +func DropBoxLongLivedAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "dropbox-long-lived-api-token", + Description: "Dropbox long lived API token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, `[a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43}`), + Keywords: []string{"dropbox"}, + } + + // validate TODO + return &r +} diff --git a/cmd/generate/config/rules/duffel.go b/cmd/generate/config/rules/duffel.go new file mode 100644 index 000000000..5d5b428d2 --- /dev/null +++ b/cmd/generate/config/rules/duffel.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Duffel() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "duffel-api-token", + Description: "Duffel API token", + Regex: regexp.MustCompile(`duffel_(test|live)_(?i)[a-z0-9_\-=]{43}`), + Keywords: []string{"duffel"}, + } + + // validate + tps := []string{ + generateSampleSecret("duffel", "duffel_test_"+secrets.NewSecret(alphaNumericExtended("43"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/dynatrace.go b/cmd/generate/config/rules/dynatrace.go new file mode 100644 index 000000000..95b985152 --- /dev/null +++ b/cmd/generate/config/rules/dynatrace.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Dynatrace() *config.Rule { + // define rule + r := config.Rule{ + Description: "Dynatrace API token", + RuleID: "dynatrace-api-token", + Regex: regexp.MustCompile(`dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}`), + Keywords: []string{"dynatrace"}, + } + + // validate + tps := []string{ + generateSampleSecret("dynatrace", "dt0c01."+secrets.NewSecret(alphaNumeric("24"))+"."+secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/easypost.go b/cmd/generate/config/rules/easypost.go new file mode 100644 index 000000000..b2a3ace0f --- /dev/null +++ b/cmd/generate/config/rules/easypost.go @@ -0,0 +1,40 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func EasyPost() *config.Rule { + // define rule + r := config.Rule{ + Description: "EasyPost API token", + RuleID: "easypost-api-token", + Regex: regexp.MustCompile(`EZAK(?i)[a-z0-9]{54}`), + Keywords: []string{"EZAK"}, + } + + // validate + tps := []string{ + generateSampleSecret("EZAK", "EZAK"+secrets.NewSecret(alphaNumeric("54"))), + } + return validate(r, tps, nil) +} + +func EasyPostTestAPI() *config.Rule { + // define rule + r := config.Rule{ + Description: "EasyPost test API token", + RuleID: "easypost-test-api-token", + Regex: regexp.MustCompile(`EZTK(?i)[a-z0-9]{54}`), + Keywords: []string{"EZTK"}, + } + + // validate + tps := []string{ + generateSampleSecret("EZTK", "EZTK"+secrets.NewSecret(alphaNumeric("54"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/etsy.go b/cmd/generate/config/rules/etsy.go new file mode 100644 index 000000000..926308f5a --- /dev/null +++ b/cmd/generate/config/rules/etsy.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func EtsyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "etsy-access-token", + Description: "Etsy Access Token", + Regex: generateSemiGenericRegex([]string{"etsy"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{ + "etsy", + }, + } + + // validate + tps := []string{ + generateSampleSecret("etsy", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/facebook.go b/cmd/generate/config/rules/facebook.go new file mode 100644 index 000000000..d614e8e61 --- /dev/null +++ b/cmd/generate/config/rules/facebook.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Facebook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Facebook", + RuleID: "facebook", + Regex: generateSemiGenericRegex([]string{"facebook"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"facebook"}, + } + + // validate + tps := []string{ + generateSampleSecret("facebook", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/fastly.go b/cmd/generate/config/rules/fastly.go new file mode 100644 index 000000000..58a8db4ed --- /dev/null +++ b/cmd/generate/config/rules/fastly.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FastlyAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Fastly API key", + RuleID: "fastly-api-token", + Regex: generateSemiGenericRegex([]string{"fastly"}, alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{"fastly"}, + } + + // validate + tps := []string{ + generateSampleSecret("fastly", secrets.NewSecret(alphaNumericExtended("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/finicity.go b/cmd/generate/config/rules/finicity.go new file mode 100644 index 000000000..f85404875 --- /dev/null +++ b/cmd/generate/config/rules/finicity.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FinicityClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity Client Secret", + RuleID: "finicity-client-secret", + Regex: generateSemiGenericRegex([]string{"finicity"}, alphaNumeric("20")), + SecretGroup: 1, + Keywords: []string{"finicity"}, + } + + // validate + tps := []string{ + generateSampleSecret("finicity", secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} + +func FinicityAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity API token", + RuleID: "finicity-api-token", + Regex: generateSemiGenericRegex([]string{"finicity"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"finicity"}, + } + + // validate + tps := []string{ + generateSampleSecret("finicity", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/finnhub.go b/cmd/generate/config/rules/finnhub.go new file mode 100644 index 000000000..61bf9129c --- /dev/null +++ b/cmd/generate/config/rules/finnhub.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FinnhubAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "finnhub-access-token", + Description: "Finnhub Access Token", + Regex: generateSemiGenericRegex([]string{"finnhub"}, alphaNumeric("20")), + SecretGroup: 1, + Keywords: []string{ + "finnhub", + }, + } + + // validate + tps := []string{ + generateSampleSecret("finnhub", secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/flickr.go b/cmd/generate/config/rules/flickr.go new file mode 100644 index 000000000..8d478e492 --- /dev/null +++ b/cmd/generate/config/rules/flickr.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FlickrAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "flickr-access-token", + Description: "Flickr Access Token", + Regex: generateSemiGenericRegex([]string{"flickr"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "flickr", + }, + } + + // validate + tps := []string{ + generateSampleSecret("flickr", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/flutterwave.go b/cmd/generate/config/rules/flutterwave.go new file mode 100644 index 000000000..98b9cffb1 --- /dev/null +++ b/cmd/generate/config/rules/flutterwave.go @@ -0,0 +1,56 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FlutterwavePublicKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity Public Key", + RuleID: "flutterwave-public-key", + Regex: regexp.MustCompile(`FLWPUBK_TEST-(?i)[a-h0-9]{32}-X`), + Keywords: []string{"FLWPUBK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWPUBK_TEST-"+secrets.NewSecret(hex("32"))+"-X"), + } + return validate(r, tps, nil) +} + +func FlutterwaveSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Flutterwave Secret Key", + RuleID: "flutterwave-secret-key", + Regex: regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{32}-X`), + Keywords: []string{"FLWSECK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+secrets.NewSecret(hex("32"))+"-X"), + } + return validate(r, tps, nil) +} + +func FlutterwaveEncKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Flutterwave Encryption Key", + RuleID: "flutterwave-encryption-key", + Regex: regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{12}`), + Keywords: []string{"FLWSECK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+secrets.NewSecret(hex("12"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/frameio.go b/cmd/generate/config/rules/frameio.go new file mode 100644 index 000000000..ecfa3673f --- /dev/null +++ b/cmd/generate/config/rules/frameio.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FrameIO() *config.Rule { + // define rule + r := config.Rule{ + Description: "Frame.io API token", + RuleID: "frameio-api-token", + Regex: regexp.MustCompile(`fio-u-(?i)[a-z0-9\-_=]{64}`), + Keywords: []string{"fio-u-"}, + } + + // validate + tps := []string{ + generateSampleSecret("frameio", "fio-u-"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/freshbooks.go b/cmd/generate/config/rules/freshbooks.go new file mode 100644 index 000000000..9cb36225f --- /dev/null +++ b/cmd/generate/config/rules/freshbooks.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FreshbooksAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "freshbooks-access-token", + Description: "Freshbooks Access Token", + Regex: generateSemiGenericRegex([]string{"freshbooks"}, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "freshbooks", + }, + } + + // validate + tps := []string{ + generateSampleSecret("freshbooks", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gcp.go b/cmd/generate/config/rules/gcp.go new file mode 100644 index 000000000..cedd5e896 --- /dev/null +++ b/cmd/generate/config/rules/gcp.go @@ -0,0 +1,44 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +// TODO this one could probably use some work +func GCPServiceAccount() *config.Rule { + // define rule + r := config.Rule{ + Description: "Google (GCP) Service-account", + RuleID: "gcp-service-account", + Regex: regexp.MustCompile(`\"type\": \"service_account\"`), + Keywords: []string{`\"type\": \"service_account\"`}, + } + + // validate + tps := []string{ + `"type": "service_account"`, + } + return validate(r, tps, nil) +} + +func GCPAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gcp-api-key", + Description: "GCP API key", + Regex: generateUniqueTokenRegex(`AIza[0-9A-Za-z\\-_]{35}`), + SecretGroup: 1, + Keywords: []string{ + "AIza", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gcp", secrets.NewSecret(`AIza[0-9A-Za-z\\-_]{35}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/generic.go b/cmd/generate/config/rules/generic.go new file mode 100644 index 000000000..9cf8e7ad7 --- /dev/null +++ b/cmd/generate/config/rules/generic.go @@ -0,0 +1,55 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func GenericCredential() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "generic-api-key", + Description: "Generic API Key", + Regex: generateSemiGenericRegex([]string{ + "key", + "api", + "token", + "secret", + "client", + "passwd", + "password", + "auth", + "access", + }, `[0-9a-z\-_.=]{10,150}`), + SecretGroup: 1, + Keywords: []string{ + "key", + "api", + "token", + "secret", + "client", + "passwd", + "password", + "auth", + "access", + }, + Entropy: 3.5, + Allowlist: config.Allowlist{ + StopWords: DefaultStopWords, + }, + } + + // validate + tps := []string{ + generateSampleSecret("generic", "CLOJARS_34bf0e88955ff5a1c328d6a7491acc4f48e865a7b8dd4d70a70749037443"), + generateSampleSecret("generic", "Zf3D0LXCM3EIMbgJpUNnkRtOfOueHznB"), + `"client_id" : "0afae57f3ccfd9d7f5767067bc48b30f719e271ba470488056e37ab35d4b6506"`, + `"client_secret" : "6da89121079f83b2eb6acccf8219ea982c3d79bccc3e9c6a85856480661f8fde",`, + } + fps := []string{ + `client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.client-vpn-endpoint.id`, + `password combination. + +R5: Regulatory--21`, + } + return validate(r, tps, fps) +} diff --git a/cmd/generate/config/rules/github.go b/cmd/generate/config/rules/github.go new file mode 100644 index 000000000..5cc404359 --- /dev/null +++ b/cmd/generate/config/rules/github.go @@ -0,0 +1,73 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GitHubPat() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub Personal Access Token", + RuleID: "github-pat", + Regex: regexp.MustCompile(`ghp_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghp_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghp_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubOauth() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub OAuth Access Token", + RuleID: "github-oauth", + Regex: regexp.MustCompile(`gho_[0-9a-zA-Z]{36}`), + Keywords: []string{"gho_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "gho_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubApp() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub App Token", + RuleID: "github-app-token", + Regex: regexp.MustCompile(`(ghu|ghs)_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghu_", "ghs_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghu_"+secrets.NewSecret(alphaNumeric("36"))), + generateSampleSecret("github", "ghs_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubRefresh() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub Refresh Token", + RuleID: "github-refresh-token", + Regex: regexp.MustCompile(`ghr_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghr_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghr_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gitlab.go b/cmd/generate/config/rules/gitlab.go new file mode 100644 index 000000000..623b48192 --- /dev/null +++ b/cmd/generate/config/rules/gitlab.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Gitlab() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitLab Personal Access Token", + RuleID: "gitlab-pat", + Regex: regexp.MustCompile(`glpat-[0-9a-zA-Z\-\_]{20}`), + Keywords: []string{"glpat-"}, + } + + // validate + tps := []string{ + generateSampleSecret("gitlab", "glpat-"+secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gitter.go b/cmd/generate/config/rules/gitter.go new file mode 100644 index 000000000..072a8d713 --- /dev/null +++ b/cmd/generate/config/rules/gitter.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GitterAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gitter-access-token", + Description: "Gitter Access Token", + Regex: generateSemiGenericRegex([]string{"gitter"}, + alphaNumericExtendedShort("40")), + SecretGroup: 1, + Keywords: []string{ + "gitter", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gitter", + secrets.NewSecret(alphaNumericExtendedShort("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gocardless.go b/cmd/generate/config/rules/gocardless.go new file mode 100644 index 000000000..7e1203e79 --- /dev/null +++ b/cmd/generate/config/rules/gocardless.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GoCardless() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gocardless-api-token", + Description: "GoCardless API token", + Regex: generateSemiGenericRegex([]string{"gocardless"}, `live_(?i)[a-z0-9\-_=]{40}`), + SecretGroup: 1, + Keywords: []string{ + "live_", + "gocardless", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gocardless", "live_"+secrets.NewSecret(alphaNumericExtended("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/grafana.go b/cmd/generate/config/rules/grafana.go new file mode 100644 index 000000000..302847e6c --- /dev/null +++ b/cmd/generate/config/rules/grafana.go @@ -0,0 +1,65 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GrafanaApiKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana api key (or Grafana cloud api key)", + RuleID: "grafana-api-key", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`eyJrIjoi[A-Za-z0-9]{70,400}={0,2}`), + Keywords: []string{"eyJrIjoi"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-api-key", + "eyJrIjoi"+ + secrets.NewSecret(alphaNumeric("70"))), + } + return validate(r, tps, nil) +} + +func GrafanaCloudApiToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana cloud api token", + RuleID: "grafana-cloud-api-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`glc_[A-Za-z0-9+/]{32,400}={0,2}`), + Keywords: []string{"glc_"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-cloud-api-token", + "glc_"+ + secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func GrafanaServiceAccountToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana service account token", + RuleID: "grafana-service-account-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8}`), + Keywords: []string{"glsa_"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-service-account-token", + "glsa_"+ + secrets.NewSecret(alphaNumeric("32"))+ + "_"+ + secrets.NewSecret((hex("8")))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/hashicorp.go b/cmd/generate/config/rules/hashicorp.go new file mode 100644 index 000000000..ce883b4ac --- /dev/null +++ b/cmd/generate/config/rules/hashicorp.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Hashicorp() *config.Rule { + // define rule + r := config.Rule{ + Description: "HashiCorp Terraform user/org API token", + RuleID: "hashicorp-tf-api-token", + Regex: regexp.MustCompile(`(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}`), + Keywords: []string{"atlasv1"}, + } + + // validate + tps := []string{ + generateSampleSecret("hashicorpToken", secrets.NewSecret(hex("14"))+".atlasv1."+secrets.NewSecret(alphaNumericExtended("60,70"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/heroku.go b/cmd/generate/config/rules/heroku.go new file mode 100644 index 000000000..599a04c52 --- /dev/null +++ b/cmd/generate/config/rules/heroku.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func Heroku() *config.Rule { + // define rule + r := config.Rule{ + Description: "Heroku API Key", + RuleID: "heroku-api-key", + Regex: generateSemiGenericRegex([]string{"heroku"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{"heroku"}, + } + + // validate + tps := []string{ + `const HEROKU_KEY = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/hubspot.go b/cmd/generate/config/rules/hubspot.go new file mode 100644 index 000000000..746284c21 --- /dev/null +++ b/cmd/generate/config/rules/hubspot.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func HubSpot() *config.Rule { + // define rule + r := config.Rule{ + Description: "HubSpot API Token", + RuleID: "hubspot-api-key", + Regex: generateSemiGenericRegex([]string{"hubspot"}, + `[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}`), + SecretGroup: 1, + Keywords: []string{"hubspot"}, + } + + // validate + tps := []string{ + `const hubspotKey = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/intercom.go b/cmd/generate/config/rules/intercom.go new file mode 100644 index 000000000..edb2bbd4a --- /dev/null +++ b/cmd/generate/config/rules/intercom.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Intercom() *config.Rule { + // define rule + r := config.Rule{ + Description: "Intercom API Token", + RuleID: "intercom-api-key", + Regex: generateSemiGenericRegex([]string{"intercom"}, alphaNumericExtended("60")), + SecretGroup: 1, + Keywords: []string{"intercom"}, + } + + // validate + tps := []string{ + generateSampleSecret("intercom", secrets.NewSecret(alphaNumericExtended("60"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/jwt.go b/cmd/generate/config/rules/jwt.go new file mode 100644 index 000000000..4d36d64d3 --- /dev/null +++ b/cmd/generate/config/rules/jwt.go @@ -0,0 +1,21 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func JWT() *config.Rule { + // define rule + r := config.Rule{ + Description: "JSON Web Token", + RuleID: "jwt", + Regex: generateUniqueTokenRegex(`ey[0-9a-z]{30,34}\.ey[0-9a-z-\/_]{30,500}\.[0-9a-zA-Z-\/_]{10,200}`), + Keywords: []string{"ey"}, + } + + // validate + tps := []string{`eyJhbGciOieeeiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwic3ViZSI6IjEyMzQ1Njc4OTAiLCJuYW1lZWEiOiJKb2huIERvZSIsInN1ZmV3YWZiIjoiMTIzNDU2Nzg5MCIsIm5hbWVmZWF3ZnciOiJKb2huIERvZSIsIm5hbWVhZmV3ZmEiOiJKb2huIERvZSIsInN1ZndhZndlYWIiOiIxMjM0NTY3ODkwIiwibmFtZWZ3YWYiOiJKb2huIERvZSIsInN1YmZ3YWYiOiIxMjM0NTY3ODkwIiwibmFtZndhZSI6IkpvaG4gRG9lIiwiaWZ3YWZhYXQiOjE1MTYyMzkwMjJ9.a_5icKBDo-8EjUlrfvz2k2k-FYaindQ0DEYNrlsnRG0`, // gitleaks:allow + `JWT := eyJhbGciOieeeiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwic3ViZSI6IjEyMzQ1Njc4OTAiLCJuYW1lZWEiOiJKb2huIERvZSIsInN1ZmV3YWZiIjoiMTIzNDU2Nzg5MCIsIm5hbWVmZWF3ZnciOiJKb2huIERvZSIsIm5hbWVhZmV3ZmEiOiJKb2huIERvZSIsInN1ZndhZndlYWIiOiIxMjM0NTY3ODkwIiwibmFtZWZ3YWYiOiJKb2huIERvZSIsInN1YmZ3YWYiOiIxMjM0NTY3ODkwIiwibmFtZndhZSI6IkpvaG4gRG9lIiwiaWZ3YWZhYXQiOjE1MTYyMzkwMjJ9.a_5icKBDo-8EjUlrfvz2k2k-FYaindQ0DEYNrlsnRG0`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/kraken.go b/cmd/generate/config/rules/kraken.go new file mode 100644 index 000000000..dafabe1d0 --- /dev/null +++ b/cmd/generate/config/rules/kraken.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func KrakenAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kraken-access-token", + Description: "Kraken Access Token", + Regex: generateSemiGenericRegex([]string{"kraken"}, + alphaNumericExtendedLong("80,90")), + SecretGroup: 1, + Keywords: []string{ + "kraken", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kraken", + secrets.NewSecret(alphaNumericExtendedLong("80,90"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/kucoin.go b/cmd/generate/config/rules/kucoin.go new file mode 100644 index 000000000..fd1c39135 --- /dev/null +++ b/cmd/generate/config/rules/kucoin.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func KucoinAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kucoin-access-token", + Description: "Kucoin Access Token", + Regex: generateSemiGenericRegex([]string{"kucoin"}, hex("24")), + SecretGroup: 1, + Keywords: []string{ + "kucoin", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kucoin", secrets.NewSecret(hex("24"))), + } + return validate(r, tps, nil) +} + +func KucoinSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kucoin-secret-key", + Description: "Kucoin Secret Key", + Regex: generateSemiGenericRegex([]string{"kucoin"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "kucoin", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kucoin", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/launchdarkly.go b/cmd/generate/config/rules/launchdarkly.go new file mode 100644 index 000000000..84814c366 --- /dev/null +++ b/cmd/generate/config/rules/launchdarkly.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LaunchDarklyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "launchdarkly-access-token", + Description: "Launchdarkly Access Token", + Regex: generateSemiGenericRegex([]string{"launchdarkly"}, alphaNumericExtended("40")), + SecretGroup: 1, + Keywords: []string{ + "launchdarkly", + }, + } + + // validate + tps := []string{ + generateSampleSecret("launchdarkly", secrets.NewSecret(alphaNumericExtended("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/linear.go b/cmd/generate/config/rules/linear.go new file mode 100644 index 000000000..270cd2391 --- /dev/null +++ b/cmd/generate/config/rules/linear.go @@ -0,0 +1,41 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LinearAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Linear API Token", + RuleID: "linear-api-key", + Regex: regexp.MustCompile(`lin_api_(?i)[a-z0-9]{40}`), + Keywords: []string{"lin_api_"}, + } + + // validate + tps := []string{ + generateSampleSecret("linear", "lin_api_"+secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} + +func LinearClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Linear Client Secret", + RuleID: "linear-client-secret", + Regex: generateSemiGenericRegex([]string{"linear"}, hex("32")), + Keywords: []string{"linear"}, + SecretGroup: 1, + } + + // validate + tps := []string{ + generateSampleSecret("linear", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/linkedin.go b/cmd/generate/config/rules/linkedin.go new file mode 100644 index 000000000..2df9c6dc8 --- /dev/null +++ b/cmd/generate/config/rules/linkedin.go @@ -0,0 +1,52 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LinkedinClientSecret() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "linkedin-client-secret", + Description: "LinkedIn Client secret", + Regex: generateSemiGenericRegex([]string{ + "linkedin", + "linked-in", + }, alphaNumeric("16")), + SecretGroup: 1, + Keywords: []string{ + "linkedin", + "linked-in", + }, + } + + // validate + tps := []string{ + generateSampleSecret("linkedin", secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} + +func LinkedinClientID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "linkedin-client-id", + Description: "LinkedIn Client ID", + Regex: generateSemiGenericRegex([]string{ + "linkedin", + "linked-in", + }, alphaNumeric("14")), + SecretGroup: 1, + Keywords: []string{ + "linkedin", + "linked-in", + }, + } + + // validate + tps := []string{ + generateSampleSecret("linkedin", secrets.NewSecret(alphaNumeric("14"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/lob.go b/cmd/generate/config/rules/lob.go new file mode 100644 index 000000000..3aea66172 --- /dev/null +++ b/cmd/generate/config/rules/lob.go @@ -0,0 +1,47 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LobPubAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Lob Publishable API Key", + RuleID: "lob-pub-api-key", + Regex: generateSemiGenericRegex([]string{"lob"}, `(test|live)_pub_[a-f0-9]{31}`), + SecretGroup: 1, + Keywords: []string{ + "test_pub", + "live_pub", + "_pub", + }, + } + + // validate + tps := []string{ + generateSampleSecret("lob", "test_pub_"+secrets.NewSecret(hex("31"))), + } + return validate(r, tps, nil) +} + +func LobAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Lob API Key", + RuleID: "lob-api-key", + Regex: generateSemiGenericRegex([]string{"lob"}, `(live|test)_[a-f0-9]{35}`), + Keywords: []string{ + "test_", + "live_", + }, + SecretGroup: 1, + } + + // validate + tps := []string{ + generateSampleSecret("lob", "test_"+secrets.NewSecret(hex("35"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mailchimp.go b/cmd/generate/config/rules/mailchimp.go new file mode 100644 index 000000000..7fa87b904 --- /dev/null +++ b/cmd/generate/config/rules/mailchimp.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MailChimp() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailchimp-api-key", + Description: "Mailchimp API key", + Regex: generateSemiGenericRegex([]string{"mailchimp"}, `[a-f0-9]{32}-us20`), + SecretGroup: 1, + Keywords: []string{ + "mailchimp", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailchimp", secrets.NewSecret(hex("32"))+"-us20"), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mailgun.go b/cmd/generate/config/rules/mailgun.go new file mode 100644 index 000000000..c135e7273 --- /dev/null +++ b/cmd/generate/config/rules/mailgun.go @@ -0,0 +1,63 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MailGunPrivateAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-private-api-token", + Description: "Mailgun private API token", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `key-[a-f0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", "key-"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func MailGunPubAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-pub-key", + Description: "Mailgun public validation key", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `pubkey-[a-f0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", "pubkey-"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func MailGunSigningKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-signing-key", + Description: "Mailgun webhook signing key", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `[a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", secrets.NewSecret(hex("32"))+"-00001111-22223333"), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mapbox.go b/cmd/generate/config/rules/mapbox.go new file mode 100644 index 000000000..bed791fac --- /dev/null +++ b/cmd/generate/config/rules/mapbox.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MapBox() *config.Rule { + // define rule + r := config.Rule{ + Description: "MapBox API token", + RuleID: "mapbox-api-token", + Regex: generateSemiGenericRegex([]string{"mapbox"}, `pk\.[a-z0-9]{60}\.[a-z0-9]{22}`), + SecretGroup: 1, + Keywords: []string{"mapbox"}, + } + + // validate + tps := []string{ + generateSampleSecret("mapbox", "pk."+secrets.NewSecret(alphaNumeric("60"))+"."+secrets.NewSecret(alphaNumeric("22"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mattermost.go b/cmd/generate/config/rules/mattermost.go new file mode 100644 index 000000000..7f73ba85d --- /dev/null +++ b/cmd/generate/config/rules/mattermost.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MattermostAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mattermost-access-token", + Description: "Mattermost Access Token", + Regex: generateSemiGenericRegex([]string{"mattermost"}, alphaNumeric("26")), + SecretGroup: 1, + Keywords: []string{ + "mattermost", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mattermost", secrets.NewSecret(alphaNumeric("26"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/messagebird.go b/cmd/generate/config/rules/messagebird.go new file mode 100644 index 000000000..6973a4fb5 --- /dev/null +++ b/cmd/generate/config/rules/messagebird.go @@ -0,0 +1,58 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MessageBirdAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "MessageBird API token", + RuleID: "messagebird-api-token", + Regex: generateSemiGenericRegex([]string{ + "messagebird", + "message-bird", + "message_bird", + }, alphaNumeric("25")), + SecretGroup: 1, + Keywords: []string{ + "messagebird", + "message-bird", + "message_bird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("messagebird", secrets.NewSecret(alphaNumeric("25"))), + generateSampleSecret("message-bird", secrets.NewSecret(alphaNumeric("25"))), + generateSampleSecret("message_bird", secrets.NewSecret(alphaNumeric("25"))), + } + return validate(r, tps, nil) +} + +func MessageBirdClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "MessageBird client ID", + RuleID: "messagebird-client-id", + Regex: generateSemiGenericRegex([]string{ + "messagebird", + "message-bird", + "message_bird", + }, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "messagebird", + "message-bird", + "message_bird", + }, + } + + // validate + tps := []string{ + `const MessageBirdClientID = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/netlify.go b/cmd/generate/config/rules/netlify.go new file mode 100644 index 000000000..2997c65e0 --- /dev/null +++ b/cmd/generate/config/rules/netlify.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NetlifyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "netlify-access-token", + Description: "Netlify Access Token", + Regex: generateSemiGenericRegex([]string{"netlify"}, + alphaNumericExtended("40,46")), + SecretGroup: 1, + Keywords: []string{ + "netlify", + }, + } + + // validate + tps := []string{ + generateSampleSecret("netlify", secrets.NewSecret(alphaNumericExtended("40,46"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/newrelic.go b/cmd/generate/config/rules/newrelic.go new file mode 100644 index 000000000..8f5645e58 --- /dev/null +++ b/cmd/generate/config/rules/newrelic.go @@ -0,0 +1,77 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NewRelicUserID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-user-api-key", + Description: "New Relic user API Key", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, `NRAK-[a-z0-9]{27}`), + SecretGroup: 1, + Keywords: []string{ + "NRAK", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", "NRAK-"+secrets.NewSecret(alphaNumeric("27"))), + } + return validate(r, tps, nil) +} + +func NewRelicUserKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-user-api-id", + Description: "New Relic user API ID", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "new-relic", + "newrelic", + "new_relic", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} + +func NewRelicBrowserAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-browser-api-token", + Description: "New Relic ingest browser API token", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, `NRJS-[a-f0-9]{19}`), + SecretGroup: 1, + Keywords: []string{ + "NRJS-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", "NRJS-"+secrets.NewSecret(hex("19"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/npm.go b/cmd/generate/config/rules/npm.go new file mode 100644 index 000000000..96031fceb --- /dev/null +++ b/cmd/generate/config/rules/npm.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NPM() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "npm-access-token", + Description: "npm access token", + Regex: generateUniqueTokenRegex(`npm_[a-z0-9]{36}`), + SecretGroup: 1, + Keywords: []string{ + "npm_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("npmAccessToken", "npm_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/nytimes.go b/cmd/generate/config/rules/nytimes.go new file mode 100644 index 000000000..58fb6df86 --- /dev/null +++ b/cmd/generate/config/rules/nytimes.go @@ -0,0 +1,29 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NytimesAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "nytimes-access-token", + Description: "Nytimes Access Token", + Regex: generateSemiGenericRegex([]string{ + "nytimes", "new-york-times,", "newyorktimes"}, + alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{ + "nytimes", + "new-york-times", + "newyorktimes", + }, + } + + // validate + tps := []string{ + generateSampleSecret("nytimes", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/okta.go b/cmd/generate/config/rules/okta.go new file mode 100644 index 000000000..650ffc4fe --- /dev/null +++ b/cmd/generate/config/rules/okta.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func OktaAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "okta-access-token", + Description: "Okta Access Token", + Regex: generateSemiGenericRegex([]string{"okta"}, + alphaNumericExtended("42")), + SecretGroup: 1, + Keywords: []string{ + "okta", + }, + } + + // validate + tps := []string{ + generateSampleSecret("okta", secrets.NewSecret(alphaNumeric("42"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/plaid.go b/cmd/generate/config/rules/plaid.go new file mode 100644 index 000000000..8cfc16d00 --- /dev/null +++ b/cmd/generate/config/rules/plaid.go @@ -0,0 +1,66 @@ +package rules + +import ( + "fmt" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PlaidAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-client-id", + Description: "Plaid Client ID", + Regex: generateSemiGenericRegex([]string{"plaid"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} + +func PlaidSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-secret-key", + Description: "Plaid Secret key", + Regex: generateSemiGenericRegex([]string{"plaid"}, alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} + +func PlaidAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-api-token", + Description: "Plaid API Token", + Regex: generateSemiGenericRegex([]string{"plaid"}, + fmt.Sprintf("access-(?:sandbox|development|production)-%s", hex8_4_4_4_12())), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(fmt.Sprintf("access-(?:sandbox|development|production)-%s", hex8_4_4_4_12()))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/planetscale.go b/cmd/generate/config/rules/planetscale.go new file mode 100644 index 000000000..847055123 --- /dev/null +++ b/cmd/generate/config/rules/planetscale.go @@ -0,0 +1,69 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PlanetScalePassword() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-password", + Description: "PlanetScale password", + Regex: generateUniqueTokenRegex(`pscale_pw_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_pw_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} + +func PlanetScaleAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-api-token", + Description: "PlanetScale API token", + Regex: generateUniqueTokenRegex(`pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_tkn_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} + +func PlanetScaleOAuthToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-oauth-token", + Description: "PlanetScale OAuth token", + Regex: generateUniqueTokenRegex(`pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_oauth_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/postman.go b/cmd/generate/config/rules/postman.go new file mode 100644 index 000000000..5e2bf3762 --- /dev/null +++ b/cmd/generate/config/rules/postman.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PostManAPI() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "postman-api-token", + Description: "Postman API token", + Regex: generateUniqueTokenRegex(`PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34}`), + SecretGroup: 1, + Keywords: []string{ + "PMAK-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("postmanAPItoken", "PMAK-"+secrets.NewSecret(hex("24"))+"-"+secrets.NewSecret(hex("34"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/prefect.go b/cmd/generate/config/rules/prefect.go new file mode 100644 index 000000000..5ab23137d --- /dev/null +++ b/cmd/generate/config/rules/prefect.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Prefect() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "prefect-api-token", + Description: "Prefect API token", + Regex: generateUniqueTokenRegex(`pnu_[a-z0-9]{36}`), + SecretGroup: 1, + Keywords: []string{ + "pnu_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("api-token", "pnu_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/privatekey.go b/cmd/generate/config/rules/privatekey.go new file mode 100644 index 000000000..9ca2a995c --- /dev/null +++ b/cmd/generate/config/rules/privatekey.go @@ -0,0 +1,28 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func PrivateKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Private Key", + RuleID: "private-key", + Regex: regexp.MustCompile(`(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY----`), + Keywords: []string{"-----BEGIN"}, + } + + // validate + tps := []string{`-----BEGIN PRIVATE KEY----- +anything +-----END PRIVATE KEY-----`, + `-----BEGIN RSA PRIVATE KEY----- +abcdefghijklmnopqrstuvwxyz +-----END RSA PRIVATE KEY----- +`, + } // gitleaks:allow + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/pulumi.go b/cmd/generate/config/rules/pulumi.go new file mode 100644 index 000000000..53edea9dc --- /dev/null +++ b/cmd/generate/config/rules/pulumi.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PulumiAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "pulumi-api-token", + Description: "Pulumi API token", + Regex: generateUniqueTokenRegex(`pul-[a-f0-9]{40}`), + SecretGroup: 1, + Keywords: []string{ + "pul-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("pulumi-api-token", "pul-"+secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/pypi.go b/cmd/generate/config/rules/pypi.go new file mode 100644 index 000000000..9fcdc0e01 --- /dev/null +++ b/cmd/generate/config/rules/pypi.go @@ -0,0 +1,26 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PyPiUploadToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "PyPI upload token", + RuleID: "pypi-upload-token", + Regex: regexp.MustCompile( + `pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}`), + Keywords: []string{ + "pypi-AgEIcHlwaS5vcmc", + }, + } + + // validate + tps := []string{"pypiToken := \"pypi-AgEIcHlwaS5vcmc" + secrets.NewSecret(hex("32")) + + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rapidapi.go b/cmd/generate/config/rules/rapidapi.go new file mode 100644 index 000000000..dd2841ea1 --- /dev/null +++ b/cmd/generate/config/rules/rapidapi.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func RapidAPIAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "rapidapi-access-token", + Description: "RapidAPI Access Token", + Regex: generateSemiGenericRegex([]string{"rapidapi"}, + alphaNumericExtendedShort("50")), + SecretGroup: 1, + Keywords: []string{ + "rapidapi", + }, + } + + // validate + tps := []string{ + generateSampleSecret("rapidapi", + secrets.NewSecret(alphaNumericExtendedShort("50"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/readme.go b/cmd/generate/config/rules/readme.go new file mode 100644 index 000000000..ac68cced2 --- /dev/null +++ b/cmd/generate/config/rules/readme.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ReadMe() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "readme-api-token", + Description: "Readme API token", + Regex: generateUniqueTokenRegex(`rdme_[a-z0-9]{70}`), + SecretGroup: 1, + Keywords: []string{ + "rdme_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("api-token", "rdme_"+secrets.NewSecret(alphaNumeric("70"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rubygems.go b/cmd/generate/config/rules/rubygems.go new file mode 100644 index 000000000..8329cd741 --- /dev/null +++ b/cmd/generate/config/rules/rubygems.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func RubyGemsAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "rubygems-api-token", + Description: "Rubygem API token", + Regex: generateUniqueTokenRegex(`rubygems_[a-f0-9]{48}`), + SecretGroup: 1, + Keywords: []string{ + "rubygems_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("rubygemsAPIToken", "rubygems_"+secrets.NewSecret(hex("48"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rule.go b/cmd/generate/config/rules/rule.go new file mode 100644 index 000000000..24d4e9016 --- /dev/null +++ b/cmd/generate/config/rules/rule.go @@ -0,0 +1,110 @@ +package rules + +import ( + "fmt" + "regexp" + "strings" + + "github.com/rs/zerolog/log" + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" +) + +const ( + // case insensitive prefix + caseInsensitive = `(?i)` + + // identifier prefix (just an ignore group) + identifierPrefix = `(?:` + identifierSuffix = `)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}` + + // commonly used assignment operators or function call + operator = `(?:=|>|:=|\|\|:|<=|=>|:)` + + // boundaries for the secret + // \x60 = ` + secretPrefixUnique = `\b(` + secretPrefix = `(?:'|\"|\s|=|\x60){0,5}(` + secretSuffix = `)(?:['|\"|\n|\r|\s|\x60|;]|$)` +) + +func generateSemiGenericRegex(identifiers []string, secretRegex string) *regexp.Regexp { + var sb strings.Builder + sb.WriteString(caseInsensitive) + sb.WriteString(identifierPrefix) + sb.WriteString(strings.Join(identifiers, "|")) + sb.WriteString(identifierSuffix) + sb.WriteString(operator) + sb.WriteString(secretPrefix) + sb.WriteString(secretRegex) + sb.WriteString(secretSuffix) + return regexp.MustCompile(sb.String()) +} + +func generateUniqueTokenRegex(secretRegex string) *regexp.Regexp { + var sb strings.Builder + sb.WriteString(caseInsensitive) + sb.WriteString(secretPrefixUnique) + sb.WriteString(secretRegex) + sb.WriteString(secretSuffix) + return regexp.MustCompile(sb.String()) +} + +func generateSampleSecret(identifier string, secret string) string { + return fmt.Sprintf("%s_api_token = \"%s\"", identifier, secret) +} + +func validate(r config.Rule, truePositives []string, falsePositives []string) *config.Rule { + // normalize keywords like in the config package + var keywords []string + for _, k := range r.Keywords { + keywords = append(keywords, strings.ToLower(k)) + } + r.Keywords = keywords + + rules := make(map[string]config.Rule) + rules[r.RuleID] = r + d := detect.NewDetector(config.Config{ + Rules: rules, + Keywords: keywords, + }) + for _, tp := range truePositives { + if len(d.DetectString(tp)) != 1 { + log.Fatal().Msgf("Failed to validate. For rule ID [%s], true positive [%s] was not detected by regexp [%s]", r.RuleID, tp, r.Regex) + } + } + for _, fp := range falsePositives { + if len(d.DetectString(fp)) != 0 { + log.Fatal().Msgf("Failed to validate (fp) [%s]", r.RuleID) + } + } + return &r +} + +func numeric(size string) string { + return fmt.Sprintf(`[0-9]{%s}`, size) +} + +func hex(size string) string { + return fmt.Sprintf(`[a-f0-9]{%s}`, size) +} + +func alphaNumeric(size string) string { + return fmt.Sprintf(`[a-z0-9]{%s}`, size) +} + +func alphaNumericExtendedShort(size string) string { + return fmt.Sprintf(`[a-z0-9_-]{%s}`, size) +} + +func alphaNumericExtended(size string) string { + return fmt.Sprintf(`[a-z0-9=_\-]{%s}`, size) +} + +func alphaNumericExtendedLong(size string) string { + return fmt.Sprintf(`[a-z0-9\/=_\+\-]{%s}`, size) +} + +func hex8_4_4_4_12() string { + return `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}` +} diff --git a/cmd/generate/config/rules/sendbird.go b/cmd/generate/config/rules/sendbird.go new file mode 100644 index 000000000..204768318 --- /dev/null +++ b/cmd/generate/config/rules/sendbird.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendbirdAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendbird-access-token", + Description: "Sendbird Access Token", + Regex: generateSemiGenericRegex([]string{"sendbird"}, hex("40")), + SecretGroup: 1, + Keywords: []string{ + "sendbird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendbird", secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} + +func SendbirdAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendbird-access-id", + Description: "Sendbird Access ID", + Regex: generateSemiGenericRegex([]string{"sendbird"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "sendbird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendbird", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sendgrid.go b/cmd/generate/config/rules/sendgrid.go new file mode 100644 index 000000000..80b1001a9 --- /dev/null +++ b/cmd/generate/config/rules/sendgrid.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendGridAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendgrid-api-token", + Description: "SendGrid API token", + Regex: generateUniqueTokenRegex(`SG\.(?i)[a-z0-9=_\-\.]{66}`), + SecretGroup: 1, + Keywords: []string{ + "SG.", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sengridAPIToken", "SG."+secrets.NewSecret(alphaNumericExtended("66"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sendinblue.go b/cmd/generate/config/rules/sendinblue.go new file mode 100644 index 000000000..41f75104d --- /dev/null +++ b/cmd/generate/config/rules/sendinblue.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendInBlueAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendinblue-api-token", + Description: "Sendinblue API token", + Regex: generateUniqueTokenRegex(`xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16}`), + SecretGroup: 1, + Keywords: []string{ + "xkeysib-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendinblue", "xkeysib-"+secrets.NewSecret(hex("64"))+"-"+secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sentry.go b/cmd/generate/config/rules/sentry.go new file mode 100644 index 000000000..74452ebbc --- /dev/null +++ b/cmd/generate/config/rules/sentry.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SentryAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sentry-access-token", + Description: "Sentry Access Token", + Regex: generateSemiGenericRegex([]string{"sentry"}, hex("64")), + SecretGroup: 1, + Keywords: []string{ + "sentry", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sentry", secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/shippo.go b/cmd/generate/config/rules/shippo.go new file mode 100644 index 000000000..494777e15 --- /dev/null +++ b/cmd/generate/config/rules/shippo.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ShippoAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "shippo-api-token", + Description: "Shippo API token", + Regex: generateUniqueTokenRegex(`shippo_(live|test)_[a-f0-9]{40}`), + SecretGroup: 1, + Keywords: []string{ + "shippo_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("shippo", "shippo_live_"+secrets.NewSecret(hex("40"))), + generateSampleSecret("shippo", "shippo_test_"+secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/shopify.go b/cmd/generate/config/rules/shopify.go new file mode 100644 index 000000000..b6bf4e881 --- /dev/null +++ b/cmd/generate/config/rules/shopify.go @@ -0,0 +1,64 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ShopifySharedSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify shared secret", + RuleID: "shopify-shared-secret", + Regex: regexp.MustCompile(`shpss_[a-fA-F0-9]{32}`), + Keywords: []string{"shpss_"}, + } + + // validate + tps := []string{"shopifySecret := \"shpss_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify access token", + RuleID: "shopify-access-token", + Regex: regexp.MustCompile(`shpat_[a-fA-F0-9]{32}`), + Keywords: []string{"shpat_"}, + } + + // validate + tps := []string{"shopifyToken := \"shpat_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyCustomAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify custom access token", + RuleID: "shopify-custom-access-token", + Regex: regexp.MustCompile(`shpca_[a-fA-F0-9]{32}`), + Keywords: []string{"shpca_"}, + } + + // validate + tps := []string{"shopifyToken := \"shpca_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyPrivateAppAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify private app access token", + RuleID: "shopify-private-app-access-token", + Regex: regexp.MustCompile(`shppa_[a-fA-F0-9]{32}`), + Keywords: []string{"shppa_"}, + } + + // validate + tps := []string{"shopifyToken := \"shppa_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sidekiq.go b/cmd/generate/config/rules/sidekiq.go new file mode 100644 index 000000000..71f0c8059 --- /dev/null +++ b/cmd/generate/config/rules/sidekiq.go @@ -0,0 +1,60 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func SidekiqSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Sidekiq Secret", + RuleID: "sidekiq-secret", + SecretGroup: 1, + Regex: generateSemiGenericRegex([]string{"BUNDLE_ENTERPRISE__CONTRIBSYS__COM", "BUNDLE_GEMS__CONTRIBSYS__COM"}, + `[a-f0-9]{8}:[a-f0-9]{8}`), + Keywords: []string{"BUNDLE_ENTERPRISE__CONTRIBSYS__COM", "BUNDLE_GEMS__CONTRIBSYS__COM"}, + } + + // validate + tps := []string{ + "BUNDLE_ENTERPRISE__CONTRIBSYS__COM: cafebabe:deadbeef", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM = cafebabe:deadbeef", + "BUNDLE_GEMS__CONTRIBSYS__COM: \"cafebabe:deadbeef\"", + "export BUNDLE_GEMS__CONTRIBSYS__COM=\"cafebabe:deadbeef\"", + "export BUNDLE_GEMS__CONTRIBSYS__COM = \"cafebabe:deadbeef\"", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef && echo 'hello world'", + } + return validate(r, tps, nil) +} + +func SidekiqSensitiveUrl() *config.Rule { + // define rule + r := config.Rule{ + Description: "Sidekiq Sensitive URL", + RuleID: "sidekiq-sensitive-url", + SecretGroup: 2, + Regex: regexp.MustCompile(`(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)`), + Keywords: []string{"gems.contribsys.com", "enterprise.contribsys.com"}, + } + + // validate + tps := []string{ + "https://cafebabe:deadbeef@gems.contribsys.com/", + "https://cafebabe:deadbeef@gems.contribsys.com", + "https://cafeb4b3:d3adb33f@enterprise.contribsys.com/", + "https://cafeb4b3:d3adb33f@enterprise.contribsys.com", + "http://cafebabe:deadbeef@gems.contribsys.com/", + "http://cafebabe:deadbeef@gems.contribsys.com", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com/", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com#heading1", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com?param1=true¶m2=false", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/slack.go b/cmd/generate/config/rules/slack.go new file mode 100644 index 000000000..63484be06 --- /dev/null +++ b/cmd/generate/config/rules/slack.go @@ -0,0 +1,51 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SlackAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Slack token", + RuleID: "slack-access-token", + Regex: regexp.MustCompile( + "xox[baprs]-([0-9a-zA-Z]{10,48})"), + Keywords: []string{ + "xoxb", + "xoxa", + "xoxp", + "xoxr", + "xoxs", + }, + } + + // validate + tps := []string{ + "\"slackToken\": \"xoxb-" + secrets.NewSecret(alphaNumeric("30")) + "\"", + } + return validate(r, tps, nil) +} + +func SlackWebHook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Slack Webhook", + RuleID: "slack-web-hook", + Regex: regexp.MustCompile( + `https:\/\/hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{44,46}`), + Keywords: []string{ + "hooks.slack.com", + }, + } + + // validate + tps := []string{ + "https://hooks.slack.com/services/" + secrets.NewSecret(alphaNumeric("44")), // gitleaks:allow + "https://hooks.slack.com/workflows/" + secrets.NewSecret(alphaNumeric("44")), // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/square.go b/cmd/generate/config/rules/square.go new file mode 100644 index 000000000..a9da8fb76 --- /dev/null +++ b/cmd/generate/config/rules/square.go @@ -0,0 +1,38 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SquareAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "square-access-token", + Description: "Square Access Token", + Regex: generateUniqueTokenRegex(`sq0atp-[0-9A-Za-z\-_]{22}`), + Keywords: []string{"sq0atp-"}, + } + + // validate + tps := []string{ + generateSampleSecret("square", secrets.NewSecret(`sq0atp-[0-9A-Za-z\-_]{22}`)), + } + return validate(r, tps, nil) +} + +func SquareSecret() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "square-secret", + Description: "Square Secret", + Regex: generateUniqueTokenRegex(`sq0csp-[0-9A-Za-z\\-_]{43}`), + Keywords: []string{"sq0csp-"}, + } + + // validate + tps := []string{ + generateSampleSecret("square", secrets.NewSecret(`sq0csp-[0-9A-Za-z\\-_]{43}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/squarespace.go b/cmd/generate/config/rules/squarespace.go new file mode 100644 index 000000000..51b7deab2 --- /dev/null +++ b/cmd/generate/config/rules/squarespace.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SquareSpaceAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "squarespace-access-token", + Description: "Squarespace Access Token", + Regex: generateSemiGenericRegex([]string{"squarespace"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "squarespace", + }, + } + + // validate + tps := []string{ + generateSampleSecret("squarespace", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/stopwords.go b/cmd/generate/config/rules/stopwords.go new file mode 100644 index 000000000..8aa07d551 --- /dev/null +++ b/cmd/generate/config/rules/stopwords.go @@ -0,0 +1,1489 @@ +package rules + +// TODO introduce skiplists: +// https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/wordlist-skipfish.fuzz.txt +// https://github.com/e3b0c442/keywords +// https://gist.github.com/maxtruxa/b2ca551e42d3aead2b3d +// https://github.com/HChakraborty/projects/commit/e860cb863ee9585c38db8360814b04ef9fa1bdce +// https://github.com/UraniumX92/Discord-Bot-using-py/tree/224b2b71a58c25f420ce980f2ea49627b4b646f1/Data%20Files +// https://github.com/Meen11/BSBI-Indexing/blob/63032017aa24f3111f18468607cd0db5997bb891/datasets/citeseer/11/10.1.1.27.6385.txt + +var DefaultStopWords = []string{ + "client", + "endpoint", + "vpn", + "_ec2_", + "aws_", + "authorize", + "author", + "define", + "config", + "credential", + "setting", + "sample", + "xxxxxx", + "000000", + "buffer", + "delete", + "aaaaaa", + "fewfwef", + "getenv", + "env_", + "system", + "example", + "ecdsa", + "sha256", + "sha1", + "sha2", + "md5", + "alert", + "wizard", + "target", + "onboard", + "welcome", + "page", + "exploit", + "experiment", + "expire", + "rabbitmq", + "scraper", + "widget", + "music", + "dns_", + "dns-", + "yahoo", + "want", + "json", + "action", + "script", + "fix_", + "fix-", + "develop", + "compas", + "stripe", + "service", + "master", + "metric", + "tech", + "gitignore", + "rich", + "open", + "stack", + "irc_", + "irc-", + "sublime", + "kohana", + "has_", + "has-", + "fabric", + "wordpres", + "role", + "osx_", + "osx-", + "boost", + "addres", + "queue", + "working", + "sandbox", + "internet", + "print", + "vision", + "tracking", + "being", + "generator", + "traffic", + "world", + "pull", + "rust", + "watcher", + "small", + "auth", + "full", + "hash", + "more", + "install", + "auto", + "complete", + "learn", + "paper", + "installer", + "research", + "acces", + "last", + "binding", + "spine", + "into", + "chat", + "algorithm", + "resource", + "uploader", + "video", + "maker", + "next", + "proc", + "lock", + "robot", + "snake", + "patch", + "matrix", + "drill", + "terminal", + "term", + "stuff", + "genetic", + "generic", + "identity", + "audit", + "pattern", + "audio", + "web_", + "web-", + "crud", + "problem", + "statu", + "cms-", + "cms_", + "arch", + "coffee", + "workflow", + "changelog", + "another", + "uiview", + "content", + "kitchen", + "gnu_", + "gnu-", + "gnu.", + "conf", + "couchdb", + "client", + "opencv", + "rendering", + "update", + "concept", + "varnish", + "gui_", + "gui-", + "gui.", + "version", + "shared", + "extra", + "product", + "still", + "not_", + "not-", + "not.", + "drop", + "ring", + "png_", + "png-", + "png.", + "actively", + "import", + "output", + "backup", + "start", + "embedded", + "registry", + "pool", + "semantic", + "instagram", + "bash", + "system", + "ninja", + "drupal", + "jquery", + "polyfill", + "physic", + "league", + "guide", + "pack", + "synopsi", + "sketch", + "injection", + "svg_", + "svg-", + "svg.", + "friendly", + "wave", + "convert", + "manage", + "camera", + "link", + "slide", + "timer", + "wrapper", + "gallery", + "url_", + "url-", + "url.", + "todomvc", + "requirej", + "party", + "http", + "payment", + "async", + "library", + "home", + "coco", + "gaia", + "display", + "universal", + "func", + "metadata", + "hipchat", + "under", + "room", + "config", + "personal", + "realtime", + "resume", + "database", + "testing", + "tiny", + "basic", + "forum", + "meetup", + "yet_", + "yet-", + "yet.", + "cento", + "dead", + "fluentd", + "editor", + "utilitie", + "run_", + "run-", + "run.", + "box_", + "box-", + "box.", + "bot_", + "bot-", + "bot.", + "making", + "sample", + "group", + "monitor", + "ajax", + "parallel", + "cassandra", + "ultimate", + "site", + "get_", + "get-", + "get.", + "gen_", + "gen-", + "gen.", + "gem_", + "gem-", + "gem.", + "extended", + "image", + "knife", + "asset", + "nested", + "zero", + "plugin", + "bracket", + "mule", + "mozilla", + "number", + "act_", + "act-", + "act.", + "map_", + "map-", + "map.", + "micro", + "debug", + "openshift", + "chart", + "expres", + "backend", + "task", + "source", + "translate", + "jbos", + "composer", + "sqlite", + "profile", + "mustache", + "mqtt", + "yeoman", + "have", + "builder", + "smart", + "like", + "oauth", + "school", + "guideline", + "captcha", + "filter", + "bitcoin", + "bridge", + "color", + "toolbox", + "discovery", + "new_", + "new-", + "new.", + "dashboard", + "when", + "setting", + "level", + "post", + "standard", + "port", + "platform", + "yui_", + "yui-", + "yui.", + "grunt", + "animation", + "haskell", + "icon", + "latex", + "cheat", + "lua_", + "lua-", + "lua.", + "gulp", + "case", + "author", + "without", + "simulator", + "wifi", + "directory", + "lisp", + "list", + "flat", + "adventure", + "story", + "storm", + "gpu_", + "gpu-", + "gpu.", + "store", + "caching", + "attention", + "solr", + "logger", + "demo", + "shortener", + "hadoop", + "finder", + "phone", + "pipeline", + "range", + "textmate", + "showcase", + "app_", + "app-", + "app.", + "idiomatic", + "edit", + "our_", + "our-", + "our.", + "out_", + "out-", + "out.", + "sentiment", + "linked", + "why_", + "why-", + "why.", + "local", + "cube", + "gmail", + "job_", + "job-", + "job.", + "rpc_", + "rpc-", + "rpc.", + "contest", + "tcp_", + "tcp-", + "tcp.", + "usage", + "buildout", + "weather", + "transfer", + "automated", + "sphinx", + "issue", + "sas_", + "sas-", + "sas.", + "parallax", + "jasmine", + "addon", + "machine", + "solution", + "dsl_", + "dsl-", + "dsl.", + "episode", + "menu", + "theme", + "best", + "adapter", + "debugger", + "chrome", + "tutorial", + "life", + "step", + "people", + "joomla", + "paypal", + "developer", + "solver", + "team", + "current", + "love", + "visual", + "date", + "data", + "canva", + "container", + "future", + "xml_", + "xml-", + "xml.", + "twig", + "nagio", + "spatial", + "original", + "sync", + "archived", + "refinery", + "science", + "mapping", + "gitlab", + "play", + "ext_", + "ext-", + "ext.", + "session", + "impact", + "set_", + "set-", + "set.", + "see_", + "see-", + "see.", + "migration", + "commit", + "community", + "shopify", + "what'", + "cucumber", + "statamic", + "mysql", + "location", + "tower", + "line", + "code", + "amqp", + "hello", + "send", + "index", + "high", + "notebook", + "alloy", + "python", + "field", + "document", + "soap", + "edition", + "email", + "php_", + "php-", + "php.", + "command", + "transport", + "official", + "upload", + "study", + "secure", + "angularj", + "akka", + "scalable", + "package", + "request", + "con_", + "con-", + "con.", + "flexible", + "security", + "comment", + "module", + "flask", + "graph", + "flash", + "apache", + "change", + "window", + "space", + "lambda", + "sheet", + "bookmark", + "carousel", + "friend", + "objective", + "jekyll", + "bootstrap", + "first", + "article", + "gwt_", + "gwt-", + "gwt.", + "classic", + "media", + "websocket", + "touch", + "desktop", + "real", + "read", + "recorder", + "moved", + "storage", + "validator", + "add-on", + "pusher", + "scs_", + "scs-", + "scs.", + "inline", + "asp_", + "asp-", + "asp.", + "timeline", + "base", + "encoding", + "ffmpeg", + "kindle", + "tinymce", + "pretty", + "jpa_", + "jpa-", + "jpa.", + "used", + "user", + "required", + "webhook", + "download", + "resque", + "espresso", + "cloud", + "mongo", + "benchmark", + "pure", + "cakephp", + "modx", + "mode", + "reactive", + "fuel", + "written", + "flickr", + "mail", + "brunch", + "meteor", + "dynamic", + "neo_", + "neo-", + "neo.", + "new_", + "new-", + "new.", + "net_", + "net-", + "net.", + "typo", + "type", + "keyboard", + "erlang", + "adobe", + "logging", + "ckeditor", + "message", + "iso_", + "iso-", + "iso.", + "hook", + "ldap", + "folder", + "reference", + "railscast", + "www_", + "www-", + "www.", + "tracker", + "azure", + "fork", + "form", + "digital", + "exporter", + "skin", + "string", + "template", + "designer", + "gollum", + "fluent", + "entity", + "language", + "alfred", + "summary", + "wiki", + "kernel", + "calendar", + "plupload", + "symfony", + "foundry", + "remote", + "talk", + "search", + "dev_", + "dev-", + "dev.", + "del_", + "del-", + "del.", + "token", + "idea", + "sencha", + "selector", + "interface", + "create", + "fun_", + "fun-", + "fun.", + "groovy", + "query", + "grail", + "red_", + "red-", + "red.", + "laravel", + "monkey", + "slack", + "supported", + "instant", + "value", + "center", + "latest", + "work", + "but_", + "but-", + "but.", + "bug_", + "bug-", + "bug.", + "virtual", + "tweet", + "statsd", + "studio", + "path", + "real-time", + "frontend", + "notifier", + "coding", + "tool", + "firmware", + "flow", + "random", + "mediawiki", + "bosh", + "been", + "beer", + "lightbox", + "theory", + "origin", + "redmine", + "hub_", + "hub-", + "hub.", + "require", + "pro_", + "pro-", + "pro.", + "ant_", + "ant-", + "ant.", + "any_", + "any-", + "any.", + "recipe", + "closure", + "mapper", + "event", + "todo", + "model", + "redi", + "provider", + "rvm_", + "rvm-", + "rvm.", + "program", + "memcached", + "rail", + "silex", + "foreman", + "activity", + "license", + "strategy", + "batch", + "streaming", + "fast", + "use_", + "use-", + "use.", + "usb_", + "usb-", + "usb.", + "impres", + "academy", + "slider", + "please", + "layer", + "cros", + "now_", + "now-", + "now.", + "miner", + "extension", + "own_", + "own-", + "own.", + "app_", + "app-", + "app.", + "debian", + "symphony", + "example", + "feature", + "serie", + "tree", + "project", + "runner", + "entry", + "leetcode", + "layout", + "webrtc", + "logic", + "login", + "worker", + "toolkit", + "mocha", + "support", + "back", + "inside", + "device", + "jenkin", + "contact", + "fake", + "awesome", + "ocaml", + "bit_", + "bit-", + "bit.", + "drive", + "screen", + "prototype", + "gist", + "binary", + "nosql", + "rest", + "overview", + "dart", + "dark", + "emac", + "mongoid", + "solarized", + "homepage", + "emulator", + "commander", + "django", + "yandex", + "gradle", + "xcode", + "writer", + "crm_", + "crm-", + "crm.", + "jade", + "startup", + "error", + "using", + "format", + "name", + "spring", + "parser", + "scratch", + "magic", + "try_", + "try-", + "try.", + "rack", + "directive", + "challenge", + "slim", + "counter", + "element", + "chosen", + "doc_", + "doc-", + "doc.", + "meta", + "should", + "button", + "packet", + "stream", + "hardware", + "android", + "infinite", + "password", + "software", + "ghost", + "xamarin", + "spec", + "chef", + "interview", + "hubot", + "mvc_", + "mvc-", + "mvc.", + "exercise", + "leaflet", + "launcher", + "air_", + "air-", + "air.", + "photo", + "board", + "boxen", + "way_", + "way-", + "way.", + "computing", + "welcome", + "notepad", + "portfolio", + "cat_", + "cat-", + "cat.", + "can_", + "can-", + "can.", + "magento", + "yaml", + "domain", + "card", + "yii_", + "yii-", + "yii.", + "checker", + "browser", + "upgrade", + "only", + "progres", + "aura", + "ruby_", + "ruby-", + "ruby.", + "polymer", + "util", + "lite", + "hackathon", + "rule", + "log_", + "log-", + "log.", + "opengl", + "stanford", + "skeleton", + "history", + "inspector", + "help", + "soon", + "selenium", + "lab_", + "lab-", + "lab.", + "scheme", + "schema", + "look", + "ready", + "leveldb", + "docker", + "game", + "minimal", + "logstash", + "messaging", + "within", + "heroku", + "mongodb", + "kata", + "suite", + "picker", + "win_", + "win-", + "win.", + "wip_", + "wip-", + "wip.", + "panel", + "started", + "starter", + "front-end", + "detector", + "deploy", + "editing", + "based", + "admin", + "capture", + "spree", + "page", + "bundle", + "goal", + "rpg_", + "rpg-", + "rpg.", + "setup", + "side", + "mean", + "reader", + "cookbook", + "mini", + "modern", + "seed", + "dom_", + "dom-", + "dom.", + "doc_", + "doc-", + "doc.", + "dot_", + "dot-", + "dot.", + "syntax", + "sugar", + "loader", + "website", + "make", + "kit_", + "kit-", + "kit.", + "protocol", + "human", + "daemon", + "golang", + "manager", + "countdown", + "connector", + "swagger", + "map_", + "map-", + "map.", + "mac_", + "mac-", + "mac.", + "man_", + "man-", + "man.", + "orm_", + "orm-", + "orm.", + "org_", + "org-", + "org.", + "little", + "zsh_", + "zsh-", + "zsh.", + "shop", + "show", + "workshop", + "money", + "grid", + "server", + "octopres", + "svn_", + "svn-", + "svn.", + "ember", + "embed", + "general", + "file", + "important", + "dropbox", + "portable", + "public", + "docpad", + "fish", + "sbt_", + "sbt-", + "sbt.", + "done", + "para", + "network", + "common", + "readme", + "popup", + "simple", + "purpose", + "mirror", + "single", + "cordova", + "exchange", + "object", + "design", + "gateway", + "account", + "lamp", + "intellij", + "math", + "mit_", + "mit-", + "mit.", + "control", + "enhanced", + "emitter", + "multi", + "add_", + "add-", + "add.", + "about", + "socket", + "preview", + "vagrant", + "cli_", + "cli-", + "cli.", + "powerful", + "top_", + "top-", + "top.", + "radio", + "watch", + "fluid", + "amazon", + "report", + "couchbase", + "automatic", + "detection", + "sprite", + "pyramid", + "portal", + "advanced", + "plu_", + "plu-", + "plu.", + "runtime", + "git_", + "git-", + "git.", + "uri_", + "uri-", + "uri.", + "haml", + "node", + "sql_", + "sql-", + "sql.", + "cool", + "core", + "obsolete", + "handler", + "iphone", + "extractor", + "array", + "copy", + "nlp_", + "nlp-", + "nlp.", + "reveal", + "pop_", + "pop-", + "pop.", + "engine", + "parse", + "check", + "html", + "nest", + "all_", + "all-", + "all.", + "chinese", + "buildpack", + "what", + "tag_", + "tag-", + "tag.", + "proxy", + "style", + "cookie", + "feed", + "restful", + "compiler", + "creating", + "prelude", + "context", + "java", + "rspec", + "mock", + "backbone", + "light", + "spotify", + "flex", + "related", + "shell", + "which", + "clas", + "webapp", + "swift", + "ansible", + "unity", + "console", + "tumblr", + "export", + "campfire", + "conway'", + "made", + "riak", + "hero", + "here", + "unix", + "unit", + "glas", + "smtp", + "how_", + "how-", + "how.", + "hot_", + "hot-", + "hot.", + "debug", + "release", + "diff", + "player", + "easy", + "right", + "old_", + "old-", + "old.", + "animate", + "time", + "push", + "explorer", + "course", + "training", + "nette", + "router", + "draft", + "structure", + "note", + "salt", + "where", + "spark", + "trello", + "power", + "method", + "social", + "via_", + "via-", + "via.", + "vim_", + "vim-", + "vim.", + "select", + "webkit", + "github", + "ftp_", + "ftp-", + "ftp.", + "creator", + "mongoose", + "led_", + "led-", + "led.", + "movie", + "currently", + "pdf_", + "pdf-", + "pdf.", + "load", + "markdown", + "phalcon", + "input", + "custom", + "atom", + "oracle", + "phonegap", + "ubuntu", + "great", + "rdf_", + "rdf-", + "rdf.", + "popcorn", + "firefox", + "zip_", + "zip-", + "zip.", + "cuda", + "dotfile", + "static", + "openwrt", + "viewer", + "powered", + "graphic", + "les_", + "les-", + "les.", + "doe_", + "doe-", + "doe.", + "maven", + "word", + "eclipse", + "lab_", + "lab-", + "lab.", + "hacking", + "steam", + "analytic", + "option", + "abstract", + "archive", + "reality", + "switcher", + "club", + "write", + "kafka", + "arduino", + "angular", + "online", + "title", + "don't", + "contao", + "notice", + "analyzer", + "learning", + "zend", + "external", + "staging", + "busines", + "tdd_", + "tdd-", + "tdd.", + "scanner", + "building", + "snippet", + "modular", + "bower", + "stm_", + "stm-", + "stm.", + "lib_", + "lib-", + "lib.", + "alpha", + "mobile", + "clean", + "linux", + "nginx", + "manifest", + "some", + "raspberry", + "gnome", + "ide_", + "ide-", + "ide.", + "block", + "statistic", + "info", + "drag", + "youtube", + "koan", + "facebook", + "paperclip", + "art_", + "art-", + "art.", + "quality", + "tab_", + "tab-", + "tab.", + "need", + "dojo", + "shield", + "computer", + "stat", + "state", + "twitter", + "utility", + "converter", + "hosting", + "devise", + "liferay", + "updated", + "force", + "tip_", + "tip-", + "tip.", + "behavior", + "active", + "call", + "answer", + "deck", + "better", + "principle", + "ches", + "bar_", + "bar-", + "bar.", + "reddit", + "three", + "haxe", + "just", + "plug-in", + "agile", + "manual", + "tetri", + "super", + "beta", + "parsing", + "doctrine", + "minecraft", + "useful", + "perl", + "sharing", + "agent", + "switch", + "view", + "dash", + "channel", + "repo", + "pebble", + "profiler", + "warning", + "cluster", + "running", + "markup", + "evented", + "mod_", + "mod-", + "mod.", + // "api_", lin_api_ is used for linear + // "api-", + // "api.", + "share", + "csv_", + "csv-", + "csv.", + "response", + "good", + "house", + "connect", + "built", + "build", + "find", + "ipython", + "webgl", + "big_", + "big-", + "big.", + "google", + "scala", + "sdl_", + "sdl-", + "sdl.", + "sdk_", + "sdk-", + "sdk.", + "native", + "day_", + "day-", + "day.", + "puppet", + "text", + "routing", + "helper", + "linkedin", + "crawler", + "host", + "guard", + "merchant", + "poker", + "over", + "writing", + "free", + "classe", + "component", + "craft", + "nodej", + "phoenix", + "longer", + "quick", + "lazy", + "memory", + "clone", + "hacker", + "middleman", + "factory", + "motion", + "multiple", + "tornado", + "hack", + "ssh_", + "ssh-", + "ssh.", + "review", + "vimrc", + "driver", + "driven", + "blog", + "particle", + "table", + "intro", + "importer", + "thrift", + "xmpp", + "framework", + "refresh", + "react", + "font", + "librarie", + "variou", + "formatter", + "analysi", + "karma", + "scroll", + "tut_", + "tut-", + "tut.", + "apple", + "tag_", + "tag-", + "tag.", + "tab_", + "tab-", + "tab.", + "category", + "ionic", + "cache", + "homebrew", + "reverse", + "english", + "getting", + "shipping", + "clojure", + "boot", + "book", + "branch", + "combination", + "combo", +} diff --git a/cmd/generate/config/rules/stripe.go b/cmd/generate/config/rules/stripe.go new file mode 100644 index 000000000..e4e8b7c9e --- /dev/null +++ b/cmd/generate/config/rules/stripe.go @@ -0,0 +1,27 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func StripeAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Stripe", + RuleID: "stripe-access-token", + Regex: regexp.MustCompile(`(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}`), + Keywords: []string{ + "sk_test", + "pk_test", + "sk_live", + "pk_live", + }, + } + + // validate + tps := []string{"stripeToken := \"sk_test_" + secrets.NewSecret(alphaNumeric("30")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sumologic.go b/cmd/generate/config/rules/sumologic.go new file mode 100644 index 000000000..c9f5d9b86 --- /dev/null +++ b/cmd/generate/config/rules/sumologic.go @@ -0,0 +1,46 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SumoLogicAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sumologic-access-id", + Description: "SumoLogic Access ID", + Regex: generateSemiGenericRegex([]string{"sumo"}, + alphaNumeric("14")), + SecretGroup: 1, + Keywords: []string{ + "sumo", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sumo", secrets.NewSecret(alphaNumeric("14"))), + } + return validate(r, tps, nil) +} + +func SumoLogicAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sumologic-access-token", + Description: "SumoLogic Access Token", + Regex: generateSemiGenericRegex([]string{"sumo"}, + alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "sumo", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sumo", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/teams.go b/cmd/generate/config/rules/teams.go new file mode 100644 index 000000000..2904c9cc1 --- /dev/null +++ b/cmd/generate/config/rules/teams.go @@ -0,0 +1,29 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TeamsWebhook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Microsoft Teams Webhook", + RuleID: "microsoft-teams-webhook", + Regex: regexp.MustCompile( + `https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}`), + Keywords: []string{ + "webhook.office.com", + "webhookb2", + "IncomingWebhook", + }, + } + + // validate + tps := []string{ + "https://mycompany.webhook.office.com/webhookb2/" + secrets.NewSecret(`[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}`), // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/telegram.go b/cmd/generate/config/rules/telegram.go new file mode 100644 index 000000000..e17027fb7 --- /dev/null +++ b/cmd/generate/config/rules/telegram.go @@ -0,0 +1,57 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TelegramBotToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Telegram Bot API Token", + RuleID: "telegram-bot-api-token", + SecretGroup: 1, + Regex: regexp.MustCompile(`(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])`), + Keywords: []string{ + "telegram", + "api", + "bot", + "token", + "url", + }, + } + + // validate + validToken := secrets.NewSecret(numeric("8") + ":A" + alphaNumericExtendedShort("34")) + minToken := secrets.NewSecret(numeric("5") + ":A" + alphaNumericExtendedShort("34")) + maxToken := secrets.NewSecret(numeric("16") + ":A" + alphaNumericExtendedShort("34")) + tps := []string{ + // variable assigment + generateSampleSecret("telegram", validToken), + // URL contaning token + generateSampleSecret("url", "https://api.telegram.org/bot"+validToken+"/sendMessage"), + // object constructor + `const bot = new Telegraf("` + validToken + `")`, + // .env + `API_TOKEN = ` + validToken, + // YAML + `bot: ` + validToken, + // Token with min bot_id + generateSampleSecret("telegram", minToken), + // Token with max bot_id + generateSampleSecret("telegram", maxToken), + } + + tooSmallToken := secrets.NewSecret(numeric("4") + ":A" + alphaNumericExtendedShort("34")) + tooBigToken := secrets.NewSecret(numeric("17") + ":A" + alphaNumericExtendedShort("34")) + fps := []string{ + // Token with too small bot_id + generateSampleSecret("telegram", tooSmallToken), + // Token with too big bot_id + generateSampleSecret("telegram", tooBigToken), + } + + return validate(r, tps, fps) +} diff --git a/cmd/generate/config/rules/travisci.go b/cmd/generate/config/rules/travisci.go new file mode 100644 index 000000000..458b12a7c --- /dev/null +++ b/cmd/generate/config/rules/travisci.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TravisCIAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "travisci-access-token", + Description: "Travis CI Access Token", + Regex: generateSemiGenericRegex([]string{"travis"}, alphaNumeric("22")), + SecretGroup: 1, + Keywords: []string{ + "travis", + }, + } + + // validate + tps := []string{ + generateSampleSecret("travis", secrets.NewSecret(alphaNumeric("22"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/trello.go b/cmd/generate/config/rules/trello.go new file mode 100644 index 000000000..6d713c065 --- /dev/null +++ b/cmd/generate/config/rules/trello.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TrelloAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "trello-access-token", + Description: "Trello Access Token", + Regex: generateSemiGenericRegex([]string{"trello"}, `[a-zA-Z-0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "trello", + }, + } + + // validate + tps := []string{ + generateSampleSecret("trello", secrets.NewSecret(`[a-zA-Z-0-9]{32}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twilio.go b/cmd/generate/config/rules/twilio.go new file mode 100644 index 000000000..f2c3b6f9c --- /dev/null +++ b/cmd/generate/config/rules/twilio.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Twilio() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twilio API Key", + RuleID: "twilio-api-key", + Regex: regexp.MustCompile(`SK[0-9a-fA-F]{32}`), + Keywords: []string{"twilio"}, + } + + // validate + tps := []string{ + "twilioAPIKey := \"SK" + secrets.NewSecret(hex("32")) + "\"", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twitch.go b/cmd/generate/config/rules/twitch.go new file mode 100644 index 000000000..d41d8a569 --- /dev/null +++ b/cmd/generate/config/rules/twitch.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TwitchAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "twitch-api-token", + Description: "Twitch API token", + Regex: generateSemiGenericRegex([]string{"twitch"}, alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{ + "twitch", + }, + } + + // validate + tps := []string{ + generateSampleSecret("twitch", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twitter.go b/cmd/generate/config/rules/twitter.go new file mode 100644 index 000000000..bf13e000c --- /dev/null +++ b/cmd/generate/config/rules/twitter.go @@ -0,0 +1,91 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TwitterAPIKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter API Key", + RuleID: "twitter-api-key", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("25")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("25"))), + } + return validate(r, tps, nil) +} + +func TwitterAPISecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter API Secret", + RuleID: "twitter-api-secret", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("50")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("50"))), + } + return validate(r, tps, nil) +} + +func TwitterBearerToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Bearer Token", + RuleID: "twitter-bearer-token", + Regex: generateSemiGenericRegex([]string{"twitter"}, "A{22}[a-zA-Z0-9%]{80,100}"), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret("A{22}[a-zA-Z0-9%]{80,100}")), + } + return validate(r, tps, nil) +} + +func TwitterAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Access Token", + RuleID: "twitter-access-token", + Regex: generateSemiGenericRegex([]string{"twitter"}, "[0-9]{15,25}-[a-zA-Z0-9]{20,40}"), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret("[0-9]{15,25}-[a-zA-Z0-9]{20,40}")), + } + return validate(r, tps, nil) +} + +func TwitterAccessSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Access Secret", + RuleID: "twitter-access-secret", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("45")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("45"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/typeform.go b/cmd/generate/config/rules/typeform.go new file mode 100644 index 000000000..3d5214873 --- /dev/null +++ b/cmd/generate/config/rules/typeform.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Typeform() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "typeform-api-token", + Description: "Typeform API token", + Regex: generateSemiGenericRegex([]string{"typeform"}, + `tfp_[a-z0-9\-_\.=]{59}`), + SecretGroup: 1, + Keywords: []string{ + "tfp_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("typeformAPIToken", "tfp_"+secrets.NewSecret(alphaNumericExtended("59"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/vault.go b/cmd/generate/config/rules/vault.go new file mode 100644 index 000000000..4645f5608 --- /dev/null +++ b/cmd/generate/config/rules/vault.go @@ -0,0 +1,38 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func VaultServiceToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Vault Service Token", + RuleID: "vault-service-token", + Regex: generateUniqueTokenRegex(`hvs\.[a-z0-9_-]{90,100}`), + Keywords: []string{"hvs"}, + } + + // validate + tps := []string{ + generateSampleSecret("vault", "hvs."+secrets.NewSecret(alphaNumericExtendedShort("90"))), + } + return validate(r, tps, nil) +} + +func VaultBatchToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Vault Batch Token", + RuleID: "vault-batch-token", + Regex: generateUniqueTokenRegex(`hvb\.[a-z0-9_-]{138,212}`), + Keywords: []string{"hvb"}, + } + + // validate + tps := []string{ + generateSampleSecret("vault", "hvb."+secrets.NewSecret(alphaNumericExtendedShort("138"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/yandex.go b/cmd/generate/config/rules/yandex.go new file mode 100644 index 000000000..f1fcce11a --- /dev/null +++ b/cmd/generate/config/rules/yandex.go @@ -0,0 +1,69 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func YandexAWSAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-aws-access-token", + Description: "Yandex AWS Access Token", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `YC[a-zA-Z0-9_\-]{38}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`YC[a-zA-Z0-9_\-]{38}`)), + } + return validate(r, tps, nil) +} + +func YandexAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-api-key", + Description: "Yandex API Key", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `AQVN[A-Za-z0-9_\-]{35,38}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`AQVN[A-Za-z0-9_\-]{35,38}`)), + } + return validate(r, tps, nil) +} + +func YandexAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-access-token", + Description: "Yandex Access Token", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/zendesk.go b/cmd/generate/config/rules/zendesk.go new file mode 100644 index 000000000..ec263c322 --- /dev/null +++ b/cmd/generate/config/rules/zendesk.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ZendeskSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "zendesk-secret-key", + Description: "Zendesk Secret Key", + Regex: generateSemiGenericRegex([]string{"zendesk"}, alphaNumeric("40")), + SecretGroup: 1, + Keywords: []string{ + "zendesk", + }, + } + + // validate + tps := []string{ + generateSampleSecret("zendesk", secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/secrets/regen.go b/cmd/generate/secrets/regen.go new file mode 100644 index 000000000..ee7496eaa --- /dev/null +++ b/cmd/generate/secrets/regen.go @@ -0,0 +1,15 @@ +// Package reggen generates text based on regex definitions +// This is a slightly altered version of https://github.com/lucasjones/reggen +package secrets + +import ( + "github.com/lucasjones/reggen" +) + +func NewSecret(regex string) string { + g, err := reggen.NewGenerator(regex) + if err != nil { + panic(err) + } + return g.Generate(1) +} diff --git a/cmd/protect.go b/cmd/protect.go new file mode 100644 index 000000000..434d6843e --- /dev/null +++ b/cmd/protect.go @@ -0,0 +1,105 @@ +package cmd + +import ( + "os" + "path/filepath" + "time" + + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" + "github.com/zricethezav/gitleaks/v8/report" +) + +func init() { + protectCmd.Flags().Bool("staged", false, "detect secrets in a --staged state") + rootCmd.AddCommand(protectCmd) +} + +var protectCmd = &cobra.Command{ + Use: "protect", + Short: "protect secrets in code", + Run: runProtect, +} + +func runProtect(cmd *cobra.Command, args []string) { + initConfig() + var vc config.ViperConfig + + if err := viper.Unmarshal(&vc); err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg, err := vc.Translate() + if err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + + cfg.Path, _ = cmd.Flags().GetString("config") + exitCode, _ := cmd.Flags().GetInt("exit-code") + staged, _ := cmd.Flags().GetBool("staged") + start := time.Now() + + // Setup detector + detector := detect.NewDetector(cfg) + detector.Config.Path, err = cmd.Flags().GetString("config") + if err != nil { + log.Fatal().Err(err).Msg("") + } + source, err := cmd.Flags().GetString("source") + if err != nil { + log.Fatal().Err(err).Msg("") + } + // if config path is not set, then use the {source}/.gitleaks.toml path. + // note that there may not be a `{source}/.gitleaks.toml` file, this is ok. + if detector.Config.Path == "" { + detector.Config.Path = filepath.Join(source, ".gitleaks.toml") + } + // set verbose flag + if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil { + log.Fatal().Err(err).Msg("") + } + // set redact flag + if detector.Redact, err = cmd.Flags().GetBool("redact"); err != nil { + log.Fatal().Err(err).Msg("") + } + + // get log options for git scan + logOpts, err := cmd.Flags().GetString("log-opts") + if err != nil { + log.Fatal().Err(err).Msg("") + } + + // start git scan + var findings []report.Finding + if staged { + findings, err = detector.DetectGit(source, logOpts, detect.ProtectStagedType) + } else { + findings, err = detector.DetectGit(source, logOpts, detect.ProtectType) + } + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + + // log info about the scan + log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("leaks found: %d", len(findings)) + } else { + log.Info().Msg("no leaks found") + } + + reportPath, _ := cmd.Flags().GetString("report-path") + ext, _ := cmd.Flags().GetString("report-format") + if reportPath != "" { + if err = report.Write(findings, cfg, ext, reportPath); err != nil { + log.Fatal().Err(err).Msg("") + } + } + if len(findings) != 0 { + os.Exit(exitCode) + } +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 000000000..fcb29f26a --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,147 @@ +package cmd + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const banner = ` + ○ + │╲ + │ ○ + ○ ░ + ░ gitleaks + +` + +const configDescription = `config file path +order of precedence: +1. --config/-c +2. env var GITLEAKS_CONFIG +3. (--source/-s)/.gitleaks.toml +If none of the three options are used, then gitleaks will use the default config` + +var rootCmd = &cobra.Command{ + Use: "gitleaks", + Short: "Gitleaks scans code, past or present, for secrets", +} + +func init() { + cobra.OnInitialize(initLog) + rootCmd.PersistentFlags().StringP("config", "c", "", configDescription) + rootCmd.PersistentFlags().Int("exit-code", 1, "exit code when leaks have been encountered") + rootCmd.PersistentFlags().StringP("source", "s", ".", "path to source (default: $PWD)") + rootCmd.PersistentFlags().StringP("report-path", "r", "", "report file") + rootCmd.PersistentFlags().StringP("report-format", "f", "json", "output format (json, csv, sarif)") + rootCmd.PersistentFlags().StringP("baseline-path", "b", "", "path to baseline with issues that can be ignored") + rootCmd.PersistentFlags().StringP("log-level", "l", "info", "log level (trace, debug, info, warn, error, fatal)") + rootCmd.PersistentFlags().BoolP("verbose", "v", false, "show verbose output from scan") + rootCmd.PersistentFlags().Bool("redact", false, "redact secrets from logs and stdout") + rootCmd.PersistentFlags().Bool("no-banner", false, "suppress banner") + err := viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config")) + if err != nil { + log.Fatal().Msgf("err binding config %s", err.Error()) + } +} + +func initLog() { + zerolog.SetGlobalLevel(zerolog.InfoLevel) + ll, err := rootCmd.Flags().GetString("log-level") + if err != nil { + log.Fatal().Msg(err.Error()) + } + switch strings.ToLower(ll) { + case "trace": + zerolog.SetGlobalLevel(zerolog.TraceLevel) + case "debug": + zerolog.SetGlobalLevel(zerolog.DebugLevel) + case "info": + zerolog.SetGlobalLevel(zerolog.InfoLevel) + case "warn": + zerolog.SetGlobalLevel(zerolog.WarnLevel) + case "err", "error": + zerolog.SetGlobalLevel(zerolog.ErrorLevel) + case "fatal": + zerolog.SetGlobalLevel(zerolog.FatalLevel) + default: + zerolog.SetGlobalLevel(zerolog.InfoLevel) + } +} + +func initConfig() { + hideBanner, err := rootCmd.Flags().GetBool("no-banner") + if err != nil { + log.Fatal().Msg(err.Error()) + } + if !hideBanner { + _, _ = fmt.Fprint(os.Stderr, banner) + } + cfgPath, err := rootCmd.Flags().GetString("config") + if err != nil { + log.Fatal().Msg(err.Error()) + } + if cfgPath != "" { + viper.SetConfigFile(cfgPath) + log.Debug().Msgf("using gitleaks config %s from `--config`", cfgPath) + } else if os.Getenv("GITLEAKS_CONFIG") != "" { + envPath := os.Getenv("GITLEAKS_CONFIG") + viper.SetConfigFile(envPath) + log.Debug().Msgf("using gitleaks config from GITLEAKS_CONFIG env var: %s", envPath) + } else { + source, err := rootCmd.Flags().GetString("source") + if err != nil { + log.Fatal().Msg(err.Error()) + } + fileInfo, err := os.Stat(source) + if err != nil { + log.Fatal().Msg(err.Error()) + } + + if !fileInfo.IsDir() { + log.Debug().Msgf("unable to load gitleaks config from %s since --source=%s is a file, using default config", + filepath.Join(source, ".gitleaks.toml"), source) + viper.SetConfigType("toml") + if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil { + log.Fatal().Msgf("err reading toml %s", err.Error()) + } + return + } + + if _, err := os.Stat(filepath.Join(source, ".gitleaks.toml")); os.IsNotExist(err) { + log.Debug().Msgf("no gitleaks config found in path %s, using default gitleaks config", filepath.Join(source, ".gitleaks.toml")) + viper.SetConfigType("toml") + if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil { + log.Fatal().Msgf("err reading default config toml %s", err.Error()) + } + return + } else { + log.Debug().Msgf("using existing gitleaks config %s from `(--source)/.gitleaks.toml`", filepath.Join(source, ".gitleaks.toml")) + } + + viper.AddConfigPath(source) + viper.SetConfigName(".gitleaks") + viper.SetConfigType("toml") + } + if err := viper.ReadInConfig(); err != nil { + log.Fatal().Msgf("unable to load gitleaks config, err: %s", err) + } +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + if strings.Contains(err.Error(), "unknown flag") { + // exit code 126: Command invoked cannot execute + os.Exit(126) + } + log.Fatal().Msg(err.Error()) + } +} diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 000000000..9594a203f --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var Version = "version is set by build process" + +func init() { + rootCmd.AddCommand(versionCmd) +} + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "display gitleaks version", + Run: runVersion, +} + +func runVersion(cmd *cobra.Command, args []string) { + fmt.Println(Version) +} diff --git a/config/allowlist.go b/config/allowlist.go new file mode 100644 index 000000000..014286363 --- /dev/null +++ b/config/allowlist.go @@ -0,0 +1,60 @@ +package config + +import ( + "regexp" + "strings" +) + +// Allowlist allows a rule to be ignored for specific +// regexes, paths, and/or commits +type Allowlist struct { + // Short human readable description of the allowlist. + Description string + + // Regexes is slice of content regular expressions that are allowed to be ignored. + Regexes []*regexp.Regexp + + // Paths is a slice of path regular expressions that are allowed to be ignored. + Paths []*regexp.Regexp + + // Commits is a slice of commit SHAs that are allowed to be ignored. + Commits []string + + // StopWords is a slice of stop words that are allowed to be ignored. + // This targets the _secret_, not the content of the regex match like the + // Regexes slice. + StopWords []string +} + +// CommitAllowed returns true if the commit is allowed to be ignored. +func (a *Allowlist) CommitAllowed(c string) bool { + if c == "" { + return false + } + for _, commit := range a.Commits { + if commit == c { + return true + } + } + return false +} + +// PathAllowed returns true if the path is allowed to be ignored. +func (a *Allowlist) PathAllowed(path string) bool { + return anyRegexMatch(path, a.Paths) +} + +// RegexAllowed returns true if the regex is allowed to be ignored. +func (a *Allowlist) RegexAllowed(s string) bool { + return anyRegexMatch(s, a.Regexes) +} + +func (a *Allowlist) ContainsStopWord(s string) bool { + s = strings.ToLower(s) + for _, stopWord := range a.StopWords { + if strings.Contains(s, strings.ToLower(stopWord)) { + return true + } + } + return false +} diff --git a/config/allowlist_test.go b/config/allowlist_test.go new file mode 100644 index 000000000..be416ee3d --- /dev/null +++ b/config/allowlist_test.go @@ -0,0 +1,93 @@ +package config + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCommitAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + commit string + commitAllowed bool + }{ + { + allowlist: Allowlist{ + Commits: []string{"commitA"}, + }, + commit: "commitA", + commitAllowed: true, + }, + { + allowlist: Allowlist{ + Commits: []string{"commitB"}, + }, + commit: "commitA", + commitAllowed: false, + }, + { + allowlist: Allowlist{ + Commits: []string{"commitB"}, + }, + commit: "", + commitAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.commitAllowed, tt.allowlist.CommitAllowed(tt.commit)) + } +} + +func TestRegexAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + secret string + regexAllowed bool + }{ + { + allowlist: Allowlist{ + Regexes: []*regexp.Regexp{regexp.MustCompile("matchthis")}, + }, + secret: "a secret: matchthis, done", + regexAllowed: true, + }, + { + allowlist: Allowlist{ + Regexes: []*regexp.Regexp{regexp.MustCompile("matchthis")}, + }, + secret: "a secret", + regexAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.regexAllowed, tt.allowlist.RegexAllowed(tt.secret)) + } +} + +func TestPathAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + path string + pathAllowed bool + }{ + { + allowlist: Allowlist{ + Paths: []*regexp.Regexp{regexp.MustCompile("path")}, + }, + path: "a path", + pathAllowed: true, + }, + { + allowlist: Allowlist{ + Paths: []*regexp.Regexp{regexp.MustCompile("path")}, + }, + path: "a ???", + pathAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.pathAllowed, tt.allowlist.PathAllowed(tt.path)) + } +} diff --git a/config/config.go b/config/config.go index b16918aec..acd887cef 100644 --- a/config/config.go +++ b/config/config.go @@ -1,249 +1,249 @@ package config import ( + _ "embed" "fmt" - "path" "regexp" - "strconv" + "strings" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/BurntSushi/toml" - log "github.com/sirupsen/logrus" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" ) -// AllowList is struct containing items that if encountered will allowlist -// a commit/line of code that would be considered a leak. -type AllowList struct { - Description string - Regexes []*regexp.Regexp - Commits []string - Files []*regexp.Regexp - Paths []*regexp.Regexp - Repos []*regexp.Regexp -} +//go:embed gitleaks.toml +var DefaultConfig string -// Entropy represents an entropy range -type Entropy struct { - Min float64 - Max float64 - Group int -} +// use to keep track of how many configs we can extend +// yea I know, globals bad +var extendDepth int -// Rule is a struct that contains information that is loaded from a gitleaks config. -// This struct is used in the Config struct as an array of Rules and is iterated -// over during an scan. Each rule will be checked. If a regex match is found AND -// that match is not allowlisted (globally or locally), then a leak will be appended -// to the final scan report. -type Rule struct { - Description string - Regex *regexp.Regexp - File *regexp.Regexp - Path *regexp.Regexp - Tags []string - AllowList AllowList - Entropies []Entropy -} +const maxExtendDepth = 2 -// Config is a composite struct of Rules and Allowlists -// Each Rule contains a description, regular expression, tags, and allowlists if available -type Config struct { - Rules []Rule - Allowlist AllowList -} - -// TomlAllowList is a struct used in the TomlLoader that loads in allowlists from -// specific rules or globally at the top level config -type TomlAllowList struct { +// ViperConfig is the config struct used by the Viper config package +// to parse the config file. This struct does not include regular expressions. +// It is used as an intermediary to convert the Viper config to the Config struct. +type ViperConfig struct { Description string - Regexes []string - Commits []string - Files []string - Paths []string - Repos []string -} - -// TomlLoader gets loaded with the values from a gitleaks toml config -// see the config in config/defaults.go for an example. TomlLoader is used -// to generate Config values (compiling regexes, etc). -type TomlLoader struct { - AllowList TomlAllowList - Rules []struct { + Extend Extend + Rules []struct { + ID string Description string + Entropy float64 + SecretGroup int Regex string - File string + Keywords []string Path string Tags []string - Entropies []struct { - Min string - Max string - Group string + + Allowlist struct { + Regexes []string + Paths []string + Commits []string + StopWords []string } - AllowList TomlAllowList + } + Allowlist struct { + Regexes []string + Paths []string + Commits []string + StopWords []string } } -// NewConfig will create a new config struct which contains -// rules on how gitleaks will proceed with its scan. -// If no options are passed via cli then NewConfig will return -// a default config which can be seen in config.go -func NewConfig(options options.Options) (Config, error) { - var cfg Config - tomlLoader := TomlLoader{} - - var err error - if options.Config != "" { - _, err = toml.DecodeFile(options.Config, &tomlLoader) - // append a allowlist rule for allowlisting the config - tomlLoader.AllowList.Files = append(tomlLoader.AllowList.Files, path.Base(options.Config)) - } else { - _, err = toml.Decode(DefaultConfig, &tomlLoader) - } - if err != nil { - return cfg, err - } +// Config is a configuration struct that contains rules and an allowlist if present. +type Config struct { + Extend Extend + Path string + Description string + Rules map[string]Rule + Allowlist Allowlist + Keywords []string - cfg, err = tomlLoader.Parse() - if err != nil { - return cfg, err - } + // used to keep sarif results consistent + orderedRules []string +} - return cfg, nil +// Extend is a struct that allows users to define how they want their +// configuration extended by other configuration files. +type Extend struct { + Path string + URL string + UseDefault bool } -// Parse will parse the values set in a TomlLoader and use those values -// to create compiled regular expressions and rules used in scans -func (tomlLoader TomlLoader) Parse() (Config, error) { - var cfg Config - for _, rule := range tomlLoader.Rules { - // check and make sure the rule is valid - if rule.Regex == "" && rule.Path == "" && rule.File == "" && len(rule.Entropies) == 0 { - log.Warnf("Rule %s does not define any actionable data", rule.Description) - continue - } - re, err := regexp.Compile(rule.Regex) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) +func (vc *ViperConfig) Translate() (Config, error) { + var ( + keywords []string + orderedRules []string + ) + rulesMap := make(map[string]Rule) + + for _, r := range vc.Rules { + var allowlistRegexes []*regexp.Regexp + for _, a := range r.Allowlist.Regexes { + allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a)) } - fileNameRe, err := regexp.Compile(rule.File) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + var allowlistPaths []*regexp.Regexp + for _, a := range r.Allowlist.Paths { + allowlistPaths = append(allowlistPaths, regexp.MustCompile(a)) } - filePathRe, err := regexp.Compile(rule.Path) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - - // rule specific allowlists - var allowList AllowList - // rule specific regexes - for _, re := range rule.AllowList.Regexes { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + if r.Keywords == nil { + r.Keywords = []string{} + } else { + for _, k := range r.Keywords { + keywords = append(keywords, strings.ToLower(k)) } - allowList.Regexes = append(allowList.Regexes, allowListedRegex) } - // rule specific filenames - for _, re := range rule.AllowList.Files { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - allowList.Files = append(allowList.Files, allowListedRegex) + if r.Tags == nil { + r.Tags = []string{} } - // rule specific paths - for _, re := range rule.AllowList.Paths { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - allowList.Paths = append(allowList.Paths, allowListedRegex) + var configRegex *regexp.Regexp + var configPathRegex *regexp.Regexp + if r.Regex == "" { + configRegex = nil + } else { + configRegex = regexp.MustCompile(r.Regex) } - - var entropies []Entropy - for _, e := range rule.Entropies { - min, err := strconv.ParseFloat(e.Min, 64) - if err != nil { - return cfg, err - } - max, err := strconv.ParseFloat(e.Max, 64) - if err != nil { - return cfg, err - } - if e.Group == "" { - e.Group = "0" - } - group, err := strconv.ParseInt(e.Group, 10, 64) - if err != nil { - return cfg, err - } else if int(group) >= len(re.SubexpNames()) { - return cfg, fmt.Errorf("problem loading config: group cannot be higher than number of groups in regexp") - } else if group < 0 { - return cfg, fmt.Errorf("problem loading config: group cannot be lower than 0") - } else if min > 8.0 || min < 0.0 || max > 8.0 || max < 0.0 { - return cfg, fmt.Errorf("problem loading config: invalid entropy ranges, must be within 0.0-8.0") - } else if min > max { - return cfg, fmt.Errorf("problem loading config: entropy Min value cannot be higher than Max value") - } - - entropies = append(entropies, Entropy{Min: min, Max: max, Group: int(group)}) + if r.Path == "" { + configPathRegex = nil + } else { + configPathRegex = regexp.MustCompile(r.Path) } - r := Rule{ - Description: rule.Description, - Regex: re, - File: fileNameRe, - Path: filePathRe, - Tags: rule.Tags, - AllowList: allowList, - Entropies: entropies, + Description: r.Description, + RuleID: r.ID, + Regex: configRegex, + Path: configPathRegex, + SecretGroup: r.SecretGroup, + Entropy: r.Entropy, + Tags: r.Tags, + Keywords: r.Keywords, + Allowlist: Allowlist{ + Regexes: allowlistRegexes, + Paths: allowlistPaths, + Commits: r.Allowlist.Commits, + StopWords: r.Allowlist.StopWords, + }, } + orderedRules = append(orderedRules, r.RuleID) - cfg.Rules = append(cfg.Rules, r) + if r.Regex != nil && r.SecretGroup > r.Regex.NumSubexp() { + return Config{}, fmt.Errorf("%s invalid regex secret group %d, max regex secret group %d", r.Description, r.SecretGroup, r.Regex.NumSubexp()) + } + rulesMap[r.RuleID] = r + } + var allowlistRegexes []*regexp.Regexp + for _, a := range vc.Allowlist.Regexes { + allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a)) + } + var allowlistPaths []*regexp.Regexp + for _, a := range vc.Allowlist.Paths { + allowlistPaths = append(allowlistPaths, regexp.MustCompile(a)) + } + c := Config{ + Description: vc.Description, + Extend: vc.Extend, + Rules: rulesMap, + Allowlist: Allowlist{ + Regexes: allowlistRegexes, + Paths: allowlistPaths, + Commits: vc.Allowlist.Commits, + StopWords: vc.Allowlist.StopWords, + }, + Keywords: keywords, + orderedRules: orderedRules, } - // global regex allowLists - for _, allowListRegex := range tomlLoader.AllowList.Regexes { - re, err := regexp.Compile(allowListRegex) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + if maxExtendDepth != extendDepth { + // disallow both usedefault and path from being set + if c.Extend.Path != "" && c.Extend.UseDefault { + log.Fatal().Msg("unable to load config due to extend.path and extend.useDefault being set") + } + if c.Extend.UseDefault { + c.extendDefault() + } else if c.Extend.Path != "" { + c.extendPath() } - cfg.Allowlist.Regexes = append(cfg.Allowlist.Regexes, re) + } - // global file name allowLists - for _, allowListFileName := range tomlLoader.AllowList.Files { - re, err := regexp.Compile(allowListFileName) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + return c, nil +} + +func (c *Config) OrderedRules() []Rule { + var orderedRules []Rule + for _, id := range c.orderedRules { + if _, ok := c.Rules[id]; ok { + orderedRules = append(orderedRules, c.Rules[id]) } - cfg.Allowlist.Files = append(cfg.Allowlist.Files, re) } + return orderedRules +} - // global file path allowLists - for _, allowListFilePath := range tomlLoader.AllowList.Paths { - re, err := regexp.Compile(allowListFilePath) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - cfg.Allowlist.Paths = append(cfg.Allowlist.Paths, re) +func (c *Config) extendDefault() { + extendDepth++ + viper.SetConfigType("toml") + if err := viper.ReadConfig(strings.NewReader(DefaultConfig)); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return } + defaultViperConfig := ViperConfig{} + if err := viper.Unmarshal(&defaultViperConfig); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + cfg, err := defaultViperConfig.Translate() + if err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + log.Debug().Msg("extending config with default config") + c.extend(cfg) - // global repo allowLists - for _, allowListRepo := range tomlLoader.AllowList.Repos { - re, err := regexp.Compile(allowListRepo) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - cfg.Allowlist.Repos = append(cfg.Allowlist.Repos, re) +} + +func (c *Config) extendPath() { + extendDepth++ + viper.SetConfigFile(c.Extend.Path) + if err := viper.ReadInConfig(); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + extensionViperConfig := ViperConfig{} + if err := viper.Unmarshal(&extensionViperConfig); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return } + cfg, err := extensionViperConfig.Translate() + if err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + log.Debug().Msgf("extending config with %s", c.Extend.Path) + c.extend(cfg) +} - cfg.Allowlist.Commits = tomlLoader.AllowList.Commits - cfg.Allowlist.Description = tomlLoader.AllowList.Description +func (c *Config) extendURL() { + // TODO +} + +func (c *Config) extend(extensionConfig Config) { + for ruleID, rule := range extensionConfig.Rules { + if _, ok := c.Rules[ruleID]; !ok { + log.Trace().Msgf("adding %s to base config", ruleID) + c.Rules[ruleID] = rule + c.Keywords = append(c.Keywords, rule.Keywords...) + } + } - return cfg, nil + // append allowlists, not attempting to merge + c.Allowlist.Commits = append(c.Allowlist.Commits, + extensionConfig.Allowlist.Commits...) + c.Allowlist.Paths = append(c.Allowlist.Paths, + extensionConfig.Allowlist.Paths...) + c.Allowlist.Regexes = append(c.Allowlist.Regexes, + extensionConfig.Allowlist.Regexes...) } diff --git a/config/config_test.go b/config/config_test.go index d824d17c8..7c2ad366f 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,127 +5,144 @@ import ( "regexp" "testing" - "github.com/zricethezav/gitleaks/v6/options" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" ) -func TestParse(t *testing.T) { +const configPath = "../testdata/config/" + +func TestTranslate(t *testing.T) { tests := []struct { - description string - opts options.Options - wantErr error - wantFileRegex *regexp.Regexp - wantMessages *regexp.Regexp - wantAllowlist AllowList + cfgName string + cfg Config + wantError error }{ { - description: "default config", - opts: options.Options{}, - }, - { - description: "test successful load", - opts: options.Options{ - Config: "../test_data/test_configs/aws_key.toml", + cfgName: "allow_aws_re", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Regexes: []*regexp.Regexp{ + regexp.MustCompile("AKIALALEMEL33243OLIA"), + }, + }, + }, + }, }, }, { - description: "test bad toml", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key.toml", + cfgName: "allow_commit", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Commits: []string{"allowthiscommit"}, + }, + }, + }, }, - wantErr: fmt.Errorf("Near line 7 (last key parsed 'rules.description'): expected value but found \"AWS\" instead"), }, { - description: "test bad regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_regex_aws_key.toml", + cfgName: "allow_path", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Paths: []*regexp.Regexp{ + regexp.MustCompile(".go"), + }, + }, + }, + }, }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: invalid nested repetition operator: `???`"), }, { - description: "test bad global allowlist file regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key_global_allowlist_file.toml", + cfgName: "entropy_group", + cfg: Config{ + Rules: map[string]Rule{"discord-api-key": { + Description: "Discord API key", + Regex: regexp.MustCompile(`(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]`), + RuleID: "discord-api-key", + Allowlist: Allowlist{}, + Entropy: 3.5, + SecretGroup: 3, + Tags: []string{}, + Keywords: []string{}, + }, + }, }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: missing argument to repetition operator: `??`"), }, { - description: "test bad global file regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key_file_regex.toml", - }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: missing argument to repetition operator: `??`"), + cfgName: "bad_entropy_group", + cfg: Config{}, + wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"), }, { - description: "test successful load big ol thing", - opts: options.Options{ - Config: "../test_data/test_configs/large.toml", + cfgName: "base", + cfg: Config{ + Rules: map[string]Rule{ + "aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + }, + "aws-secret-key": { + Description: "AWS Secret Key", + Regex: regexp.MustCompile(`(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}`), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-secret-key", + }, + "aws-secret-key-again": { + Description: "AWS Secret Key", + Regex: regexp.MustCompile(`(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}`), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-secret-key-again", + }, + }, }, }, - { - description: "test load entropy", - opts: options.Options{ - Config: "../test_data/test_configs/entropy.toml", - }, - }, - { - description: "test entropy bad range", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_1.toml", - }, - wantErr: fmt.Errorf("problem loading config: entropy Min value cannot be higher than Max value"), - }, - { - description: "test entropy value max", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_2.toml", - }, - wantErr: fmt.Errorf("strconv.ParseFloat: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value min", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_3.toml", - }, - wantErr: fmt.Errorf("strconv.ParseFloat: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_4.toml", - }, - wantErr: fmt.Errorf("strconv.ParseInt: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_5.toml", - }, - wantErr: fmt.Errorf("problem loading config: group cannot be lower than 0"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_6.toml", - }, - wantErr: fmt.Errorf("problem loading config: group cannot be higher than number of groups in regexp"), - }, - { - description: "test entropy range limits", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_7.toml", - }, - wantErr: fmt.Errorf("problem loading config: invalid entropy ranges, must be within 0.0-8.0"), - }, } - for _, test := range tests { - _, err := NewConfig(test.opts) + for _, tt := range tests { + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(tt.cfgName) + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc ViperConfig + err = viper.Unmarshal(&vc) if err != nil { - if test.wantErr == nil { - t.Error(test.description, err) - } else if test.wantErr.Error() != err.Error() { - t.Errorf("expected err: %s, got %s", test.wantErr, err) + t.Error(err) + } + cfg, err := vc.Translate() + if tt.wantError != nil { + if err == nil { + t.Errorf("expected error") } + assert.Equal(t, tt.wantError, err) } + + assert.Equal(t, cfg.Rules, tt.cfg.Rules) } } diff --git a/config/default.go b/config/default.go deleted file mode 100644 index 854c9fc36..000000000 --- a/config/default.go +++ /dev/null @@ -1,139 +0,0 @@ -package config - -// DefaultConfig is the default gitleaks configuration. If --config={path-to-config} is set than the config located -// at {path-to-config} will be used. Alternatively, if --repo-config is set then gitleaks will attempt to -// use the config set in a gitleaks.toml or .gitleaks.toml file in the repo that is run with --repo-config set. -const DefaultConfig = ` -title = "gitleaks config" - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?[0-9a-z]{35,44}''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?[0-9a-z]{18,25}''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)[0-9a-zA-Z]{35,40}''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?[0-9a-z]{16}''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "Asymmetric Private Key" - regex = '''-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----''' - tags = ["key", "AsymmetricPrivateKey"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - -[[rules]] - description = "Google (GCP) Service Account" - regex = '''"type": "service_account"''' - tags = ["key", "Google"] - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "SendGrid API Key" - regex = '''SG\.[\w_]{16,32}\.[\w_]{16,64}''' - tags = ["key", "SendGrid"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?SK[0-9a-f]{32}''' - tags = ["key", "twilio"] - -[allowlist] - description = "Allowlisted files" - files = ['''^\.?gitleaks.toml$''', - '''(.*?)(jpg|gif|doc|pdf|bin)$''', - '''(go.mod|go.sum)$'''] -` diff --git a/config/gitleaks.toml b/config/gitleaks.toml new file mode 100644 index 000000000..60f4652d4 --- /dev/null +++ b/config/gitleaks.toml @@ -0,0 +1,2758 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md + +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''', + '''node_modules''', + '''vendor''', +] + +[[rules]] +description = "Adafruit API Key" +id = "adafruit-api-key" +regex = '''(?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "adafruit", +] + +[[rules]] +description = "Adobe Client ID (OAuth Web)" +id = "adobe-client-id" +regex = '''(?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "adobe", +] + +[[rules]] +description = "Adobe Client Secret" +id = "adobe-client-secret" +regex = '''(?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "p8e-", +] + +[[rules]] +description = "Age secret key" +id = "age secret key" +regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}''' +keywords = [ + "age-secret-key-1", +] + +[[rules]] +description = "Airtable API Key" +id = "airtable-api-key" +regex = '''(?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "airtable", +] + +[[rules]] +description = "Algolia API Key" +id = "algolia-api-key" +regex = '''(?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "algolia", +] + +[[rules]] +description = "Alibaba AccessKey ID" +id = "alibaba-access-key-id" +regex = '''(?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ltai", +] + +[[rules]] +description = "Alibaba Secret Key" +id = "alibaba-secret-key" +regex = '''(?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "alibaba", +] + +[[rules]] +description = "Asana Client ID" +id = "asana-client-id" +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "asana", +] + +[[rules]] +description = "Asana Client Secret" +id = "asana-client-secret" +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "asana", +] + +[[rules]] +description = "Atlassian API token" +id = "atlassian-api-token" +regex = '''(?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "atlassian","confluence","jira", +] + +[[rules]] +description = "AWS" +id = "aws-access-token" +regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' +keywords = [ + "akia","agpa","aida","aroa","aipa","anpa","anva","asia", +] + +[[rules]] +description = "Beamer API token" +id = "beamer-api-token" +regex = '''(?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "beamer", +] + +[[rules]] +description = "Bitbucket Client ID" +id = "bitbucket-client-id" +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bitbucket", +] + +[[rules]] +description = "Bitbucket Client Secret" +id = "bitbucket-client-secret" +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bitbucket", +] + +[[rules]] +description = "Bittrex Access Key" +id = "bittrex-access-key" +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bittrex", +] + +[[rules]] +description = "Bittrex Secret Key" +id = "bittrex-secret-key" +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bittrex", +] + +[[rules]] +description = "Clojars API token" +id = "clojars-api-token" +regex = '''(?i)(CLOJARS_)[a-z0-9]{60}''' +keywords = [ + "clojars", +] + +[[rules]] +description = "Codecov Access Token" +id = "codecov-access-token" +regex = '''(?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "codecov", +] + +[[rules]] +description = "Coinbase Access Token" +id = "coinbase-access-token" +regex = '''(?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "coinbase", +] + +[[rules]] +description = "Confluent Access Token" +id = "confluent-access-token" +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "confluent", +] + +[[rules]] +description = "Confluent Secret Key" +id = "confluent-secret-key" +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "confluent", +] + +[[rules]] +description = "Contentful delivery API token" +id = "contentful-delivery-api-token" +regex = '''(?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "contentful", +] + +[[rules]] +description = "Databricks API token" +id = "databricks-api-token" +regex = '''(?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dapi", +] + +[[rules]] +description = "Datadog Access Token" +id = "datadog-access-token" +regex = '''(?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "datadog", +] + +[[rules]] +description = "DigitalOcean OAuth Access Token" +id = "digitalocean-access-token" +regex = '''(?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "doo_v1_", +] + +[[rules]] +description = "DigitalOcean Personal Access Token" +id = "digitalocean-pat" +regex = '''(?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dop_v1_", +] + +[[rules]] +description = "DigitalOcean OAuth Refresh Token" +id = "digitalocean-refresh-token" +regex = '''(?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dor_v1_", +] + +[[rules]] +description = "Discord API key" +id = "discord-api-token" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Discord client ID" +id = "discord-client-id" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Discord client secret" +id = "discord-client-secret" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Doppler API token" +id = "doppler-api-token" +regex = '''(dp\.pt\.)(?i)[a-z0-9]{43}''' +keywords = [ + "doppler", +] + +[[rules]] +description = "Droneci Access Token" +id = "droneci-access-token" +regex = '''(?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "droneci", +] + +[[rules]] +description = "Dropbox API secret" +id = "dropbox-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dropbox", +] + +[[rules]] +description = "Dropbox long lived API token" +id = "dropbox-long-lived-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +description = "Dropbox short lived API token" +id = "dropbox-short-lived-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +description = "Duffel API token" +id = "duffel-api-token" +regex = '''duffel_(test|live)_(?i)[a-z0-9_\-=]{43}''' +keywords = [ + "duffel", +] + +[[rules]] +description = "Dynatrace API token" +id = "dynatrace-api-token" +regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}''' +keywords = [ + "dynatrace", +] + +[[rules]] +description = "EasyPost API token" +id = "easypost-api-token" +regex = '''EZAK(?i)[a-z0-9]{54}''' +keywords = [ + "ezak", +] + +[[rules]] +description = "EasyPost test API token" +id = "easypost-test-api-token" +regex = '''EZTK(?i)[a-z0-9]{54}''' +keywords = [ + "eztk", +] + +[[rules]] +description = "Etsy Access Token" +id = "etsy-access-token" +regex = '''(?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "etsy", +] + +[[rules]] +description = "Facebook" +id = "facebook" +regex = '''(?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "facebook", +] + +[[rules]] +description = "Fastly API key" +id = "fastly-api-token" +regex = '''(?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "fastly", +] + +[[rules]] +description = "Finicity API token" +id = "finicity-api-token" +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finicity", +] + +[[rules]] +description = "Finicity Client Secret" +id = "finicity-client-secret" +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finicity", +] + +[[rules]] +description = "Finnhub Access Token" +id = "finnhub-access-token" +regex = '''(?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finnhub", +] + +[[rules]] +description = "Flickr Access Token" +id = "flickr-access-token" +regex = '''(?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "flickr", +] + +[[rules]] +description = "Flutterwave Encryption Key" +id = "flutterwave-encryption-key" +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{12}''' +keywords = [ + "flwseck_test", +] + +[[rules]] +description = "Finicity Public Key" +id = "flutterwave-public-key" +regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwpubk_test", +] + +[[rules]] +description = "Flutterwave Secret Key" +id = "flutterwave-secret-key" +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwseck_test", +] + +[[rules]] +description = "Frame.io API token" +id = "frameio-api-token" +regex = '''fio-u-(?i)[a-z0-9\-_=]{64}''' +keywords = [ + "fio-u-", +] + +[[rules]] +description = "Freshbooks Access Token" +id = "freshbooks-access-token" +regex = '''(?i)(?:freshbooks)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "freshbooks", +] + +[[rules]] +description = "GCP API key" +id = "gcp-api-key" +regex = '''(?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "aiza", +] + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-z\-_.=]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +entropy = 3.5 +keywords = [ + "key","api","token","secret","client","passwd","password","auth","access", +] +[rules.allowlist] +paths = [ + '''Database.refactorlog''' +] +stopwords= [ + "client", + "endpoint", + "vpn", + "_ec2_", + "aws_", + "authorize", + "author", + "define", + "config", + "credential", + "setting", + "sample", + "xxxxxx", + "000000", + "buffer", + "delete", + "aaaaaa", + "fewfwef", + "getenv", + "env_", + "system", + "example", + "ecdsa", + "sha256", + "sha1", + "sha2", + "md5", + "alert", + "wizard", + "target", + "onboard", + "welcome", + "page", + "exploit", + "experiment", + "expire", + "rabbitmq", + "scraper", + "widget", + "music", + "dns_", + "dns-", + "yahoo", + "want", + "json", + "action", + "script", + "fix_", + "fix-", + "develop", + "compas", + "stripe", + "service", + "master", + "metric", + "tech", + "gitignore", + "rich", + "open", + "stack", + "irc_", + "irc-", + "sublime", + "kohana", + "has_", + "has-", + "fabric", + "wordpres", + "role", + "osx_", + "osx-", + "boost", + "addres", + "queue", + "working", + "sandbox", + "internet", + "print", + "vision", + "tracking", + "being", + "generator", + "traffic", + "world", + "pull", + "rust", + "watcher", + "small", + "auth", + "full", + "hash", + "more", + "install", + "auto", + "complete", + "learn", + "paper", + "installer", + "research", + "acces", + "last", + "binding", + "spine", + "into", + "chat", + "algorithm", + "resource", + "uploader", + "video", + "maker", + "next", + "proc", + "lock", + "robot", + "snake", + "patch", + "matrix", + "drill", + "terminal", + "term", + "stuff", + "genetic", + "generic", + "identity", + "audit", + "pattern", + "audio", + "web_", + "web-", + "crud", + "problem", + "statu", + "cms-", + "cms_", + "arch", + "coffee", + "workflow", + "changelog", + "another", + "uiview", + "content", + "kitchen", + "gnu_", + "gnu-", + "gnu.", + "conf", + "couchdb", + "client", + "opencv", + "rendering", + "update", + "concept", + "varnish", + "gui_", + "gui-", + "gui.", + "version", + "shared", + "extra", + "product", + "still", + "not_", + "not-", + "not.", + "drop", + "ring", + "png_", + "png-", + "png.", + "actively", + "import", + "output", + "backup", + "start", + "embedded", + "registry", + "pool", + "semantic", + "instagram", + "bash", + "system", + "ninja", + "drupal", + "jquery", + "polyfill", + "physic", + "league", + "guide", + "pack", + "synopsi", + "sketch", + "injection", + "svg_", + "svg-", + "svg.", + "friendly", + "wave", + "convert", + "manage", + "camera", + "link", + "slide", + "timer", + "wrapper", + "gallery", + "url_", + "url-", + "url.", + "todomvc", + "requirej", + "party", + "http", + "payment", + "async", + "library", + "home", + "coco", + "gaia", + "display", + "universal", + "func", + "metadata", + "hipchat", + "under", + "room", + "config", + "personal", + "realtime", + "resume", + "database", + "testing", + "tiny", + "basic", + "forum", + "meetup", + "yet_", + "yet-", + "yet.", + "cento", + "dead", + "fluentd", + "editor", + "utilitie", + "run_", + "run-", + "run.", + "box_", + "box-", + "box.", + "bot_", + "bot-", + "bot.", + "making", + "sample", + "group", + "monitor", + "ajax", + "parallel", + "cassandra", + "ultimate", + "site", + "get_", + "get-", + "get.", + "gen_", + "gen-", + "gen.", + "gem_", + "gem-", + "gem.", + "extended", + "image", + "knife", + "asset", + "nested", + "zero", + "plugin", + "bracket", + "mule", + "mozilla", + "number", + "act_", + "act-", + "act.", + "map_", + "map-", + "map.", + "micro", + "debug", + "openshift", + "chart", + "expres", + "backend", + "task", + "source", + "translate", + "jbos", + "composer", + "sqlite", + "profile", + "mustache", + "mqtt", + "yeoman", + "have", + "builder", + "smart", + "like", + "oauth", + "school", + "guideline", + "captcha", + "filter", + "bitcoin", + "bridge", + "color", + "toolbox", + "discovery", + "new_", + "new-", + "new.", + "dashboard", + "when", + "setting", + "level", + "post", + "standard", + "port", + "platform", + "yui_", + "yui-", + "yui.", + "grunt", + "animation", + "haskell", + "icon", + "latex", + "cheat", + "lua_", + "lua-", + "lua.", + "gulp", + "case", + "author", + "without", + "simulator", + "wifi", + "directory", + "lisp", + "list", + "flat", + "adventure", + "story", + "storm", + "gpu_", + "gpu-", + "gpu.", + "store", + "caching", + "attention", + "solr", + "logger", + "demo", + "shortener", + "hadoop", + "finder", + "phone", + "pipeline", + "range", + "textmate", + "showcase", + "app_", + "app-", + "app.", + "idiomatic", + "edit", + "our_", + "our-", + "our.", + "out_", + "out-", + "out.", + "sentiment", + "linked", + "why_", + "why-", + "why.", + "local", + "cube", + "gmail", + "job_", + "job-", + "job.", + "rpc_", + "rpc-", + "rpc.", + "contest", + "tcp_", + "tcp-", + "tcp.", + "usage", + "buildout", + "weather", + "transfer", + "automated", + "sphinx", + "issue", + "sas_", + "sas-", + "sas.", + "parallax", + "jasmine", + "addon", + "machine", + "solution", + "dsl_", + "dsl-", + "dsl.", + "episode", + "menu", + "theme", + "best", + "adapter", + "debugger", + "chrome", + "tutorial", + "life", + "step", + "people", + "joomla", + "paypal", + "developer", + "solver", + "team", + "current", + "love", + "visual", + "date", + "data", + "canva", + "container", + "future", + "xml_", + "xml-", + "xml.", + "twig", + "nagio", + "spatial", + "original", + "sync", + "archived", + "refinery", + "science", + "mapping", + "gitlab", + "play", + "ext_", + "ext-", + "ext.", + "session", + "impact", + "set_", + "set-", + "set.", + "see_", + "see-", + "see.", + "migration", + "commit", + "community", + "shopify", + "what'", + "cucumber", + "statamic", + "mysql", + "location", + "tower", + "line", + "code", + "amqp", + "hello", + "send", + "index", + "high", + "notebook", + "alloy", + "python", + "field", + "document", + "soap", + "edition", + "email", + "php_", + "php-", + "php.", + "command", + "transport", + "official", + "upload", + "study", + "secure", + "angularj", + "akka", + "scalable", + "package", + "request", + "con_", + "con-", + "con.", + "flexible", + "security", + "comment", + "module", + "flask", + "graph", + "flash", + "apache", + "change", + "window", + "space", + "lambda", + "sheet", + "bookmark", + "carousel", + "friend", + "objective", + "jekyll", + "bootstrap", + "first", + "article", + "gwt_", + "gwt-", + "gwt.", + "classic", + "media", + "websocket", + "touch", + "desktop", + "real", + "read", + "recorder", + "moved", + "storage", + "validator", + "add-on", + "pusher", + "scs_", + "scs-", + "scs.", + "inline", + "asp_", + "asp-", + "asp.", + "timeline", + "base", + "encoding", + "ffmpeg", + "kindle", + "tinymce", + "pretty", + "jpa_", + "jpa-", + "jpa.", + "used", + "user", + "required", + "webhook", + "download", + "resque", + "espresso", + "cloud", + "mongo", + "benchmark", + "pure", + "cakephp", + "modx", + "mode", + "reactive", + "fuel", + "written", + "flickr", + "mail", + "brunch", + "meteor", + "dynamic", + "neo_", + "neo-", + "neo.", + "new_", + "new-", + "new.", + "net_", + "net-", + "net.", + "typo", + "type", + "keyboard", + "erlang", + "adobe", + "logging", + "ckeditor", + "message", + "iso_", + "iso-", + "iso.", + "hook", + "ldap", + "folder", + "reference", + "railscast", + "www_", + "www-", + "www.", + "tracker", + "azure", + "fork", + "form", + "digital", + "exporter", + "skin", + "string", + "template", + "designer", + "gollum", + "fluent", + "entity", + "language", + "alfred", + "summary", + "wiki", + "kernel", + "calendar", + "plupload", + "symfony", + "foundry", + "remote", + "talk", + "search", + "dev_", + "dev-", + "dev.", + "del_", + "del-", + "del.", + "token", + "idea", + "sencha", + "selector", + "interface", + "create", + "fun_", + "fun-", + "fun.", + "groovy", + "query", + "grail", + "red_", + "red-", + "red.", + "laravel", + "monkey", + "slack", + "supported", + "instant", + "value", + "center", + "latest", + "work", + "but_", + "but-", + "but.", + "bug_", + "bug-", + "bug.", + "virtual", + "tweet", + "statsd", + "studio", + "path", + "real-time", + "frontend", + "notifier", + "coding", + "tool", + "firmware", + "flow", + "random", + "mediawiki", + "bosh", + "been", + "beer", + "lightbox", + "theory", + "origin", + "redmine", + "hub_", + "hub-", + "hub.", + "require", + "pro_", + "pro-", + "pro.", + "ant_", + "ant-", + "ant.", + "any_", + "any-", + "any.", + "recipe", + "closure", + "mapper", + "event", + "todo", + "model", + "redi", + "provider", + "rvm_", + "rvm-", + "rvm.", + "program", + "memcached", + "rail", + "silex", + "foreman", + "activity", + "license", + "strategy", + "batch", + "streaming", + "fast", + "use_", + "use-", + "use.", + "usb_", + "usb-", + "usb.", + "impres", + "academy", + "slider", + "please", + "layer", + "cros", + "now_", + "now-", + "now.", + "miner", + "extension", + "own_", + "own-", + "own.", + "app_", + "app-", + "app.", + "debian", + "symphony", + "example", + "feature", + "serie", + "tree", + "project", + "runner", + "entry", + "leetcode", + "layout", + "webrtc", + "logic", + "login", + "worker", + "toolkit", + "mocha", + "support", + "back", + "inside", + "device", + "jenkin", + "contact", + "fake", + "awesome", + "ocaml", + "bit_", + "bit-", + "bit.", + "drive", + "screen", + "prototype", + "gist", + "binary", + "nosql", + "rest", + "overview", + "dart", + "dark", + "emac", + "mongoid", + "solarized", + "homepage", + "emulator", + "commander", + "django", + "yandex", + "gradle", + "xcode", + "writer", + "crm_", + "crm-", + "crm.", + "jade", + "startup", + "error", + "using", + "format", + "name", + "spring", + "parser", + "scratch", + "magic", + "try_", + "try-", + "try.", + "rack", + "directive", + "challenge", + "slim", + "counter", + "element", + "chosen", + "doc_", + "doc-", + "doc.", + "meta", + "should", + "button", + "packet", + "stream", + "hardware", + "android", + "infinite", + "password", + "software", + "ghost", + "xamarin", + "spec", + "chef", + "interview", + "hubot", + "mvc_", + "mvc-", + "mvc.", + "exercise", + "leaflet", + "launcher", + "air_", + "air-", + "air.", + "photo", + "board", + "boxen", + "way_", + "way-", + "way.", + "computing", + "welcome", + "notepad", + "portfolio", + "cat_", + "cat-", + "cat.", + "can_", + "can-", + "can.", + "magento", + "yaml", + "domain", + "card", + "yii_", + "yii-", + "yii.", + "checker", + "browser", + "upgrade", + "only", + "progres", + "aura", + "ruby_", + "ruby-", + "ruby.", + "polymer", + "util", + "lite", + "hackathon", + "rule", + "log_", + "log-", + "log.", + "opengl", + "stanford", + "skeleton", + "history", + "inspector", + "help", + "soon", + "selenium", + "lab_", + "lab-", + "lab.", + "scheme", + "schema", + "look", + "ready", + "leveldb", + "docker", + "game", + "minimal", + "logstash", + "messaging", + "within", + "heroku", + "mongodb", + "kata", + "suite", + "picker", + "win_", + "win-", + "win.", + "wip_", + "wip-", + "wip.", + "panel", + "started", + "starter", + "front-end", + "detector", + "deploy", + "editing", + "based", + "admin", + "capture", + "spree", + "page", + "bundle", + "goal", + "rpg_", + "rpg-", + "rpg.", + "setup", + "side", + "mean", + "reader", + "cookbook", + "mini", + "modern", + "seed", + "dom_", + "dom-", + "dom.", + "doc_", + "doc-", + "doc.", + "dot_", + "dot-", + "dot.", + "syntax", + "sugar", + "loader", + "website", + "make", + "kit_", + "kit-", + "kit.", + "protocol", + "human", + "daemon", + "golang", + "manager", + "countdown", + "connector", + "swagger", + "map_", + "map-", + "map.", + "mac_", + "mac-", + "mac.", + "man_", + "man-", + "man.", + "orm_", + "orm-", + "orm.", + "org_", + "org-", + "org.", + "little", + "zsh_", + "zsh-", + "zsh.", + "shop", + "show", + "workshop", + "money", + "grid", + "server", + "octopres", + "svn_", + "svn-", + "svn.", + "ember", + "embed", + "general", + "file", + "important", + "dropbox", + "portable", + "public", + "docpad", + "fish", + "sbt_", + "sbt-", + "sbt.", + "done", + "para", + "network", + "common", + "readme", + "popup", + "simple", + "purpose", + "mirror", + "single", + "cordova", + "exchange", + "object", + "design", + "gateway", + "account", + "lamp", + "intellij", + "math", + "mit_", + "mit-", + "mit.", + "control", + "enhanced", + "emitter", + "multi", + "add_", + "add-", + "add.", + "about", + "socket", + "preview", + "vagrant", + "cli_", + "cli-", + "cli.", + "powerful", + "top_", + "top-", + "top.", + "radio", + "watch", + "fluid", + "amazon", + "report", + "couchbase", + "automatic", + "detection", + "sprite", + "pyramid", + "portal", + "advanced", + "plu_", + "plu-", + "plu.", + "runtime", + "git_", + "git-", + "git.", + "uri_", + "uri-", + "uri.", + "haml", + "node", + "sql_", + "sql-", + "sql.", + "cool", + "core", + "obsolete", + "handler", + "iphone", + "extractor", + "array", + "copy", + "nlp_", + "nlp-", + "nlp.", + "reveal", + "pop_", + "pop-", + "pop.", + "engine", + "parse", + "check", + "html", + "nest", + "all_", + "all-", + "all.", + "chinese", + "buildpack", + "what", + "tag_", + "tag-", + "tag.", + "proxy", + "style", + "cookie", + "feed", + "restful", + "compiler", + "creating", + "prelude", + "context", + "java", + "rspec", + "mock", + "backbone", + "light", + "spotify", + "flex", + "related", + "shell", + "which", + "clas", + "webapp", + "swift", + "ansible", + "unity", + "console", + "tumblr", + "export", + "campfire", + "conway'", + "made", + "riak", + "hero", + "here", + "unix", + "unit", + "glas", + "smtp", + "how_", + "how-", + "how.", + "hot_", + "hot-", + "hot.", + "debug", + "release", + "diff", + "player", + "easy", + "right", + "old_", + "old-", + "old.", + "animate", + "time", + "push", + "explorer", + "course", + "training", + "nette", + "router", + "draft", + "structure", + "note", + "salt", + "where", + "spark", + "trello", + "power", + "method", + "social", + "via_", + "via-", + "via.", + "vim_", + "vim-", + "vim.", + "select", + "webkit", + "github", + "ftp_", + "ftp-", + "ftp.", + "creator", + "mongoose", + "led_", + "led-", + "led.", + "movie", + "currently", + "pdf_", + "pdf-", + "pdf.", + "load", + "markdown", + "phalcon", + "input", + "custom", + "atom", + "oracle", + "phonegap", + "ubuntu", + "great", + "rdf_", + "rdf-", + "rdf.", + "popcorn", + "firefox", + "zip_", + "zip-", + "zip.", + "cuda", + "dotfile", + "static", + "openwrt", + "viewer", + "powered", + "graphic", + "les_", + "les-", + "les.", + "doe_", + "doe-", + "doe.", + "maven", + "word", + "eclipse", + "lab_", + "lab-", + "lab.", + "hacking", + "steam", + "analytic", + "option", + "abstract", + "archive", + "reality", + "switcher", + "club", + "write", + "kafka", + "arduino", + "angular", + "online", + "title", + "don't", + "contao", + "notice", + "analyzer", + "learning", + "zend", + "external", + "staging", + "busines", + "tdd_", + "tdd-", + "tdd.", + "scanner", + "building", + "snippet", + "modular", + "bower", + "stm_", + "stm-", + "stm.", + "lib_", + "lib-", + "lib.", + "alpha", + "mobile", + "clean", + "linux", + "nginx", + "manifest", + "some", + "raspberry", + "gnome", + "ide_", + "ide-", + "ide.", + "block", + "statistic", + "info", + "drag", + "youtube", + "koan", + "facebook", + "paperclip", + "art_", + "art-", + "art.", + "quality", + "tab_", + "tab-", + "tab.", + "need", + "dojo", + "shield", + "computer", + "stat", + "state", + "twitter", + "utility", + "converter", + "hosting", + "devise", + "liferay", + "updated", + "force", + "tip_", + "tip-", + "tip.", + "behavior", + "active", + "call", + "answer", + "deck", + "better", + "principle", + "ches", + "bar_", + "bar-", + "bar.", + "reddit", + "three", + "haxe", + "just", + "plug-in", + "agile", + "manual", + "tetri", + "super", + "beta", + "parsing", + "doctrine", + "minecraft", + "useful", + "perl", + "sharing", + "agent", + "switch", + "view", + "dash", + "channel", + "repo", + "pebble", + "profiler", + "warning", + "cluster", + "running", + "markup", + "evented", + "mod_", + "mod-", + "mod.", + "share", + "csv_", + "csv-", + "csv.", + "response", + "good", + "house", + "connect", + "built", + "build", + "find", + "ipython", + "webgl", + "big_", + "big-", + "big.", + "google", + "scala", + "sdl_", + "sdl-", + "sdl.", + "sdk_", + "sdk-", + "sdk.", + "native", + "day_", + "day-", + "day.", + "puppet", + "text", + "routing", + "helper", + "linkedin", + "crawler", + "host", + "guard", + "merchant", + "poker", + "over", + "writing", + "free", + "classe", + "component", + "craft", + "nodej", + "phoenix", + "longer", + "quick", + "lazy", + "memory", + "clone", + "hacker", + "middleman", + "factory", + "motion", + "multiple", + "tornado", + "hack", + "ssh_", + "ssh-", + "ssh.", + "review", + "vimrc", + "driver", + "driven", + "blog", + "particle", + "table", + "intro", + "importer", + "thrift", + "xmpp", + "framework", + "refresh", + "react", + "font", + "librarie", + "variou", + "formatter", + "analysi", + "karma", + "scroll", + "tut_", + "tut-", + "tut.", + "apple", + "tag_", + "tag-", + "tag.", + "tab_", + "tab-", + "tab.", + "category", + "ionic", + "cache", + "homebrew", + "reverse", + "english", + "getting", + "shipping", + "clojure", + "boot", + "book", + "branch", + "combination", + "combo", +] +[[rules]] +description = "GitHub App Token" +id = "github-app-token" +regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' +keywords = [ + "ghu_","ghs_", +] + +[[rules]] +description = "GitHub OAuth Access Token" +id = "github-oauth" +regex = '''gho_[0-9a-zA-Z]{36}''' +keywords = [ + "gho_", +] + +[[rules]] +description = "GitHub Personal Access Token" +id = "github-pat" +regex = '''ghp_[0-9a-zA-Z]{36}''' +keywords = [ + "ghp_", +] + +[[rules]] +description = "GitHub Refresh Token" +id = "github-refresh-token" +regex = '''ghr_[0-9a-zA-Z]{36}''' +keywords = [ + "ghr_", +] + +[[rules]] +description = "GitLab Personal Access Token" +id = "gitlab-pat" +regex = '''glpat-[0-9a-zA-Z\-\_]{20}''' +keywords = [ + "glpat-", +] + +[[rules]] +description = "Gitter Access Token" +id = "gitter-access-token" +regex = '''(?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "gitter", +] + +[[rules]] +description = "GoCardless API token" +id = "gocardless-api-token" +regex = '''(?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "live_","gocardless", +] + +[[rules]] +description = "Grafana api key (or Grafana cloud api key)" +id = "grafana-api-key" +regex = '''(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "eyjrijoi", +] + +[[rules]] +description = "Grafana cloud api token" +id = "grafana-cloud-api-token" +regex = '''(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "glc_", +] + +[[rules]] +description = "Grafana service account token" +id = "grafana-service-account-token" +regex = '''(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "glsa_", +] + +[[rules]] +description = "HashiCorp Terraform user/org API token" +id = "hashicorp-tf-api-token" +regex = '''(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}''' +keywords = [ + "atlasv1", +] + +[[rules]] +description = "Heroku API Key" +id = "heroku-api-key" +regex = '''(?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "heroku", +] + +[[rules]] +description = "HubSpot API Token" +id = "hubspot-api-key" +regex = '''(?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "hubspot", +] + +[[rules]] +description = "Intercom API Token" +id = "intercom-api-key" +regex = '''(?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "intercom", +] + +[[rules]] +description = "JSON Web Token" +id = "jwt" +regex = '''(?i)\b(ey[0-9a-z]{30,34}\.ey[0-9a-z-\/_]{30,500}\.[0-9a-zA-Z-\/_]{10,200})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ey", +] + +[[rules]] +description = "Kraken Access Token" +id = "kraken-access-token" +regex = '''(?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kraken", +] + +[[rules]] +description = "Kucoin Access Token" +id = "kucoin-access-token" +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kucoin", +] + +[[rules]] +description = "Kucoin Secret Key" +id = "kucoin-secret-key" +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kucoin", +] + +[[rules]] +description = "Launchdarkly Access Token" +id = "launchdarkly-access-token" +regex = '''(?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "launchdarkly", +] + +[[rules]] +description = "Linear API Token" +id = "linear-api-key" +regex = '''lin_api_(?i)[a-z0-9]{40}''' +keywords = [ + "lin_api_", +] + +[[rules]] +description = "Linear Client Secret" +id = "linear-client-secret" +regex = '''(?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linear", +] + +[[rules]] +description = "LinkedIn Client ID" +id = "linkedin-client-id" +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +description = "LinkedIn Client secret" +id = "linkedin-client-secret" +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +description = "Lob API Key" +id = "lob-api-key" +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "test_","live_", +] + +[[rules]] +description = "Lob Publishable API Key" +id = "lob-pub-api-key" +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "test_pub","live_pub","_pub", +] + +[[rules]] +description = "Mailchimp API key" +id = "mailchimp-api-key" +regex = '''(?i)(?:mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us20)(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailchimp", +] + +[[rules]] +description = "Mailgun private API token" +id = "mailgun-private-api-token" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "Mailgun public validation key" +id = "mailgun-pub-key" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "Mailgun webhook signing key" +id = "mailgun-signing-key" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "MapBox API token" +id = "mapbox-api-token" +regex = '''(?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mapbox", +] + +[[rules]] +description = "Mattermost Access Token" +id = "mattermost-access-token" +regex = '''(?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mattermost", +] + +[[rules]] +description = "MessageBird API token" +id = "messagebird-api-token" +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +description = "MessageBird client ID" +id = "messagebird-client-id" +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +description = "Microsoft Teams Webhook" +id = "microsoft-teams-webhook" +regex = '''https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}''' +keywords = [ + "webhook.office.com","webhookb2","incomingwebhook", +] + +[[rules]] +description = "Netlify Access Token" +id = "netlify-access-token" +regex = '''(?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "netlify", +] + +[[rules]] +description = "New Relic ingest browser API token" +id = "new-relic-browser-api-token" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nrjs-", +] + +[[rules]] +description = "New Relic user API ID" +id = "new-relic-user-api-id" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "new-relic","newrelic","new_relic", +] + +[[rules]] +description = "New Relic user API Key" +id = "new-relic-user-api-key" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nrak", +] + +[[rules]] +description = "npm access token" +id = "npm-access-token" +regex = '''(?i)\b(npm_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "npm_", +] + +[[rules]] +description = "Nytimes Access Token" +id = "nytimes-access-token" +regex = '''(?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nytimes","new-york-times","newyorktimes", +] + +[[rules]] +description = "Okta Access Token" +id = "okta-access-token" +regex = '''(?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "okta", +] + +[[rules]] +description = "Plaid API Token" +id = "plaid-api-token" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "Plaid Client ID" +id = "plaid-client-id" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "Plaid Secret key" +id = "plaid-secret-key" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "PlanetScale API token" +id = "planetscale-api-token" +regex = '''(?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_tkn_", +] + +[[rules]] +description = "PlanetScale OAuth token" +id = "planetscale-oauth-token" +regex = '''(?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_oauth_", +] + +[[rules]] +description = "PlanetScale password" +id = "planetscale-password" +regex = '''(?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_pw_", +] + +[[rules]] +description = "Postman API token" +id = "postman-api-token" +regex = '''(?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pmak-", +] + +[[rules]] +description = "Prefect API token" +id = "prefect-api-token" +regex = '''(?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pnu_", +] + +[[rules]] +description = "Private Key" +id = "private-key" +regex = '''(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY----''' +keywords = [ + "-----begin", +] + +[[rules]] +description = "Pulumi API token" +id = "pulumi-api-token" +regex = '''(?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pul-", +] + +[[rules]] +description = "PyPI upload token" +id = "pypi-upload-token" +regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' +keywords = [ + "pypi-ageichlwas5vcmc", +] + +[[rules]] +description = "RapidAPI Access Token" +id = "rapidapi-access-token" +regex = '''(?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rapidapi", +] + +[[rules]] +description = "Readme API token" +id = "readme-api-token" +regex = '''(?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rdme_", +] + +[[rules]] +description = "Rubygem API token" +id = "rubygems-api-token" +regex = '''(?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rubygems_", +] + +[[rules]] +description = "Sendbird Access ID" +id = "sendbird-access-id" +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sendbird", +] + +[[rules]] +description = "Sendbird Access Token" +id = "sendbird-access-token" +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sendbird", +] + +[[rules]] +description = "SendGrid API token" +id = "sendgrid-api-token" +regex = '''(?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sg.", +] + +[[rules]] +description = "Sendinblue API token" +id = "sendinblue-api-token" +regex = '''(?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "xkeysib-", +] + +[[rules]] +description = "Sentry Access Token" +id = "sentry-access-token" +regex = '''(?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sentry", +] + +[[rules]] +description = "Shippo API token" +id = "shippo-api-token" +regex = '''(?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "shippo_", +] + +[[rules]] +description = "Shopify access token" +id = "shopify-access-token" +regex = '''shpat_[a-fA-F0-9]{32}''' +keywords = [ + "shpat_", +] + +[[rules]] +description = "Shopify custom access token" +id = "shopify-custom-access-token" +regex = '''shpca_[a-fA-F0-9]{32}''' +keywords = [ + "shpca_", +] + +[[rules]] +description = "Shopify private app access token" +id = "shopify-private-app-access-token" +regex = '''shppa_[a-fA-F0-9]{32}''' +keywords = [ + "shppa_", +] + +[[rules]] +description = "Shopify shared secret" +id = "shopify-shared-secret" +regex = '''shpss_[a-fA-F0-9]{32}''' +keywords = [ + "shpss_", +] + +[[rules]] +description = "Sidekiq Secret" +id = "sidekiq-secret" +regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", +] + +[[rules]] +description = "Sidekiq Sensitive URL" +id = "sidekiq-sensitive-url" +regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' +secretGroup = 2 +keywords = [ + "gems.contribsys.com","enterprise.contribsys.com", +] + +[[rules]] +description = "Slack token" +id = "slack-access-token" +regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})''' +keywords = [ + "xoxb","xoxa","xoxp","xoxr","xoxs", +] + +[[rules]] +description = "Slack Webhook" +id = "slack-web-hook" +regex = '''https:\/\/hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{44,46}''' +keywords = [ + "hooks.slack.com", +] + +[[rules]] +description = "Square Access Token" +id = "square-access-token" +regex = '''(?i)\b(sq0atp-[0-9A-Za-z\-_]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sq0atp-", +] + +[[rules]] +description = "Squarespace Access Token" +id = "squarespace-access-token" +regex = '''(?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "squarespace", +] + +[[rules]] +description = "Stripe" +id = "stripe-access-token" +regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}''' +keywords = [ + "sk_test","pk_test","sk_live","pk_live", +] + +[[rules]] +description = "SumoLogic Access ID" +id = "sumologic-access-id" +regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sumo", +] + +[[rules]] +description = "SumoLogic Access Token" +id = "sumologic-access-token" +regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sumo", +] + +[[rules]] +description = "Telegram Bot API Token" +id = "telegram-bot-api-token" +regex = '''(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])''' +secretGroup = 1 +keywords = [ + "telegram","api","bot","token","url", +] + +[[rules]] +description = "Travis CI Access Token" +id = "travisci-access-token" +regex = '''(?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "travis", +] + +[[rules]] +description = "Twilio API Key" +id = "twilio-api-key" +regex = '''SK[0-9a-fA-F]{32}''' +keywords = [ + "twilio", +] + +[[rules]] +description = "Twitch API token" +id = "twitch-api-token" +regex = '''(?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitch", +] + +[[rules]] +description = "Twitter Access Secret" +id = "twitter-access-secret" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter Access Token" +id = "twitter-access-token" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter API Key" +id = "twitter-api-key" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter API Secret" +id = "twitter-api-secret" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter Bearer Token" +id = "twitter-bearer-token" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Typeform API token" +id = "typeform-api-token" +regex = '''(?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "tfp_", +] + +[[rules]] +description = "Vault Batch Token" +id = "vault-batch-token" +regex = '''(?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvb", +] + +[[rules]] +description = "Vault Service Token" +id = "vault-service-token" +regex = '''(?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvs", +] + +[[rules]] +description = "Yandex Access Token" +id = "yandex-access-token" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Yandex API Key" +id = "yandex-api-key" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Yandex AWS Access Token" +id = "yandex-aws-access-token" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Zendesk Secret Key" +id = "zendesk-secret-key" +regex = '''(?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "zendesk", +] + diff --git a/config/rule.go b/config/rule.go new file mode 100644 index 000000000..b7c8c1518 --- /dev/null +++ b/config/rule.go @@ -0,0 +1,43 @@ +package config + +import ( + "regexp" +) + +// Rules contain information that define details on how to detect secrets +type Rule struct { + // Description is the description of the rule. + Description string + + // RuleID is a unique identifier for this rule + RuleID string + + // Entropy is a float representing the minimum shannon + // entropy a regex group must have to be considered a secret. + Entropy float64 + + // SecretGroup is an int used to extract secret from regex + // match and used as the group that will have its entropy + // checked if `entropy` is set. + SecretGroup int + + // Regex is a golang regular expression used to detect secrets. + Regex *regexp.Regexp + + // Path is a golang regular expression used to + // filter secrets by path + Path *regexp.Regexp + + // Tags is an array of strings used for metadata + // and reporting purposes. + Tags []string + + // Keywords are used for pre-regex check filtering. Rules that contain + // keywords will perform a quick string compare check to make sure the + // keyword(s) are in the content being scanned. + Keywords []string + + // Allowlist allows a rule to be ignored for specific + // regexes, paths, and/or commits + Allowlist Allowlist +} diff --git a/config/utils.go b/config/utils.go new file mode 100644 index 000000000..ada6ff0fe --- /dev/null +++ b/config/utils.go @@ -0,0 +1,24 @@ +package config + +import ( + "regexp" +) + +func anyRegexMatch(f string, res []*regexp.Regexp) bool { + for _, re := range res { + if regexMatched(f, re) { + return true + } + } + return false +} + +func regexMatched(f string, re *regexp.Regexp) bool { + if re == nil { + return false + } + if re.FindString(f) != "" { + return true + } + return false +} diff --git a/detect/baseline.go b/detect/baseline.go new file mode 100644 index 000000000..b002fd4bf --- /dev/null +++ b/detect/baseline.go @@ -0,0 +1,65 @@ +package detect + +import ( + "encoding/json" + "fmt" + "io" + "os" + + "github.com/rs/zerolog/log" + + "github.com/zricethezav/gitleaks/v8/report" +) + +func IsNew(finding report.Finding, baseline []report.Finding) bool { + // Explicitly testing each property as it gives significantly better performance in comparison to cmp.Equal(). Drawback is that + // the code requires maintanance if/when the Finding struct changes + for _, b := range baseline { + + if finding.Author == b.Author && + finding.Commit == b.Commit && + finding.Date == b.Date && + finding.Description == b.Description && + finding.Email == b.Email && + finding.EndColumn == b.EndColumn && + finding.EndLine == b.EndLine && + finding.Entropy == b.Entropy && + finding.File == b.File && + // Omit checking finding.Fingerprint - if the format of the fingerprint changes, the users will see unexpected behaviour + finding.Match == b.Match && + finding.Message == b.Message && + finding.RuleID == b.RuleID && + finding.Secret == b.Secret && + finding.StartColumn == b.StartColumn && + finding.StartLine == b.StartLine { + return false + } + } + return true +} + +func LoadBaseline(baselinePath string) ([]report.Finding, error) { + var previousFindings []report.Finding + jsonFile, err := os.Open(baselinePath) + if err != nil { + return nil, fmt.Errorf("could not open %s", baselinePath) + } + + defer func() { + if cerr := jsonFile.Close(); cerr != nil { + log.Warn().Err(cerr).Msg("problem closing jsonFile handle") + } + }() + + bytes, err := io.ReadAll(jsonFile) + if err != nil { + return nil, fmt.Errorf("could not read data from the file %s", baselinePath) + } + + err = json.Unmarshal(bytes, &previousFindings) + if err != nil { + return nil, fmt.Errorf("the format of the file %s is not supported", baselinePath) + } + + return previousFindings, nil +} diff --git a/detect/baseline_test.go b/detect/baseline_test.go new file mode 100644 index 000000000..eb8983945 --- /dev/null +++ b/detect/baseline_test.go @@ -0,0 +1,137 @@ +package detect + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/zricethezav/gitleaks/v8/report" +) + +func TestIsNew(t *testing.T) { + tests := []struct { + findings report.Finding + baseline []report.Finding + expect bool + }{ + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0000", + }, + }, + expect: false, + }, + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0002", + }, + }, + expect: true, + }, + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + Tags: []string{"a", "b"}, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0000", + Tags: []string{"a", "c"}, + }, + }, + expect: false, // Updated tags doesn't make it a new finding + }, + } + for _, test := range tests { + assert.Equal(t, test.expect, IsNew(test.findings, test.baseline)) + } +} + +func TestFileLoadBaseline(t *testing.T) { + tests := []struct { + Filename string + ExpectedError error + }{ + { + Filename: "../testdata/baseline/baseline.csv", + ExpectedError: errors.New("the format of the file ../testdata/baseline/baseline.csv is not supported"), + }, + { + Filename: "../testdata/baseline/baseline.sarif", + ExpectedError: errors.New("the format of the file ../testdata/baseline/baseline.sarif is not supported"), + }, + { + Filename: "../testdata/baseline/notfound.json", + ExpectedError: errors.New("could not open ../testdata/baseline/notfound.json"), + }, + } + + for _, test := range tests { + _, err := LoadBaseline(test.Filename) + assert.Equal(t, test.ExpectedError.Error(), err.Error()) + } +} + +func TestIgnoreIssuesInBaseline(t *testing.T) { + tests := []struct { + findings []report.Finding + baseline []report.Finding + expectCount int + }{ + { + findings: []report.Finding{ + { + Author: "a", + Commit: "5", + }, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "5", + }, + }, + expectCount: 0, + }, + { + findings: []report.Finding{ + { + Author: "a", + Commit: "5", + Fingerprint: "a", + }, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "5", + Fingerprint: "b", + }, + }, + expectCount: 0, + }, + } + + for _, test := range tests { + d, _ := NewDetectorDefaultConfig() + d.baseline = test.baseline + for _, finding := range test.findings { + d.addFinding(finding) + } + assert.Equal(t, test.expectCount, len(d.findings)) + } +} diff --git a/detect/detect.go b/detect/detect.go new file mode 100644 index 000000000..c0784462b --- /dev/null +++ b/detect/detect.go @@ -0,0 +1,511 @@ +package detect + +import ( + "bufio" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect/git" + "github.com/zricethezav/gitleaks/v8/report" + + "github.com/fatih/semgroup" + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/h2non/filetype" + ahocorasick "github.com/petar-dambovaliev/aho-corasick" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" +) + +// Type used to differentiate between git scan types: +// $ gitleaks detect +// $ gitleaks protect +// $ gitleaks protect staged +type GitScanType int + +const ( + DetectType GitScanType = iota + ProtectType + ProtectStagedType + + gitleaksAllowSignature = "gitleaks:allow" +) + +// Detector is the main detector struct +type Detector struct { + // Config is the configuration for the detector + Config config.Config + + // Redact is a flag to redact findings. This is exported + // so users using gitleaks as a library can set this flag + // without calling `detector.Start(cmd *cobra.Command)` + Redact bool + + // verbose is a flag to print findings + Verbose bool + + // commitMap is used to keep track of commits that have been scanned. + // This is only used for logging purposes and git scans. + commitMap map[string]bool + + // findingMutex is to prevent concurrent access to the + // findings slice when adding findings. + findingMutex *sync.Mutex + + // findings is a slice of report.Findings. This is the result + // of the detector's scan which can then be used to generate a + // report. + findings []report.Finding + + // prefilter is a ahocorasick struct used for doing efficient string + // matching given a set of words (keywords from the rules in the config) + prefilter ahocorasick.AhoCorasick + + // a list of known findings that should be ignored + baseline []report.Finding + + // path to baseline + baselinePath string + + // gitleaksIgnore + gitleaksIgnore map[string]bool +} + +// Fragment contains the data to be scanned +type Fragment struct { + // Raw is the raw content of the fragment + Raw string + + // FilePath is the path to the file if applicable + FilePath string + + // CommitSHA is the SHA of the commit if applicable + CommitSHA string + + // newlineIndices is a list of indices of newlines in the raw content. + // This is used to calculate the line location of a finding + newlineIndices [][]int + + // keywords is a map of all the keywords contain within the contents + // of this fragment + keywords map[string]bool +} + +// NewDetector creates a new detector with the given config +func NewDetector(cfg config.Config) *Detector { + builder := ahocorasick.NewAhoCorasickBuilder(ahocorasick.Opts{ + AsciiCaseInsensitive: true, + MatchOnlyWholeWords: false, + MatchKind: ahocorasick.LeftMostLongestMatch, + DFA: true, + }) + + return &Detector{ + commitMap: make(map[string]bool), + gitleaksIgnore: make(map[string]bool), + findingMutex: &sync.Mutex{}, + findings: make([]report.Finding, 0), + Config: cfg, + prefilter: builder.Build(cfg.Keywords), + } +} + +// NewDetectorDefaultConfig creates a new detector with the default config +func NewDetectorDefaultConfig() (*Detector, error) { + viper.SetConfigType("toml") + err := viper.ReadConfig(strings.NewReader(config.DefaultConfig)) + if err != nil { + return nil, err + } + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + return nil, err + } + cfg, err := vc.Translate() + if err != nil { + return nil, err + } + return NewDetector(cfg), nil +} + +func (d *Detector) AddGitleaksIgnore(gitleaksIgnorePath string) error { + log.Debug().Msg("found .gitleaksignore file") + file, err := os.Open(gitleaksIgnorePath) + + if err != nil { + return err + } + + defer file.Close() + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + d.gitleaksIgnore[scanner.Text()] = true + } + return nil +} + +func (d *Detector) AddBaseline(baselinePath string) error { + if baselinePath != "" { + baseline, err := LoadBaseline(baselinePath) + if err != nil { + return err + } + d.baseline = baseline + } + d.baselinePath = baselinePath + return nil +} + +// DetectBytes scans the given bytes and returns a list of findings +func (d *Detector) DetectBytes(content []byte) []report.Finding { + return d.DetectString(string(content)) +} + +// DetectString scans the given string and returns a list of findings +func (d *Detector) DetectString(content string) []report.Finding { + return d.Detect(Fragment{ + Raw: content, + }) +} + +// detectRule scans the given fragment for the given rule and returns a list of findings +func (d *Detector) detectRule(fragment Fragment, rule config.Rule) []report.Finding { + var findings []report.Finding + + // check if filepath or commit is allowed for this rule + if rule.Allowlist.CommitAllowed(fragment.CommitSHA) || + rule.Allowlist.PathAllowed(fragment.FilePath) { + return findings + } + + if rule.Path != nil && rule.Regex == nil { + // Path _only_ rule + if rule.Path.Match([]byte(fragment.FilePath)) { + finding := report.Finding{ + Description: rule.Description, + File: fragment.FilePath, + RuleID: rule.RuleID, + Match: fmt.Sprintf("file detected: %s", fragment.FilePath), + Tags: rule.Tags, + } + return append(findings, finding) + } + } else if rule.Path != nil { + // if path is set _and_ a regex is set, then we need to check both + // so if the path does not match, then we should return early and not + // consider the regex + if !rule.Path.Match([]byte(fragment.FilePath)) { + return findings + } + } + + // if path only rule, skip content checks + if rule.Regex == nil { + return findings + } + + matchIndices := rule.Regex.FindAllStringIndex(fragment.Raw, -1) + for _, matchIndex := range matchIndices { + // extract secret from match + secret := strings.Trim(fragment.Raw[matchIndex[0]:matchIndex[1]], "\n") + + // determine location of match. Note that the location + // in the finding will be the line/column numbers of the _match_ + // not the _secret_, which will be different if the secretGroup + // value is set for this rule + loc := location(fragment, matchIndex) + + if matchIndex[1] > loc.endLineIndex { + loc.endLineIndex = matchIndex[1] + } + + finding := report.Finding{ + Description: rule.Description, + File: fragment.FilePath, + RuleID: rule.RuleID, + StartLine: loc.startLine, + EndLine: loc.endLine, + StartColumn: loc.startColumn, + EndColumn: loc.endColumn, + Secret: secret, + Match: secret, + Tags: rule.Tags, + Line: fragment.Raw[loc.startLineIndex:loc.endLineIndex], + } + + if strings.Contains(fragment.Raw[loc.startLineIndex:loc.endLineIndex], + gitleaksAllowSignature) { + continue + } + + // check if the secret is in the allowlist + if rule.Allowlist.RegexAllowed(finding.Secret) || + d.Config.Allowlist.RegexAllowed(finding.Secret) { + continue + } + + // extract secret from secret group if set + if rule.SecretGroup != 0 { + groups := rule.Regex.FindStringSubmatch(secret) + if len(groups) <= rule.SecretGroup || len(groups) == 0 { + // Config validation should prevent this + continue + } + secret = groups[rule.SecretGroup] + finding.Secret = secret + } + + // check if the secret is in the list of stopwords + if rule.Allowlist.ContainsStopWord(finding.Secret) || + d.Config.Allowlist.ContainsStopWord(finding.Secret) { + continue + } + + // check entropy + entropy := shannonEntropy(finding.Secret) + finding.Entropy = float32(entropy) + if rule.Entropy != 0.0 { + if entropy <= rule.Entropy { + // entropy is too low, skip this finding + continue + } + // NOTE: this is a goofy hack to get around the fact there golang's regex engine + // does not support positive lookaheads. Ideally we would want to add a + // restriction on generic rules regex that requires the secret match group + // contains both numbers and alphabetical characters, not just alphabetical characters. + // What this bit of code does is check if the ruleid is prepended with "generic" and enforces the + // secret contains both digits and alphabetical characters. + // TODO: this should be replaced with stop words + if strings.HasPrefix(rule.RuleID, "generic") { + if !containsDigit(secret) { + continue + } + } + } + + findings = append(findings, finding) + } + return findings +} + +// GitScan accepts a *gitdiff.File channel which contents a git history generated from +// the output of `git log -p ...`. startGitScan will look at each file (patch) in the history +// and determine if the patch contains any findings. +func (d *Detector) DetectGit(source string, logOpts string, gitScanType GitScanType) ([]report.Finding, error) { + var ( + gitdiffFiles <-chan *gitdiff.File + err error + ) + switch gitScanType { + case DetectType: + gitdiffFiles, err = git.GitLog(source, logOpts) + if err != nil { + return d.findings, err + } + case ProtectType: + gitdiffFiles, err = git.GitDiff(source, false) + if err != nil { + return d.findings, err + } + case ProtectStagedType: + gitdiffFiles, err = git.GitDiff(source, true) + if err != nil { + return d.findings, err + } + } + + s := semgroup.NewGroup(context.Background(), 4) + + for gitdiffFile := range gitdiffFiles { + gitdiffFile := gitdiffFile + + // skip binary files + if gitdiffFile.IsBinary || gitdiffFile.IsDelete { + continue + } + + // Check if commit is allowed + commitSHA := "" + if gitdiffFile.PatchHeader != nil { + commitSHA = gitdiffFile.PatchHeader.SHA + if d.Config.Allowlist.CommitAllowed(gitdiffFile.PatchHeader.SHA) { + continue + } + } + d.addCommit(commitSHA) + + s.Go(func() error { + for _, textFragment := range gitdiffFile.TextFragments { + if textFragment == nil { + return nil + } + + fragment := Fragment{ + Raw: textFragment.Raw(gitdiff.OpAdd), + CommitSHA: commitSHA, + FilePath: gitdiffFile.NewName, + } + + for _, finding := range d.Detect(fragment) { + d.addFinding(augmentGitFinding(finding, textFragment, gitdiffFile)) + } + } + return nil + }) + } + + if err := s.Wait(); err != nil { + return d.findings, err + } + log.Info().Msgf("%d commits scanned.", len(d.commitMap)) + log.Debug().Msg("Note: this number might be smaller than expected due to commits with no additions") + if git.ErrEncountered { + return d.findings, fmt.Errorf("%s", "git error encountered, see logs") + } + return d.findings, nil +} + +// DetectFiles accepts a path to a source directory or file and begins a scan of the +// file or directory. +func (d *Detector) DetectFiles(source string) ([]report.Finding, error) { + s := semgroup.NewGroup(context.Background(), 4) + paths := make(chan string) + s.Go(func() error { + defer close(paths) + return filepath.Walk(source, + func(path string, fInfo os.FileInfo, err error) error { + if err != nil { + return err + } + if fInfo.Name() == ".git" && fInfo.IsDir() { + return filepath.SkipDir + } + if fInfo.Size() == 0 { + return nil + } + if fInfo.Mode().IsRegular() { + paths <- path + } + return nil + }) + }) + for pa := range paths { + p := pa + s.Go(func() error { + b, err := os.ReadFile(p) + if err != nil { + return err + } + + mimetype, err := filetype.Match(b) + if err != nil { + return err + } + if mimetype.MIME.Type == "application" { + return nil // skip binary files + } + + fragment := Fragment{ + Raw: string(b), + FilePath: p, + } + for _, finding := range d.Detect(fragment) { + // need to add 1 since line counting starts at 1 + finding.EndLine++ + finding.StartLine++ + d.addFinding(finding) + } + + return nil + }) + } + + if err := s.Wait(); err != nil { + return d.findings, err + } + + return d.findings, nil +} + +// Detect scans the given fragment and returns a list of findings +func (d *Detector) Detect(fragment Fragment) []report.Finding { + var findings []report.Finding + + // initiate fragment keywords + fragment.keywords = make(map[string]bool) + + // check if filepath is allowed + if fragment.FilePath != "" && (d.Config.Allowlist.PathAllowed(fragment.FilePath) || + fragment.FilePath == d.Config.Path || (d.baselinePath != "" && fragment.FilePath == d.baselinePath)) { + return findings + } + + // add newline indices for location calculation in detectRule + fragment.newlineIndices = regexp.MustCompile("\n").FindAllStringIndex(fragment.Raw, -1) + + // build keyword map for prefiltering rules + normalizedRaw := strings.ToLower(fragment.Raw) + matches := d.prefilter.FindAll(normalizedRaw) + for _, m := range matches { + fragment.keywords[normalizedRaw[m.Start():m.End()]] = true + } + + for _, rule := range d.Config.Rules { + if len(rule.Keywords) == 0 { + // if not keywords are associated with the rule always scan the + // fragment using the rule + findings = append(findings, d.detectRule(fragment, rule)...) + continue + } + fragmentContainsKeyword := false + // check if keywords are in the fragment + for _, k := range rule.Keywords { + if _, ok := fragment.keywords[strings.ToLower(k)]; ok { + fragmentContainsKeyword = true + } + } + if fragmentContainsKeyword { + findings = append(findings, d.detectRule(fragment, rule)...) + } + } + return filter(findings, d.Redact) +} + +// addFinding synchronously adds a finding to the findings slice +func (d *Detector) addFinding(finding report.Finding) { + if finding.Commit == "" { + finding.Fingerprint = fmt.Sprintf("%s:%s:%d", finding.File, finding.RuleID, finding.StartLine) + } else { + finding.Fingerprint = fmt.Sprintf("%s:%s:%s:%d", finding.Commit, finding.File, finding.RuleID, finding.StartLine) + } + // check if we should ignore this finding + if _, ok := d.gitleaksIgnore[finding.Fingerprint]; ok { + log.Debug().Msgf("ignoring finding with Fingerprint %s", + finding.Fingerprint) + return + } + + if d.baseline != nil && !IsNew(finding, d.baseline) { + log.Debug().Msgf("baseline duplicate -- ignoring finding with Fingerprint %s", finding.Fingerprint) + return + } + + d.findingMutex.Lock() + d.findings = append(d.findings, finding) + if d.Verbose { + printFinding(finding) + } + d.findingMutex.Unlock() +} + +// addCommit synchronously adds a commit to the commit slice +func (d *Detector) addCommit(commit string) { + d.commitMap[commit] = true +} diff --git a/detect/detect_test.go b/detect/detect_test.go new file mode 100644 index 000000000..c4c4863d8 --- /dev/null +++ b/detect/detect_test.go @@ -0,0 +1,578 @@ +package detect + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/report" +) + +const configPath = "../testdata/config/" +const repoBasePath = "../testdata/repos/" + +func TestDetect(t *testing.T) { + tests := []struct { + cfgName string + fragment Fragment + expectedFindings []report.Finding + wantError error + }{ + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OKIA\ // gitleaks:allow"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \ + + \"AKIALALEMEL33243OKIA\ // gitleaks:allow" + + `, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OKIA\" + + // gitleaks:allow" + + `, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + Secret: "AKIALALEMEL33243OKIA", + Match: "AKIALALEMEL33243OKIA", + File: "tmp.go", + Line: `awsToken := \"AKIALALEMEL33243OKIA\"`, + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + StartLine: 0, + EndLine: 0, + StartColumn: 15, + EndColumn: 34, + Entropy: 3.1464393, + }, + }, + }, + { + cfgName: "escaped_character_group", + fragment: Fragment{ + Raw: `pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "PyPI upload token", + Secret: "pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB", + Match: "pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB", + Line: `pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB`, + File: "tmp.go", + RuleID: "pypi-upload-token", + Tags: []string{"key", "pypi"}, + StartLine: 1, + EndLine: 1, + StartColumn: 1, + EndColumn: 86, + Entropy: 1.9606875, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + Line: `awsToken := \"AKIALALEMEL33243OLIA\"`, + File: "tmp.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + StartLine: 1, + EndLine: 1, + StartColumn: 15, + EndColumn: 34, + Entropy: 3.0841837, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Secret", + Match: "BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;", + Secret: "cafebabe:deadbeef", + Line: `export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;`, + File: "tmp.sh", + RuleID: "sidekiq-secret", + Tags: []string{}, + Entropy: 2.6098502, + StartLine: 1, + EndLine: 1, + StartColumn: 8, + EndColumn: 60, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `echo hello1; export BUNDLE_ENTERPRISE__CONTRIBSYS__COM="cafebabe:deadbeef" && echo hello2`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Secret", + Match: "BUNDLE_ENTERPRISE__CONTRIBSYS__COM=\"cafebabe:deadbeef\"", + Secret: "cafebabe:deadbeef", + File: "tmp.sh", + Line: `echo hello1; export BUNDLE_ENTERPRISE__CONTRIBSYS__COM="cafebabe:deadbeef" && echo hello2`, + RuleID: "sidekiq-secret", + Tags: []string{}, + Entropy: 2.6098502, + StartLine: 1, + EndLine: 1, + StartColumn: 21, + EndColumn: 74, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `url = "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1"`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Sensitive URL", + Match: "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:", + Secret: "cafeb4b3:d3adb33f", + File: "tmp.sh", + Line: `url = "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1"`, + RuleID: "sidekiq-sensitive-url", + Tags: []string{}, + Entropy: 2.984234, + StartLine: 1, + EndLine: 1, + StartColumn: 8, + EndColumn: 58, + }, + }, + }, + { + cfgName: "allow_aws_re", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_path", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_commit", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + CommitSHA: "allowthiscommit", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "entropy_group", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "Discord API key", + Match: "Discord_Public_Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"", + Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5", + Line: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + File: "tmp.go", + RuleID: "discord-api-key", + Tags: []string{}, + Entropy: 3.7906237, + StartLine: 1, + EndLine: 1, + StartColumn: 7, + EndColumn: 93, + }, + }, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{ + { + Description: "Generic API Key", + Match: "Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"", + Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5", + Line: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + File: "tmp.py", + RuleID: "generic-api-key", + Tags: []string{}, + Entropy: 3.7906237, + StartLine: 1, + EndLine: 1, + StartColumn: 22, + EndColumn: 93, + }, + }, + }, + { + cfgName: "path_only", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{ + { + Description: "Python Files", + Match: "file detected: tmp.py", + File: "tmp.py", + RuleID: "python-files-only", + Tags: []string{}, + }, + }, + }, + { + cfgName: "bad_entropy_group", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"), + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: filepath.Join(configPath, "simple.toml"), + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_global_aws_re", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "load2523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{}, + }, + } + + for _, tt := range tests { + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(tt.cfgName) + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, err := vc.Translate() + cfg.Path = filepath.Join(configPath, tt.cfgName+".toml") + if tt.wantError != nil { + if err == nil { + t.Errorf("expected error") + } + assert.Equal(t, tt.wantError, err) + } + d := NewDetector(cfg) + + findings := d.Detect(tt.fragment) + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +// TestFromGit tests the FromGit function +func TestFromGit(t *testing.T) { + tests := []struct { + cfgName string + source string + logOpts string + expectedFindings []report.Finding + }{ + { + source: filepath.Join(repoBasePath, "small"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 19, + EndColumn: 38, + Line: "\n awsToken := \"AKIALALEMEL33243OLIA\"", + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + File: "main.go", + Date: "2021-11-02T23:37:53Z", + Commit: "1b6da43b82b22e4eaa10bcf8ee591e91abbfc587", + Author: "Zachary Rice", + Email: "zricer@protonmail.com", + Message: "Accidentally add a secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "1b6da43b82b22e4eaa10bcf8ee591e91abbfc587:main.go:aws-access-key:20", + }, + { + Description: "AWS Access Key", + StartLine: 9, + EndLine: 9, + StartColumn: 17, + EndColumn: 36, + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + Line: "\n\taws_token := \"AKIALALEMEL33243OLIA\"", + File: "foo/foo.go", + Date: "2021-11-02T23:48:06Z", + Commit: "491504d5a31946ce75e22554cc34203d8e5ff3ca", + Author: "Zach Rice", + Email: "zricer@protonmail.com", + Message: "adding foo package with secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "491504d5a31946ce75e22554cc34203d8e5ff3ca:foo/foo.go:aws-access-key:9", + }, + }, + }, + { + source: filepath.Join(repoBasePath, "small"), + logOpts: "--all foo...", + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 9, + EndLine: 9, + StartColumn: 17, + EndColumn: 36, + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\taws_token := \"AKIALALEMEL33243OLIA\"", + Match: "AKIALALEMEL33243OLIA", + Date: "2021-11-02T23:48:06Z", + File: "foo/foo.go", + Commit: "491504d5a31946ce75e22554cc34203d8e5ff3ca", + Author: "Zach Rice", + Email: "zricer@protonmail.com", + Message: "adding foo package with secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "491504d5a31946ce75e22554cc34203d8e5ff3ca:foo/foo.go:aws-access-key:9", + }, + }, + }, + } + + err := moveDotGit("dotGit", ".git") + if err != nil { + t.Fatal(err) + } + defer func() { + if err := moveDotGit(".git", "dotGit"); err != nil { + t.Error(err) + } + }() + + for _, tt := range tests { + + viper.AddConfigPath(configPath) + viper.SetConfigName("simple") + viper.SetConfigType("toml") + err = viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, err := vc.Translate() + if err != nil { + t.Error(err) + } + detector := NewDetector(cfg) + findings, err := detector.DetectGit(tt.source, tt.logOpts, DetectType) + if err != nil { + t.Error(err) + } + + for _, f := range findings { + f.Match = "" // remove lines cause copying and pasting them has some wack formatting + } + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +// TestFromGit tests the FromGit function +func TestFromFiles(t *testing.T) { + tests := []struct { + cfgName string + source string + expectedFindings []report.Finding + }{ + { + source: filepath.Join(repoBasePath, "nogit"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 16, + EndColumn: 35, + Match: "AKIALALEMEL33243OLIA", + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\tawsToken := \"AKIALALEMEL33243OLIA\"", + File: "../testdata/repos/nogit/main.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "../testdata/repos/nogit/main.go:aws-access-key:20", + }, + }, + }, + { + source: filepath.Join(repoBasePath, "nogit", "main.go"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 16, + EndColumn: 35, + Match: "AKIALALEMEL33243OLIA", + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\tawsToken := \"AKIALALEMEL33243OLIA\"", + File: "../testdata/repos/nogit/main.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "../testdata/repos/nogit/main.go:aws-access-key:20", + }, + }, + }, + } + + for _, tt := range tests { + viper.AddConfigPath(configPath) + viper.SetConfigName("simple") + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, _ := vc.Translate() + detector := NewDetector(cfg) + findings, err := detector.DetectFiles(tt.source) + if err != nil { + t.Error(err) + } + + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +func moveDotGit(from, to string) error { + repoDirs, err := os.ReadDir("../testdata/repos") + if err != nil { + return err + } + for _, dir := range repoDirs { + if to == ".git" { + _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), "dotGit")) + if os.IsNotExist(err) { + // dont want to delete the only copy of .git accidentally + continue + } + os.RemoveAll(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), ".git")) + } + if !dir.IsDir() { + continue + } + _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from)) + if os.IsNotExist(err) { + continue + } + + err = os.Rename(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from), + fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), to)) + if err != nil { + return err + } + } + return nil +} diff --git a/detect/git/git.go b/detect/git/git.go new file mode 100644 index 000000000..944fd4925 --- /dev/null +++ b/detect/git/git.go @@ -0,0 +1,121 @@ +package git + +import ( + "bufio" + "io" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/rs/zerolog/log" +) + +var ErrEncountered bool + +// GitLog returns a channel of gitdiff.File objects from the +// git log -p command for the given source. +func GitLog(source string, logOpts string) (<-chan *gitdiff.File, error) { + sourceClean := filepath.Clean(source) + var cmd *exec.Cmd + if logOpts != "" { + args := []string{"-C", sourceClean, "log", "-p", "-U0"} + args = append(args, strings.Split(logOpts, " ")...) + cmd = exec.Command("git", args...) + } else { + cmd = exec.Command("git", "-C", sourceClean, "log", "-p", "-U0", + "--full-history", "--all") + } + + log.Debug().Msgf("executing: %s", cmd.String()) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + go listenForStdErr(stderr) + + if err := cmd.Start(); err != nil { + return nil, err + } + // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722 + time.Sleep(50 * time.Millisecond) + + return gitdiff.Parse(cmd, stdout) +} + +// GitDiff returns a channel of gitdiff.File objects from +// the git diff command for the given source. +func GitDiff(source string, staged bool) (<-chan *gitdiff.File, error) { + sourceClean := filepath.Clean(source) + var cmd *exec.Cmd + cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", ".") + if staged { + cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", + "--staged", ".") + } + log.Debug().Msgf("executing: %s", cmd.String()) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + go listenForStdErr(stderr) + + if err := cmd.Start(); err != nil { + return nil, err + } + // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722 + time.Sleep(50 * time.Millisecond) + + return gitdiff.Parse(cmd, stdout) +} + +// listenForStdErr listens for stderr output from git and prints it to stdout +// then exits with exit code 1 +func listenForStdErr(stderr io.ReadCloser) { + scanner := bufio.NewScanner(stderr) + for scanner.Scan() { + // if git throws one of the following errors: + // + // exhaustive rename detection was skipped due to too many files. + // you may want to set your diff.renameLimit variable to at least + // (some large number) and retry the command. + // + // inexact rename detection was skipped due to too many files. + // you may want to set your diff.renameLimit variable to at least + // (some large number) and retry the command. + // + // we skip exiting the program as git log -p/git diff will continue + // to send data to stdout and finish executing. This next bit of + // code prevents gitleaks from stopping mid scan if this error is + // encountered + if strings.Contains(scanner.Text(), + "exhaustive rename detection was skipped") || + strings.Contains(scanner.Text(), + "inexact rename detection was skipped") || + strings.Contains(scanner.Text(), + "you may want to set your diff.renameLimit") { + log.Warn().Msg(scanner.Text()) + } else { + log.Error().Msgf("[git] %s", scanner.Text()) + + // asynchronously set this error flag to true so that we can + // capture a log message and exit with a non-zero exit code + // This value should get set before the `git` command exits so it's + // safe-ish, although I know I know, bad practice. + ErrEncountered = true + } + } +} diff --git a/detect/git/git_test.go b/detect/git/git_test.go new file mode 100644 index 000000000..3a2ea9c35 --- /dev/null +++ b/detect/git/git_test.go @@ -0,0 +1,158 @@ +package git_test + +// TODO: commenting out this test for now because it's flaky. Alternatives to consider to get this working: +// -- use `git stash` instead of `restore()` + +// const repoBasePath = "../../testdata/repos/" + +// const expectPath = "../../testdata/expected/" + +// func TestGitLog(t *testing.T) { +// tests := []struct { +// source string +// logOpts string +// expected string +// }{ +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: filepath.Join(expectPath, "git", "small.txt"), +// }, +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: filepath.Join(expectPath, "git", "small-branch-foo.txt"), +// logOpts: "--all foo...", +// }, +// } + +// err := moveDotGit("dotGit", ".git") +// if err != nil { +// t.Fatal(err) +// } +// defer func() { +// if err = moveDotGit(".git", "dotGit"); err != nil { +// t.Fatal(err) +// } +// }() + +// for _, tt := range tests { +// files, err := git.GitLog(tt.source, tt.logOpts) +// if err != nil { +// t.Error(err) +// } + +// var diffSb strings.Builder +// for f := range files { +// for _, tf := range f.TextFragments { +// diffSb.WriteString(tf.Raw(gitdiff.OpAdd)) +// } +// } + +// expectedBytes, err := os.ReadFile(tt.expected) +// if err != nil { +// t.Error(err) +// } +// expected := string(expectedBytes) +// if expected != diffSb.String() { +// // write string builder to .got file using os.Create +// err = os.WriteFile(strings.Replace(tt.expected, ".txt", ".got.txt", 1), []byte(diffSb.String()), 0644) +// if err != nil { +// t.Error(err) +// } +// t.Error("expected: ", expected, "got: ", diffSb.String()) +// } +// } +// } + +// func TestGitDiff(t *testing.T) { +// tests := []struct { +// source string +// expected string +// additions string +// target string +// }{ +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: "this line is added\nand another one", +// additions: "this line is added\nand another one", +// target: filepath.Join(repoBasePath, "small", "main.go"), +// }, +// } + +// err := moveDotGit("dotGit", ".git") +// if err != nil { +// t.Fatal(err) +// } +// defer func() { +// if err = moveDotGit(".git", "dotGit"); err != nil { +// t.Fatal(err) +// } +// }() + +// for _, tt := range tests { +// noChanges, err := os.ReadFile(tt.target) +// if err != nil { +// t.Error(err) +// } +// err = os.WriteFile(tt.target, []byte(tt.additions), 0644) +// if err != nil { +// restore(tt.target, noChanges, t) +// t.Error(err) +// } + +// files, err := git.GitDiff(tt.source, false) +// if err != nil { +// restore(tt.target, noChanges, t) +// t.Error(err) +// } + +// for f := range files { +// sb := strings.Builder{} +// for _, tf := range f.TextFragments { +// sb.WriteString(tf.Raw(gitdiff.OpAdd)) +// } +// if sb.String() != tt.expected { +// restore(tt.target, noChanges, t) +// t.Error("expected: ", tt.expected, "got: ", sb.String()) +// } +// } +// restore(tt.target, noChanges, t) +// } +// } + +// func restore(path string, data []byte, t *testing.T) { +// err := os.WriteFile(path, data, 0644) +// if err != nil { +// t.Fatal(err) +// } +// } + +// func moveDotGit(from, to string) error { +// repoDirs, err := os.ReadDir("../../testdata/repos") +// if err != nil { +// return err +// } +// for _, dir := range repoDirs { +// if to == ".git" { +// _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), "dotGit")) +// if os.IsNotExist(err) { +// // dont want to delete the only copy of .git accidentally +// continue +// } +// os.RemoveAll(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), ".git")) +// } +// if !dir.IsDir() { +// continue +// } +// _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from)) +// if os.IsNotExist(err) { +// continue +// } + +// err = os.Rename(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from), +// fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), to)) +// if err != nil { +// return err +// } +// } +// return nil +// } diff --git a/detect/location.go b/detect/location.go new file mode 100644 index 000000000..ac94d4159 --- /dev/null +++ b/detect/location.go @@ -0,0 +1,69 @@ +package detect + +// Location represents a location in a file +type Location struct { + startLine int + endLine int + startColumn int + endColumn int + startLineIndex int + endLineIndex int +} + +func location(fragment Fragment, matchIndex []int) Location { + var ( + prevNewLine int + location Location + lineSet bool + _lineNum int + ) + + start := matchIndex[0] + end := matchIndex[1] + + // default startLineIndex to 0 + location.startLineIndex = 0 + + for lineNum, pair := range fragment.newlineIndices { + _lineNum = lineNum + newLineByteIndex := pair[0] + if prevNewLine <= start && start < newLineByteIndex { + lineSet = true + location.startLine = lineNum + location.endLine = lineNum + location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1 + location.startLineIndex = prevNewLine + location.endLineIndex = newLineByteIndex + } + if prevNewLine < end && end <= newLineByteIndex { + location.endLine = lineNum + location.endColumn = (end - prevNewLine) + location.endLineIndex = newLineByteIndex + } + prevNewLine = pair[0] + } + + if !lineSet { + // if lines never get set then that means the secret is most likely + // on the last line of the diff output and the diff output does not have + // a newline + location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1 + location.endColumn = (end - prevNewLine) + location.startLine = _lineNum + 1 + location.endLine = _lineNum + 1 + + // search for new line byte index + i := 0 + for end+i < len(fragment.Raw) { + if fragment.Raw[end+i] == '\n' { + break + } + if fragment.Raw[end+i] == '\r' { + break + } + i++ + } + location.endLineIndex = end + i + } + return location +} diff --git a/detect/location_test.go b/detect/location_test.go new file mode 100644 index 000000000..d8c1a58c5 --- /dev/null +++ b/detect/location_test.go @@ -0,0 +1,60 @@ +package detect + +import ( + "testing" +) + +// TestGetLocation tests the getLocation function. +func TestGetLocation(t *testing.T) { + tests := []struct { + linePairs [][]int + start int + end int + wantLocation Location + }{ + { + linePairs: [][]int{ + {0, 39}, + {40, 55}, + {56, 57}, + }, + start: 35, + end: 38, + wantLocation: Location{ + startLine: 1, + startColumn: 36, + endLine: 1, + endColumn: 38, + startLineIndex: 0, + endLineIndex: 40, + }, + }, + { + linePairs: [][]int{ + {0, 39}, + {40, 55}, + {56, 57}, + }, + start: 40, + end: 44, + wantLocation: Location{ + startLine: 2, + startColumn: 1, + endLine: 2, + endColumn: 4, + startLineIndex: 40, + endLineIndex: 56, + }, + }, + } + + for _, test := range tests { + loc := location(Fragment{newlineIndices: test.linePairs}, []int{test.start, test.end}) + if loc != test.wantLocation { + t.Errorf("\nstartLine %d\nstartColumn: %d\nendLine: %d\nendColumn: %d\nstartLineIndex: %d\nendlineIndex %d", + loc.startLine, loc.startColumn, loc.endLine, loc.endColumn, loc.startLineIndex, loc.endLineIndex) + + t.Error("got", loc, "want", test.wantLocation) + } + } +} diff --git a/detect/utils.go b/detect/utils.go new file mode 100644 index 000000000..bea893f54 --- /dev/null +++ b/detect/utils.go @@ -0,0 +1,158 @@ +package detect + +import ( + // "encoding/json" + "fmt" + "math" + "strings" + "time" + + "github.com/charmbracelet/lipgloss" + + "github.com/zricethezav/gitleaks/v8/report" + + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/rs/zerolog/log" +) + +// augmentGitFinding updates the start and end line numbers of a finding to include the +// delta from the git diff +func augmentGitFinding(finding report.Finding, textFragment *gitdiff.TextFragment, f *gitdiff.File) report.Finding { + if !strings.HasPrefix(finding.Match, "file detected") { + finding.StartLine += int(textFragment.NewPosition) + finding.EndLine += int(textFragment.NewPosition) + } + + if f.PatchHeader != nil { + finding.Commit = f.PatchHeader.SHA + finding.Message = f.PatchHeader.Message() + if f.PatchHeader.Author != nil { + finding.Author = f.PatchHeader.Author.Name + finding.Email = f.PatchHeader.Author.Email + } + finding.Date = f.PatchHeader.AuthorDate.UTC().Format(time.RFC3339) + } + return finding +} + +// shannonEntropy calculates the entropy of data using the formula defined here: +// https://en.wiktionary.org/wiki/Shannon_entropy +// Another way to think about what this is doing is calculating the number of bits +// needed to on average encode the data. So, the higher the entropy, the more random the data, the +// more bits needed to encode that data. +func shannonEntropy(data string) (entropy float64) { + if data == "" { + return 0 + } + + charCounts := make(map[rune]int) + for _, char := range data { + charCounts[char]++ + } + + invLength := 1.0 / float64(len(data)) + for _, count := range charCounts { + freq := float64(count) * invLength + entropy -= freq * math.Log2(freq) + } + + return entropy +} + +// filter will dedupe and redact findings +func filter(findings []report.Finding, redact bool) []report.Finding { + var retFindings []report.Finding + for _, f := range findings { + include := true + if strings.Contains(strings.ToLower(f.RuleID), "generic") { + for _, fPrime := range findings { + if f.StartLine == fPrime.StartLine && + f.Commit == fPrime.Commit && + f.RuleID != fPrime.RuleID && + strings.Contains(fPrime.Secret, f.Secret) && + !strings.Contains(strings.ToLower(fPrime.RuleID), "generic") { + + genericMatch := strings.Replace(f.Match, f.Secret, "REDACTED", -1) + betterMatch := strings.Replace(fPrime.Match, fPrime.Secret, "REDACTED", -1) + log.Trace().Msgf("skipping %s finding (%s), %s rule takes precendence (%s)", f.RuleID, genericMatch, fPrime.RuleID, betterMatch) + include = false + break + } + } + } + + if redact { + f.Redact() + } + if include { + retFindings = append(retFindings, f) + } + } + return retFindings +} + +func printFinding(f report.Finding) { + // trim all whitespace and tabs from the line + f.Line = strings.TrimSpace(f.Line) + // trim all whitespace and tabs from the secret + f.Secret = strings.TrimSpace(f.Secret) + // trim all whitespace and tabs from the match + f.Match = strings.TrimSpace(f.Match) + + matchInLineIDX := strings.Index(f.Line, f.Match) + secretInMatchIdx := strings.Index(f.Match, f.Secret) + + start := f.Line[0:matchInLineIDX] + startMatchIdx := 0 + if matchInLineIDX > 20 { + startMatchIdx = matchInLineIDX - 20 + start = "..." + f.Line[startMatchIdx:matchInLineIDX] + } + + matchBeginning := lipgloss.NewStyle().SetString(f.Match[0:secretInMatchIdx]).Foreground(lipgloss.Color("#f5d445")) + secret := lipgloss.NewStyle().SetString(f.Secret). + Bold(true). + Italic(true). + Foreground(lipgloss.Color("#f05c07")) + matchEnd := lipgloss.NewStyle().SetString(f.Match[secretInMatchIdx+len(f.Secret):]).Foreground(lipgloss.Color("#f5d445")) + lineEnd := f.Line[matchInLineIDX+len(f.Match):] + if len(f.Secret) > 100 { + secret = lipgloss.NewStyle().SetString(f.Secret[0:100] + "..."). + Bold(true). + Italic(true). + Foreground(lipgloss.Color("#f05c07")) + } + if len(lineEnd) > 20 { + lineEnd = lineEnd[0:20] + "..." + } + + finding := fmt.Sprintf("%s%s%s%s%s\n", strings.TrimPrefix(strings.TrimLeft(start, " "), "\n"), matchBeginning, secret, matchEnd, lineEnd) + fmt.Printf("%-12s %s", "Finding:", finding) + fmt.Printf("%-12s %s\n", "Secret:", secret) + fmt.Printf("%-12s %s\n", "RuleID:", f.RuleID) + fmt.Printf("%-12s %f\n", "Entropy:", f.Entropy) + fmt.Printf("%-12s %s\n", "File:", f.File) + fmt.Printf("%-12s %d\n", "Line:", f.StartLine) + if f.Commit == "" { + fmt.Printf("%-12s %s\n", "Fingerprint:", f.Fingerprint) + fmt.Println("") + return + } + fmt.Printf("%-12s %s\n", "Commit:", f.Commit) + fmt.Printf("%-12s %s\n", "Author:", f.Author) + fmt.Printf("%-12s %s\n", "Email:", f.Email) + fmt.Printf("%-12s %s\n", "Date:", f.Date) + fmt.Printf("%-12s %s\n", "Fingerprint:", f.Fingerprint) + fmt.Println("") +} + +func containsDigit(s string) bool { + for _, c := range s { + switch c { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return true + } + + } + return false +} diff --git a/examples/leaky-repo.toml b/examples/leaky-repo.toml deleted file mode 100644 index 62ef4d2d3..000000000 --- a/examples/leaky-repo.toml +++ /dev/null @@ -1,195 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS cred file info" - regex = '''(?i)(aws_access_key_id|aws_secret_access_key)(.{0,20})?=.[0-9a-zA-Z\/+]{20,40}''' - tags = ["AWS"] - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "Env Var" - regex = '''(?i)(apikey|secret|key|api|password|pass|pw|host)=[0-9a-zA-Z-_.{}]{4,120}''' - -[[rules]] - description = "Port" - regex = '''(?i)port(.{0,4})?[0-9]{1,10}''' - [rules.allowlist] - regexes = ['''(?i)port '''] - description = "ignore export " - - - -[[rules]] - description = "Email" - regex = '''[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}''' - tags = ["email"] - [rules.allowlist] - files = ['''(?i)bashrc'''] - description = "ignore bashrc emails" - - -[[rules]] - description = "Generic Credential" - regex = '''(?i)(dbpasswd|dbuser|dbname|dbhost|api_key|apikey|secret|key|api|password|user|guid|hostname|pw|auth)(.{0,20})?['|"]([0-9a-zA-Z-_\/+!{}/=]{4,120})['|"]''' - tags = ["key", "API", "generic"] - # ignore leaks with specific identifiers like slack and aws - [rules.allowlist] - description = "ignore slack, mailchimp, aws" - regexes = [ - '''xox[baprs]-([0-9a-zA-Z]{10,48})''', - '''(?i)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''', - '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - ] - -[[rules]] - description = "High Entropy" - regex = '''[0-9a-zA-Z-_!{}/=]{4,120}''' - file = '''(?i)(dump.sql|high-entropy-misc.txt)$''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "7.0" - [rules.allowlist] - description = "ignore ssh key and pems" - files = ['''(pem|ppk|env)$'''] - paths = ['''(.*)?ssh'''] - -[[rules]] - description = "Potential bash var" - regex='''(?i)(=)([0-9a-zA-Z-_!{}=]{4,120})''' - tags = ["key", "bash", "API", "generic"] - [[rules.Entropies]] - Min = "3.5" - Max = "4.5" - Group = "1" - -[[rules]] - description = "WP-Config" - regex='''define(.{0,20})?(DB_CHARSET|NONCE_SALT|LOGGED_IN_SALT|AUTH_SALT|NONCE_KEY|DB_HOST|DB_PASSWORD|AUTH_KEY|SECURE_AUTH_KEY|LOGGED_IN_KEY|DB_NAME|DB_USER)(.{0,20})?['|"].{10,120}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Files with keys and credentials" - file = '''(?i)(id_rsa|passwd|id_rsa.pub|pgpass|pem|key|shadow)''' - -# Global allowlist -[allowlist] - description = "image allowlists" - files = ['''(.*?)(jpg|gif|doc|pdf|bin)$'''] - diff --git a/examples/pre-commit.example b/examples/pre-commit.example deleted file mode 100644 index 005fae352..000000000 --- a/examples/pre-commit.example +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# This is an example of what adding gitleaks to a pre-commit hook would look like. - -gitleaksEnabled=$(git config --bool hooks.gitleaks) -cmd="/Users/zrice/go/src/github.com/zricethezav/gitleaks/gitleaks --verbose --redact --pretty" -if [ $gitleaksEnabled == "true" ]; then - $cmd - if [ $? -eq 1 ]; then -cat <<\EOF -Error: gitleaks has detected sensitive information in your changes. -If you know what you are doing you can disable this check using: - - git config hooks.gitleaks false - -EOF -exit 1 - fi -fi diff --git a/examples/regex_and_entropy_config.toml b/examples/regex_and_entropy_config.toml deleted file mode 100644 index c8718fa84..000000000 --- a/examples/regex_and_entropy_config.toml +++ /dev/null @@ -1,17 +0,0 @@ -# This config contains a single rule which defines a regex and a range of entropy values. If a rule has -# both regex and entropy then that rule uses BOTH the regex and entropy in combination when performing an scan. -# In other words, if a line of code has an entropy value that is within the range of the entropies defined and -# a regex match is found then that line of code contains a leak. - -# So, for this example if a line of code has an entropy value of 4.6 AND matches the regex below then we got a leak. - -[[rules]] - description = "entropy and regex" - regex = '''(?i)key(.{0,20})?['|"][0-9a-zA-Z]{16,45}['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "5.7" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" diff --git a/examples/simple_regex_and_allowlist_config.toml b/examples/simple_regex_and_allowlist_config.toml deleted file mode 100644 index e99eb49cc..000000000 --- a/examples/simple_regex_and_allowlist_config.toml +++ /dev/null @@ -1,13 +0,0 @@ -# This config contains a single rule that checks for AWS keys. However, it also contains a allowlist table -# where you can define one or more allowlists. What this means is that if you have an example AWS key as part of your -# code (in a test for example), then you can allowlist that specific key so gitleaks will not label it as a leak. -# If this line was present in a git history: `aws_access_key_id='AKIAIO5FODNN7EXAMPLE``, gitleaks would match this line -# with the rule below, but since we have a allowlist against that specific key, it would be ignored. - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - regexes = ['''AKIAIO5FODNN7EXAMPLE.*'''] - description = "ignore example aws key" diff --git a/examples/simple_regex_config.toml b/examples/simple_regex_config.toml deleted file mode 100644 index 1c167a737..000000000 --- a/examples/simple_regex_config.toml +++ /dev/null @@ -1,6 +0,0 @@ -# This is a simple gitleaks config that contains one rule which checks for AWS keys. - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/go.mod b/go.mod index 04d5600d2..036d897f1 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,47 @@ -module github.com/zricethezav/gitleaks/v6 +module github.com/zricethezav/gitleaks/v8 -go 1.14 +go 1.19 require ( - github.com/BurntSushi/toml v0.3.1 - github.com/go-git/go-billy/v5 v5.0.0 - github.com/go-git/go-git/v5 v5.1.0 - github.com/google/go-cmp v0.4.0 // indirect - github.com/google/go-github/v31 v31.0.0 - github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 - github.com/jessevdk/go-flags v1.4.0 - github.com/mattn/go-colorable v0.1.2 - github.com/sergi/go-diff v1.1.0 - github.com/sirupsen/logrus v1.4.2 - github.com/xanzy/go-gitlab v0.21.0 - golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + github.com/charmbracelet/lipgloss v0.5.0 + github.com/fatih/semgroup v1.2.0 + github.com/gitleaks/go-gitdiff v0.8.0 + github.com/h2non/filetype v1.1.3 + github.com/rs/zerolog v1.26.1 + github.com/spf13/cobra v1.2.1 + github.com/spf13/viper v1.8.1 + github.com/stretchr/testify v1.7.0 +) + +require ( + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect + github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb + github.com/magiconair/properties v1.8.5 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index e86abebe3..ad57b30f6 100644 --- a/go.sum +++ b/go.sum @@ -1,127 +1,631 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= -github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= -github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/semgroup v1.2.0 h1:h/OLXwEM+3NNyAdZEpMiH1OzfplU09i2qXPVThGZvyg= +github.com/fatih/semgroup v1.2.0/go.mod h1:1KAD4iIYfXjE4U13B48VM4z9QUwV5Tt8O4rS879kgm8= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gitleaks/go-gitdiff v0.8.0 h1:7aExTZm+K/M/EQKOyYcub8rIAdWK6ONxPGuRzxmWW+0= +github.com/gitleaks/go-gitdiff v0.8.0/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= -github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw= -github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= +github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb h1:w1g9wNDIE/pHSTmAaUhv4TZQuPBS6GV3mMz5hkgziIU= +github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8= +github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/xanzy/go-gitlab v0.21.0 h1:Ru55sR4TBoDNsAKwCOpzeaGtbiWj7xTksVmzBJbLu6c= -github.com/xanzy/go-gitlab v0.21.0/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ= +golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/hosts/github.go b/hosts/github.go deleted file mode 100644 index 9330b8243..000000000 --- a/hosts/github.go +++ /dev/null @@ -1,190 +0,0 @@ -package hosts - -import ( - "context" - "strconv" - "strings" - "sync" - - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/google/go-github/v31/github" - log "github.com/sirupsen/logrus" - "golang.org/x/oauth2" -) - -// Github wraps a github client and manager. This struct implements what the Host interface defines. -type Github struct { - client *github.Client - manager *manager.Manager - wg sync.WaitGroup -} - -// NewGithubClient accepts a manager struct and returns a Github host pointer which will be used to -// perform a github scan on an organization, user, or PR. -func NewGithubClient(m *manager.Manager) (*Github, error) { - var err error - ctx := context.Background() - token := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: options.GetAccessToken(m.Opts)}, - ) - - var githubClient *github.Client - httpClient := oauth2.NewClient(ctx, token) - - if m.Opts.BaseURL == "" { - githubClient = github.NewClient(httpClient) - } else { - githubClient, err = github.NewEnterpriseClient(m.Opts.BaseURL, m.Opts.BaseURL, httpClient) - } - - return &Github{ - manager: m, - client: githubClient, - }, err -} - -// Scan will scan a github user or organization's repos. -func (g *Github) Scan() { - ctx := context.Background() - listOptions := github.ListOptions{ - PerPage: 100, - Page: 1, - } - - var ( - githubRepos []*github.Repository - auth transport.AuthMethod - ) - - for { - var ( - _githubRepos []*github.Repository - resp *github.Response - err error - ) - if g.manager.Opts.User != "" { - _githubRepos, resp, err = g.client.Repositories.List(ctx, g.manager.Opts.User, - &github.RepositoryListOptions{ListOptions: listOptions}) - } else if g.manager.Opts.Organization != "" { - _githubRepos, resp, err = g.client.Repositories.ListByOrg(ctx, g.manager.Opts.Organization, - &github.RepositoryListByOrgOptions{ListOptions: listOptions}) - } else { - _githubRepos, resp, err = g.client.Repositories.List(ctx, "", - &github.RepositoryListOptions{ListOptions: listOptions}) - } - - for _, r := range _githubRepos { - if g.manager.Opts.ExcludeForks && r.GetFork() { - log.Debugf("excluding forked repo: %s", *r.Name) - continue - } - githubRepos = append(githubRepos, r) - } - - if resp == nil { - break - } - - if resp.LastPage != 0 { - log.Infof("gathering github repos... progress: page %d of %d", listOptions.Page, resp.LastPage) - } else { - log.Infof("gathering github repos... progress: page %d of %d", listOptions.Page, listOptions.Page) - } - - listOptions.Page = resp.NextPage - if err != nil || listOptions.Page == 0 { - break - } - } - - for _, repo := range githubRepos { - r := scan.NewRepo(g.manager) - - if g.manager.CloneOptions != nil { - auth = g.manager.CloneOptions.Auth - } - err := r.Clone(&git.CloneOptions{ - URL: *repo.CloneURL, - Auth: auth, - }) - r.Name = *repo.Name - if err != nil { - log.Warn("unable to clone via https and access token, attempting with ssh now") - auth, err := options.SSHAuth(g.manager.Opts) - if err != nil { - log.Warnf("unable to get ssh auth, skipping clone and scan for repo %s: %+v\n", *repo.CloneURL, err) - continue - } - err = r.Clone(&git.CloneOptions{ - URL: *repo.SSHURL, - Auth: auth, - }) - if err != nil { - log.Warnf("err cloning %s, skipping clone and scan: %+v\n", *repo.SSHURL, err) - continue - } - } - if err = r.Scan(); err != nil { - log.Warn(err) - } - } -} - -// ScanPR scan a single github PR -func (g *Github) ScanPR() { - ctx := context.Background() - splits := strings.Split(g.manager.Opts.PullRequest, "/") - owner := splits[len(splits)-4] - repoName := splits[len(splits)-3] - prNum, err := strconv.Atoi(splits[len(splits)-1]) - repo := scan.NewRepo(g.manager) - repo.Name = repoName - log.Infof("scanning pr %s\n", g.manager.Opts.PullRequest) - - if err != nil { - return - } - page := 1 - for { - commits, resp, err := g.client.PullRequests.ListCommits(ctx, owner, repoName, prNum, &github.ListOptions{ - PerPage: 100, Page: page}) - if err != nil { - return - } - for _, c := range commits { - c, _, err := g.client.Repositories.GetCommit(ctx, owner, repo.Name, *c.SHA) - if err != nil { - continue - } - commitObj := object.Commit{ - Hash: plumbing.NewHash(*c.SHA), - Author: object.Signature{ - Name: *c.Commit.Author.Name, - Email: *c.Commit.Author.Email, - When: *c.Commit.Author.Date, - }, - } - for _, f := range c.Files { - if f.Patch == nil { - continue - } - repo.CheckRules(&scan.Bundle{ - Content: *f.Patch, - FilePath: *f.Filename, - Commit: &commitObj, - }) - } - } - page = resp.NextPage - if resp.LastPage == 0 { - break - } - } -} diff --git a/hosts/gitlab.go b/hosts/gitlab.go deleted file mode 100644 index c4b003652..000000000 --- a/hosts/gitlab.go +++ /dev/null @@ -1,112 +0,0 @@ -package hosts - -import ( - "context" - "sync" - - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - log "github.com/sirupsen/logrus" - "github.com/xanzy/go-gitlab" -) - -// Gitlab wraps a gitlab client and manager. This struct implements what the Host interface defines. -type Gitlab struct { - client *gitlab.Client - manager *manager.Manager - ctx context.Context - wg sync.WaitGroup -} - -// NewGitlabClient accepts a manager struct and returns a Gitlab host pointer which will be used to -// perform a gitlab scan on an group or user. -func NewGitlabClient(m *manager.Manager) (*Gitlab, error) { - var err error - - gitlabClient := &Gitlab{ - manager: m, - ctx: context.Background(), - client: gitlab.NewClient(nil, options.GetAccessToken(m.Opts)), - } - - if m.Opts.BaseURL != "" { - err = gitlabClient.client.SetBaseURL(m.Opts.BaseURL) - } - - return gitlabClient, err -} - -// Scan will scan a github user or organization's repos. -func (g *Gitlab) Scan() { - var ( - projects []*gitlab.Project - resp *gitlab.Response - err error - ) - - page := 1 - listOpts := gitlab.ListOptions{ - PerPage: 100, - Page: page, - } - for { - var _projects []*gitlab.Project - if g.manager.Opts.User != "" { - glOpts := &gitlab.ListProjectsOptions{ - ListOptions: listOpts, - } - _projects, resp, err = g.client.Projects.ListUserProjects(g.manager.Opts.User, glOpts) - - } else if g.manager.Opts.Organization != "" { - glOpts := &gitlab.ListGroupProjectsOptions{ - ListOptions: listOpts, - } - _projects, resp, err = g.client.Groups.ListGroupProjects(g.manager.Opts.Organization, glOpts) - } - if err != nil { - log.Error(err) - } - - for _, p := range _projects { - if g.manager.Opts.ExcludeForks && p.ForkedFromProject != nil { - log.Debugf("excluding forked repo: %s", p.Name) - continue - } - projects = append(projects, p) - } - - if resp == nil { - break - } - if page >= resp.TotalPages { - // exit when we've seen all pages - break - } - page = resp.NextPage - } - - // iterate of gitlab projects - for _, p := range projects { - r := scan.NewRepo(g.manager) - cloneOpts := g.manager.CloneOptions - cloneOpts.URL = p.HTTPURLToRepo - err := r.Clone(cloneOpts) - if err != nil { - log.Error(err) - continue - } - // TODO handle clone retry with ssh like github host - r.Name = p.Name - - if err = r.Scan(); err != nil { - log.Error(err) - } - } -} - -// ScanPR TODO not implemented -func (g *Gitlab) ScanPR() { - log.Error("ScanPR is not implemented in Gitlab host yet...") -} diff --git a/hosts/host.go b/hosts/host.go deleted file mode 100644 index 3c03e4783..000000000 --- a/hosts/host.go +++ /dev/null @@ -1,53 +0,0 @@ -package hosts - -import ( - "strings" - - "github.com/zricethezav/gitleaks/v6/manager" -) - -const ( - _github int = iota + 1 - _gitlab -) - -// Host is an interface used for defining external git hosting providers like github and gitlab. -// TODO add bitbucket -type Host interface { - Scan() - ScanPR() -} - -// Run kicks off a host scan. This function accepts a manager and determines what host it should scan -func Run(m *manager.Manager) error { - var host Host - var err error - switch getHost(m.Opts.Host) { - case _github: - host, err = NewGithubClient(m) - case _gitlab: - host, err = NewGitlabClient(m) - default: - return nil - } - - if err != nil { - return err - } - - if m.Opts.PullRequest != "" { - host.ScanPR() - } else { - host.Scan() - } - return err -} - -func getHost(host string) int { - if strings.ToLower(host) == "github" { - return _github - } else if strings.ToLower(host) == "gitlab" { - return _gitlab - } - return -1 -} diff --git a/hosts/hosts_test.go b/hosts/hosts_test.go deleted file mode 100644 index c39389e47..000000000 --- a/hosts/hosts_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package hosts - -import ( - "flag" - "fmt" - "os" - "testing" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" -) - -var ( - integration = flag.Bool("integration", false, "run github/gitlab integration test") -) - -func TestGithub(t *testing.T) { - flag.Parse() - if !*integration { - fmt.Println("skipping github integration tests") - return - } - if os.Getenv("GITHUB_TOKEN") == "" { - t.Log("skipping github integration tests, need env var GITLAB_TOKEN") - return - } - - tests := []struct { - opts options.Options - desiredLeaks int - }{ - { - opts: options.Options{ - Host: "github", - User: "gitleakstest", - AccessToken: os.Getenv("GITHUB_TOKEN"), - }, - desiredLeaks: 2, - }, - { - opts: options.Options{ - Host: "github", - PullRequest: "https://github.com/gitleakstest/gronit/pull/1", - AccessToken: os.Getenv("GITHUB_TOKEN"), - }, - desiredLeaks: 4, - }, - } - - for _, test := range tests { - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - err = Run(m) - if err != nil { - t.Fatal(err) - } - - if test.desiredLeaks != len(m.GetLeaks()) { - t.Errorf("got %d leaks, want %d", len(m.GetLeaks()), test.desiredLeaks) - } - } -} - -func TestGitlab(t *testing.T) { - flag.Parse() - if !*integration { - fmt.Println("skipping gitlab integration tests") - return - } - if os.Getenv("GITLAB_TOKEN") == "" { - t.Log("skipping github integration tests, need env var GITLAB_TOKEN") - return - } - - tests := []struct { - opts options.Options - desiredLeaks int - }{ - { - opts: options.Options{ - Host: "gitlab", - User: "gitleakstest", - AccessToken: os.Getenv("GITLAB_TOKEN"), - }, - desiredLeaks: 2, - }, - } - - for _, test := range tests { - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - err = Run(m) - if err != nil { - t.Fatal(err) - } - - if test.desiredLeaks != len(m.GetLeaks()) { - t.Errorf("got %d leaks, want %d", len(m.GetLeaks()), test.desiredLeaks) - } - } -} diff --git a/main.go b/main.go index de1fcbeb1..3a7cf2e0e 100644 --- a/main.go +++ b/main.go @@ -1,97 +1,28 @@ package main import ( - "io/ioutil" "os" - "time" + "os/signal" - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/hosts" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - "github.com/hako/durafmt" - log "github.com/sirupsen/logrus" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/zricethezav/gitleaks/v8/cmd" ) func main() { - opts, err := options.ParseOptions() - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - err = opts.Guard() - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - cfg, err := config.NewConfig(opts) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - m, err := manager.NewManager(opts, cfg) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } + // send all logs to stdout + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) - err = Run(m) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } + // this block sets up a go routine to listen for an interrupt signal + // which will immediately exit gitleaks + stopChan := make(chan os.Signal, 1) + signal.Notify(stopChan, os.Interrupt) + go listenForInterrupt(stopChan) - leaks := m.GetLeaks() - metadata := m.GetMetadata() - - if len(m.GetLeaks()) != 0 { - if m.Opts.CheckUncommitted() { - log.Warnf("%d leaks detected in staged changes", len(leaks)) - } else { - log.Warnf("%d leaks detected. %d commits scanned in %s", len(leaks), - metadata.Commits, durafmt.Parse(time.Duration(metadata.ScanTime)*time.Nanosecond)) - } - os.Exit(options.LeaksPresent) - } else { - if m.Opts.CheckUncommitted() { - log.Infof("No leaks detected in staged changes") - } else { - log.Infof("No leaks detected. %d commits scanned in %s", - metadata.Commits, durafmt.Parse(time.Duration(metadata.ScanTime)*time.Nanosecond)) - } - os.Exit(options.Success) - } + cmd.Execute() } -// Run begins the program and contains some basic logic on how to continue with the scan. If any external git host -// options are set (like scanning a gitlab or github user) then a specific host client will be created and -// then Scan() and Report() will be called. Otherwise, gitleaks will create a new repo and an scan will proceed. -// If no options or the uncommitted option is set then a pre-commit scan will -// take place -- this is similar to running `git diff` on all the tracked files. -func Run(m *manager.Manager) error { - if m.Opts.Disk { - dir, err := ioutil.TempDir("", "gitleaks") - defer os.RemoveAll(dir) - if err != nil { - return err - } - m.CloneDir = dir - } - - var err error - if m.Opts.Host != "" { - err = hosts.Run(m) - } else { - err = scan.Run(m) - } - if err != nil { - return err - } - - return m.Report() +func listenForInterrupt(stopScan chan os.Signal) { + <-stopScan + log.Fatal().Msg("Interrupt signal received. Exiting...") } diff --git a/manager/manager.go b/manager/manager.go deleted file mode 100644 index a20177d88..000000000 --- a/manager/manager.go +++ /dev/null @@ -1,274 +0,0 @@ -package manager - -import ( - "crypto/sha1" - "encoding/hex" - "encoding/json" - "fmt" - "os" - "os/signal" - "runtime" - "strings" - "sync" - "text/tabwriter" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/go-git/go-git/v5" - "github.com/hako/durafmt" - "github.com/mattn/go-colorable" - log "github.com/sirupsen/logrus" -) - -const maxLineLen = 200 - -// Manager is a struct containing options and configs as well CloneOptions and CloneDir. -// This struct is passed into each NewRepo so we are not passing around the manager in func params. -type Manager struct { - Opts options.Options - Config config.Config - - CloneOptions *git.CloneOptions - CloneDir string - - leaks []Leak - leakChan chan Leak - leakWG *sync.WaitGroup - leakCache map[string]bool - - stopChan chan os.Signal - metadata Metadata - metaWG *sync.WaitGroup -} - -// Leak is a struct that contains information about some line of code that contains -// sensitive information as determined by the rules set in a gitleaks config -type Leak struct { - Line string `json:"line"` - LineNumber int `json:"lineNumber"` - Offender string `json:"offender"` - Commit string `json:"commit"` - Repo string `json:"repo"` - Rule string `json:"rule"` - Message string `json:"commitMessage"` - Author string `json:"author"` - Email string `json:"email"` - File string `json:"file"` - Date time.Time `json:"date"` - Tags string `json:"tags"` - Operation string `json:"operation"` - lookupHash string -} - -// ScanTime is a type used to determine total scan time -type ScanTime int64 - -// PatchTime is a type used to determine total patch time during an scan -type PatchTime int64 - -// CloneTime is a type used to determine total clone time -type CloneTime int64 - -// RegexTime is a type used to determine the time each rules' regex takes. This is especially useful -// if you notice that gitleaks is taking a long time. You can use --debug to see the output of the regexTime -// so you can determine which regex is not performing well. -type RegexTime struct { - Time int64 - Regex string -} - -// Metadata is a struct used to communicate metadata about an scan like timings and total commit counts. -type Metadata struct { - mux *sync.Mutex - data map[string]interface{} - - timings chan interface{} - - RegexTime map[string]int64 - Commits int - ScanTime int64 - patchTime int64 - cloneTime int64 -} - -func init() { - log.SetOutput(os.Stdout) - log.SetFormatter(&log.TextFormatter{ - ForceColors: true, - FullTimestamp: true, - }) - // Fix colors on Windows - if runtime.GOOS == "windows" { - log.SetOutput(colorable.NewColorableStdout()) - } -} - -// NewManager accepts options and returns a manager struct. The manager is a container for gitleaks configurations, -// options and channel receivers. -func NewManager(opts options.Options, cfg config.Config) (*Manager, error) { - cloneOpts, err := opts.CloneOptions() - if err != nil { - return nil, err - } - - m := &Manager{ - Opts: opts, - Config: cfg, - CloneOptions: cloneOpts, - - stopChan: make(chan os.Signal, 1), - leakChan: make(chan Leak), - leakWG: &sync.WaitGroup{}, - leakCache: make(map[string]bool), - metaWG: &sync.WaitGroup{}, - metadata: Metadata{ - RegexTime: make(map[string]int64), - timings: make(chan interface{}), - data: make(map[string]interface{}), - mux: new(sync.Mutex), - }, - } - - signal.Notify(m.stopChan, os.Interrupt) - - // start receiving leaks and metadata - go m.receiveLeaks() - go m.receiveMetadata() - go m.receiveInterrupt() - - return m, nil -} - -// GetLeaks returns all available leaks -func (manager *Manager) GetLeaks() []Leak { - // need to wait for any straggling leaks - manager.leakWG.Wait() - return manager.leaks -} - -// SendLeaks accepts a leak and is used by the scan pkg. This is the public function -// that allows other packages to send leaks to the manager. -func (manager *Manager) SendLeaks(l Leak) { - if len(l.Line) > maxLineLen { - l.Line = l.Line[0:maxLineLen-1] + "..." - } - if len(l.Offender) > maxLineLen { - l.Offender = l.Offender[0:maxLineLen-1] + "..." - } - h := sha1.New() - h.Write([]byte(l.Commit + l.Offender + l.File + l.Line + string(l.LineNumber))) - l.lookupHash = hex.EncodeToString(h.Sum(nil)) - if manager.Opts.Redact { - l.Line = strings.ReplaceAll(l.Line, l.Offender, "REDACTED") - l.Offender = "REDACTED" - } - manager.leakWG.Add(1) - manager.leakChan <- l -} - -func (manager *Manager) alreadySeen(leak Leak) bool { - if _, ok := manager.leakCache[leak.lookupHash]; ok { - return true - } - manager.leakCache[leak.lookupHash] = true - return false -} - -// receiveLeaks listens to leakChan for incoming leaks. If any are received, they are appended to the -// manager's leaks for future reporting. If the -v/--verbose option is set the leaks will marshaled into -// json and printed out. -func (manager *Manager) receiveLeaks() { - for leak := range manager.leakChan { - if manager.alreadySeen(leak) { - manager.leakWG.Done() - continue - } - manager.leaks = append(manager.leaks, leak) - if manager.Opts.Verbose { - var b []byte - if manager.Opts.PrettyPrint { - b, _ = json.MarshalIndent(leak, "", " ") - } else { - b, _ = json.Marshal(leak) - } - fmt.Println(string(b)) - } - manager.leakWG.Done() - } -} - -// GetMetadata returns the metadata. TODO this may not need to be private -func (manager *Manager) GetMetadata() Metadata { - manager.metaWG.Wait() - return manager.metadata -} - -// receiveMetadata is where the messages sent to the metadata channel get consumed. You can view metadata -// by running gitleaks with the --debug option set. This is extremely useful when trying to optimize regular -// expressions as that what gitleaks spends most of its cycles on. -func (manager *Manager) receiveMetadata() { - for t := range manager.metadata.timings { - switch ti := t.(type) { - case CloneTime: - manager.metadata.cloneTime += int64(ti) - case ScanTime: - manager.metadata.ScanTime += int64(ti) - case PatchTime: - manager.metadata.patchTime += int64(ti) - case RegexTime: - manager.metadata.RegexTime[ti.Regex] = manager.metadata.RegexTime[ti.Regex] + ti.Time - } - manager.metaWG.Done() - } -} - -// IncrementCommits increments total commits during an scan by i. -func (manager *Manager) IncrementCommits(i int) { - manager.metadata.mux.Lock() - manager.metadata.Commits += i - manager.metadata.mux.Unlock() -} - -// RecordTime accepts an interface and sends it to the manager's time channel -func (manager *Manager) RecordTime(t interface{}) { - manager.metaWG.Add(1) - manager.metadata.timings <- t -} - -// DebugOutput logs metadata and other messages that occurred during a gitleaks scan -func (manager *Manager) DebugOutput() { - log.Debugf("-------------------------\n") - log.Debugf("| Times and Commit Counts|\n") - log.Debugf("-------------------------\n") - fmt.Println("totalScanTime: ", durafmt.Parse(time.Duration(manager.metadata.ScanTime)*time.Nanosecond)) - fmt.Println("totalPatchTime: ", durafmt.Parse(time.Duration(manager.metadata.patchTime)*time.Nanosecond)) - fmt.Println("totalCloneTime: ", durafmt.Parse(time.Duration(manager.metadata.cloneTime)*time.Nanosecond)) - fmt.Println("totalCommits: ", manager.metadata.Commits) - - const padding = 6 - w := tabwriter.NewWriter(os.Stdout, 0, 0, padding, '.', 0) - - log.Debugf("--------------------------\n") - log.Debugf("| Individual Regexes Times |\n") - log.Debugf("--------------------------\n") - for k, v := range manager.metadata.RegexTime { - _, _ = fmt.Fprintf(w, "%s\t%s\n", k, durafmt.Parse(time.Duration(v)*time.Nanosecond)) - } - _ = w.Flush() - -} - - -func (manager *Manager) receiveInterrupt() { - <-manager.stopChan - if manager.Opts.Report != "" { - err := manager.Report() - if err != nil { - log.Error(err) - } - } - log.Info("gitleaks received interrupt, stopping scan") - os.Exit(options.ErrorEncountered) -} diff --git a/manager/manager_test.go b/manager/manager_test.go deleted file mode 100644 index 73613df06..000000000 --- a/manager/manager_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package manager - -import ( - "crypto/rand" - "fmt" - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/options" - "io" - "testing" -) - -// TODO -// add more substantial tests... but since literally every pkg uses manager -// these tests are kind of redundant -func TestSendReceiveLeaks(t *testing.T) { - - tests := []struct { - leaksToAdd int - goRoutines int - }{ - { - leaksToAdd: 10, - }, - { - leaksToAdd: 1000, - }, - } - for _, test := range tests { - opts := options.Options{} - cfg, _ := config.NewConfig(opts) - m, _ := NewManager(opts, cfg) - - for i := 0; i < test.leaksToAdd; i++ { - // we are testing the sync of sending/receiving leaks so we need - // the hash generation in sendLeaks to be unique for each iteration - // so I'm just setting the offender string as a uuid - m.SendLeaks(Leak{Offender: newUUID()}) - } - got := m.GetLeaks() - if len(got) != test.leaksToAdd { - t.Errorf("got %d, wanted %d leaks", len(got), test.leaksToAdd) - } - } -} - -func TestSendReceiveMeta(t *testing.T) { - tests := []struct { - scanTime int64 - patchTime int64 - cloneTime int64 - regexTime int64 - iterations int - }{ - { - scanTime: 1000, - patchTime: 1000, - cloneTime: 1000, - regexTime: 1000, - iterations: 100, - }, - } - for _, test := range tests { - opts := options.Options{} - cfg, _ := config.NewConfig(opts) - m, _ := NewManager(opts, cfg) - - for i := 0; i < test.iterations; i++ { - m.RecordTime(ScanTime(test.scanTime)) - m.RecordTime(PatchTime(test.patchTime)) - m.RecordTime(CloneTime(test.cloneTime)) - m.RecordTime(RegexTime{ - Regex: "regex", - Time: test.regexTime, - }) - m.RecordTime(RegexTime{ - Regex: "regex2", - Time: test.regexTime, - }) - } - md := m.GetMetadata() - if md.cloneTime != test.cloneTime*int64(test.iterations) { - t.Errorf("clone time mismatch, got %d, wanted %d", - md.cloneTime, test.cloneTime*int64(test.iterations)) - } - if md.ScanTime != test.scanTime*int64(test.iterations) { - t.Errorf("scan time mismatch, got %d, wanted %d", - md.ScanTime, test.scanTime*int64(test.iterations)) - } - if md.patchTime != test.patchTime*int64(test.iterations) { - t.Errorf("clone time mismatch, got %d, wanted %d", - md.patchTime, test.patchTime*int64(test.iterations)) - } - } -} - -// newUUID generates a random UUID according to RFC 4122 -// Ripped from https://play.golang.org/p/4FkNSiUDMg -func newUUID() string { - uuid := make([]byte, 16) - io.ReadFull(rand.Reader, uuid) - // variant bits; see section 4.1.1 - uuid[8] = uuid[8]&^0xc0 | 0x80 - // version 4 (pseudo-random); see section 4.1.3 - uuid[6] = uuid[6]&^0xf0 | 0x40 - return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]) -} diff --git a/manager/report.go b/manager/report.go deleted file mode 100644 index 2895ca7ef..000000000 --- a/manager/report.go +++ /dev/null @@ -1,78 +0,0 @@ -package manager - -import ( - "encoding/csv" - "encoding/json" - "os" - "time" - - "github.com/zricethezav/gitleaks/v6/version" - - log "github.com/sirupsen/logrus" -) - -// Report saves gitleaks leaks to a json specified by --report={report.json} -func (manager *Manager) Report() error { - close(manager.leakChan) - close(manager.metadata.timings) - - if log.IsLevelEnabled(log.DebugLevel) { - manager.DebugOutput() - } - - if manager.Opts.Report != "" { - if len(manager.GetLeaks()) == 0 { - log.Infof("no leaks found, skipping writing report") - return nil - } - file, err := os.Create(manager.Opts.Report) - if err != nil { - return err - } - - switch manager.Opts.ReportFormat { - case "json": - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - err = encoder.Encode(manager.leaks) - if err != nil { - return err - } - case "csv": - w := csv.NewWriter(file) - _ = w.Write([]string{"repo", "line", "commit", "offender", "rule", "tags", "commitMsg", "author", "email", "file", "date"}) - for _, leak := range manager.GetLeaks() { - w.Write([]string{leak.Repo, leak.Line, leak.Commit, leak.Offender, leak.Rule, leak.Tags, leak.Message, leak.Author, leak.Email, leak.File, leak.Date.Format(time.RFC3339)}) - } - w.Flush() - case "sarif": - s := Sarif{ - Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", - Version: "2.1.0", - Runs: []Runs{ - { - Tool: Tool{ - Driver: Driver{ - Name: "Gitleaks", - SemanticVersion: version.Version, - Rules: manager.configToRules(), - }, - }, - Results: manager.leaksToResults(), - }, - }, - } - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - err = encoder.Encode(s) - if err != nil { - return err - } - } - _ = file.Close() - - log.Infof("report written to %s", manager.Opts.Report) - } - return nil -} - diff --git a/manager/sarif.go b/manager/sarif.go deleted file mode 100644 index f4d056e66..000000000 --- a/manager/sarif.go +++ /dev/null @@ -1,153 +0,0 @@ -package manager - -import ( - "fmt" - "time" -) - -//Sarif ... -type Sarif struct { - Schema string `json:"$schema"` - Version string `json:"version"` - Runs []Runs `json:"runs"` -} - -//ShortDescription ... -type ShortDescription struct { - Text string `json:"text"` -} - -//FullDescription ... -type FullDescription struct { - Text string `json:"text"` -} - -//Rules ... -type Rules struct { - ID string `json:"id"` - Name string `json:"name"` -} - -//Driver ... -type Driver struct { - Name string `json:"name"` - SemanticVersion string `json:"semanticVersion"` - Rules []Rules `json:"rules"` -} - -//Tool ... -type Tool struct { - Driver Driver `json:"driver"` -} - -//Message ... -type Message struct { - Text string `json:"text"` -} - -//ArtifactLocation ... -type ArtifactLocation struct { - URI string `json:"uri"` -} - -//Region ... -type Region struct { - StartLine int `json:"startLine"` - Snippet Snippet `json:"snippet"` -} - -//Snippet ... -type Snippet struct { - Text string `json:"text"` -} - -//PhysicalLocation ... -type PhysicalLocation struct { - ArtifactLocation ArtifactLocation `json:"artifactLocation"` - Region Region `json:"region"` -} - -//Locations ... -type Locations struct { - PhysicalLocation PhysicalLocation `json:"physicalLocation"` -} - -//Results ... -type Results struct { - Message Message `json:"message"` - Properties ResultProperties `json:"properties"` - Locations []Locations `json:"locations"` -} - -//ResultProperties ... -type ResultProperties struct { - Commit string `json:"commit"` - Offender string `json:"offender"` - Date time.Time `json:"date"` - Author string `json:"author"` - Email string `json:"email"` - CommitMessage string `json:"commitMessage"` - Operation string `json:"gitOperation"` - Repo string `json:"repo"` -} - -//Runs ... -type Runs struct { - Tool Tool `json:"tool"` - Results []Results `json:"results"` -} - -func (manager *Manager) configToRules() []Rules { - var rules []Rules - for _, rule := range manager.Config.Rules { - rules = append(rules, Rules{ - ID: rule.Description, - Name: rule.Description, - }) - } - return rules -} - -func (manager *Manager) leaksToResults() []Results { - var results []Results - for _, leak := range manager.leaks { - results = append(results, Results{ - Message: Message{ - Text: fmt.Sprintf("%s secret detected", leak.Rule), - }, - Properties: ResultProperties{ - Commit: leak.Commit, - Offender: leak.Offender, - Date: leak.Date, - Author: leak.Author, - Email: leak.Email, - CommitMessage: leak.Message, - Operation: leak.Operation, - Repo: leak.Repo, - }, - Locations: leakToLocation(leak), - }) - } - - return results -} - -func leakToLocation(leak Leak) []Locations { - return []Locations{ - { - PhysicalLocation: - PhysicalLocation{ - ArtifactLocation: ArtifactLocation{ - URI: leak.File, - }, - Region: Region{ - StartLine: leak.LineNumber, - Snippet: Snippet{ - Text: leak.Line, - }, - }, - }, - }, - } -} - diff --git a/options/options.go b/options/options.go deleted file mode 100644 index e2ed557d2..000000000 --- a/options/options.go +++ /dev/null @@ -1,257 +0,0 @@ -package options - -import ( - "fmt" - "io/ioutil" - "os" - "os/user" - "strings" - - "github.com/zricethezav/gitleaks/v6/version" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" - "github.com/jessevdk/go-flags" - log "github.com/sirupsen/logrus" -) - -// No leaks or early exit due to invalid options -// This block defines the exit codes. Success -const ( - // No leaks or early exit due to invalid options - Success = 0 - LeaksPresent = 1 - ErrorEncountered = 2 - donateMessage = "👋 maintaining gitleaks takes a lot of work so consider sponsoring me or donating a little something\n❤️ https://github.com/sponsors/zricethezav\n💸 https://www.paypal.me/zricethezav\n₿ btc:3GndEzRZa6rJ8ZpkLureUcc5TDHMYfpDxn" -) - -// Options stores values of command line options -type Options struct { - Verbose bool `short:"v" long:"verbose" description:"Show verbose output from scan"` - Repo string `short:"r" long:"repo" description:"Target repository"` - Config string `long:"config" description:"config path"` - Disk bool `long:"disk" description:"Clones repo(s) to disk"` - Version bool `long:"version" description:"version number"` - Username string `long:"username" description:"Username for git repo"` - Password string `long:"password" description:"Password for git repo"` - AccessToken string `long:"access-token" description:"Access token for git repo"` - FilesAtCommit string `long:"files-at-commit" description:"sha of commit to scan all files at commit"` - Threads int `long:"threads" description:"Maximum number of threads gitleaks spawns"` - SSH string `long:"ssh-key" description:"path to ssh key used for auth"` - Uncommited bool `long:"uncommitted" description:"run gitleaks on uncommitted code"` - RepoPath string `long:"repo-path" description:"Path to repo"` - OwnerPath string `long:"owner-path" description:"Path to owner directory (repos discovered)"` - Branch string `long:"branch" description:"Branch to scan"` - Report string `long:"report" description:"path to write json leaks file"` - ReportFormat string `long:"report-format" default:"json" description:"json, csv, sarif"` - Redact bool `long:"redact" description:"redact secrets from log messages and leaks"` - Debug bool `long:"debug" description:"log debug messages"` - RepoConfig bool `long:"repo-config" description:"Load config from target repo. Config file must be \".gitleaks.toml\" or \"gitleaks.toml\""` - PrettyPrint bool `long:"pretty" description:"Pretty print json if leaks are present"` - - // Commit Options - Commit string `long:"commit" description:"sha of commit to scan or \"latest\" to scan the last commit of the repository"` - Commits string `long:"commits" description:"comma separated list of a commits to scan"` - CommitsFile string `long:"commits-file" description:"file of new line separated list of a commits to scan"` - CommitFrom string `long:"commit-from" description:"Commit to start scan from"` - CommitTo string `long:"commit-to" description:"Commit to stop scan"` - CommitSince string `long:"commit-since" description:"Scan commits more recent than a specific date. Ex: '2006-01-02' or '2006-01-02T15:04:05-0700' format."` - CommitUntil string `long:"commit-until" description:"Scan commits older than a specific date. Ex: '2006-01-02' or '2006-01-02T15:04:05-0700' format."` - - Timeout string `long:"timeout" description:"Time allowed per scan. Ex: 10us, 30s, 1m, 1h10m1s"` - Depth int `long:"depth" description:"Number of commits to scan"` - Deletion bool `long:"include-deletion" description:"Scan for patch deletions in addition to patch additions"` - - // Hosts - Host string `long:"host" description:"git hosting service like gitlab or github. Supported hosts include: Github, Gitlab"` - BaseURL string `long:"baseurl" description:"Base URL for API requests. Defaults to the public GitLab or GitHub API, but can be set to a domain endpoint to use with a self hosted server."` - Organization string `long:"org" description:"organization to scan"` - User string `long:"user" description:"user to scan"` - PullRequest string `long:"pr" description:"pull/merge request url"` - ExcludeForks bool `long:"exclude-forks" description:"scan excludes forks"` -} - -// ParseOptions is responsible for parsing options passed in by cli. An Options struct -// is returned if successful. This struct is passed around the program -// and will determine how the program executes. If err, an err message or help message -// will be displayed and the program will exit with code 0. -func ParseOptions() (Options, error) { - var opts Options - parser := flags.NewParser(&opts, flags.Default) - _, err := parser.Parse() - - if err != nil { - if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type != flags.ErrHelp { - parser.WriteHelp(os.Stdout) - } - fmt.Println(donateMessage) - os.Exit(0) - } - - if opts.Version { - if version.Version == "" { - fmt.Println("Gitleaks uses LDFLAGS to pull most recent version. Build with 'make build' for version") - } else { - fmt.Printf("%s\n", version.Version) - } - os.Exit(Success) - } - - if opts.Debug { - log.SetLevel(log.DebugLevel) - } - - return opts, nil -} - -// Guard checks to makes sure there are no invalid options set. -// If invalid sets of options are present, a descriptive error will return -// else nil is returned -func (opts Options) Guard() error { - if !oneOrNoneSet(opts.Repo, opts.OwnerPath, opts.RepoPath, opts.Host) { - return fmt.Errorf("only one target option must can be set. target options: repo, owner-path, repo-path, host") - } - if !oneOrNoneSet(opts.Organization, opts.User, opts.PullRequest) { - return fmt.Errorf("only one target option must can be set. target options: repo, owner-path, repo-path, host") - } - if !oneOrNoneSet(opts.AccessToken, opts.Password) { - log.Warn("both access-token and password are set. Only password will be attempted") - } - - return nil -} - -func oneOrNoneSet(optStr ...string) bool { - c := 0 - for _, s := range optStr { - if s != "" { - c++ - } - } - if c <= 1 { - return true - } - return false -} - -// CloneOptions returns a git.cloneOptions pointer. The authentication method -// is determined by what is passed in via command-Line options. If No -// Username/PW or AccessToken is available and the repo target is not using the -// git protocol then the repo must be a available via no auth. -func (opts Options) CloneOptions() (*git.CloneOptions, error) { - progress := ioutil.Discard - if opts.Verbose { - progress = os.Stdout - } - - if strings.HasPrefix(opts.Repo, "git") { - // using git protocol so needs ssh auth - auth, err := SSHAuth(opts) - if err != nil { - return nil, err - } - return &git.CloneOptions{ - URL: opts.Repo, - Auth: auth, - Progress: progress, - }, nil - } - if opts.Password != "" && opts.Username != "" { - // auth using username and password - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: opts.Username, - Password: opts.Password, - }, - Progress: progress, - }, nil - } - if opts.AccessToken != "" { - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: "gitleaks_user", - Password: opts.AccessToken, - }, - Progress: progress, - }, nil - } - if os.Getenv("GITLEAKS_ACCESS_TOKEN") != "" { - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: "gitleaks_user", - Password: os.Getenv("GITLEAKS_ACCESS_TOKEN"), - }, - Progress: progress, - }, nil - } - - // No Auth, publicly available - return &git.CloneOptions{ - URL: opts.Repo, - Progress: progress, - }, nil -} - -// SSHAuth tried to generate ssh public keys based on what was passed via cli. If no -// path was passed via cli then this will attempt to retrieve keys from the default -// location for ssh keys, $HOME/.ssh/id_rsa. This function is only called if the -// repo url using the git:// protocol. -func SSHAuth(opts Options) (*ssh.PublicKeys, error) { - if opts.SSH != "" { - return ssh.NewPublicKeysFromFile("git", opts.SSH, "") - } - c, err := user.Current() - if err != nil { - return nil, err - } - defaultPath := fmt.Sprintf("%s/.ssh/id_rsa", c.HomeDir) - return ssh.NewPublicKeysFromFile("git", defaultPath, "") -} - -// OpenLocal checks what options are set, if no remote targets are set -// then return true -func (opts Options) OpenLocal() bool { - if opts.Uncommited || opts.RepoPath != "" || opts.Repo == "" { - return true - } - return false -} - -// CheckUncommitted returns a boolean that indicates whether or not gitleaks should check unstaged pre-commit changes -// or if gitleaks should check the entire git history -func (opts Options) CheckUncommitted() bool { - // check to make sure no remote shit is set - if opts.Uncommited { - return true - } - if opts == (Options{}) { - return true - } - if opts.Repo != "" { - return false - } - if opts.RepoPath != "" { - return false - } - if opts.OwnerPath != "" { - return false - } - if opts.Host != "" { - return false - } - return true -} - -// GetAccessToken accepts options and returns a string which is the access token to a git host. -// Setting this option or environment var is necessary if performing an scan with any of the git hosting providers -// in the host pkg. The access token set by cli options takes precedence over env vars. -func GetAccessToken(opts Options) string { - if opts.AccessToken != "" { - return opts.AccessToken - } - return os.Getenv("GITLEAKS_ACCESS_TOKEN") -} diff --git a/options/options_test.go b/options/options_test.go deleted file mode 100644 index 0684d0596..000000000 --- a/options/options_test.go +++ /dev/null @@ -1 +0,0 @@ -package options diff --git a/report/constants.go b/report/constants.go new file mode 100644 index 000000000..7772950c0 --- /dev/null +++ b/report/constants.go @@ -0,0 +1,4 @@ +package report + +const version = "v8.0.0" +const driver = "gitleaks" diff --git a/report/csv.go b/report/csv.go new file mode 100644 index 000000000..e36cbaa2d --- /dev/null +++ b/report/csv.go @@ -0,0 +1,57 @@ +package report + +import ( + "encoding/csv" + "io" + "strconv" +) + +// writeCsv writes the list of findings to a writeCloser. +func writeCsv(f []Finding, w io.WriteCloser) error { + if len(f) == 0 { + return nil + } + defer w.Close() + cw := csv.NewWriter(w) + err := cw.Write([]string{"RuleID", + "Commit", + "File", + "Secret", + "Match", + "StartLine", + "EndLine", + "StartColumn", + "EndColumn", + "Author", + "Message", + "Date", + "Email", + "Fingerprint", + }) + if err != nil { + return err + } + for _, f := range f { + err = cw.Write([]string{f.RuleID, + f.Commit, + f.File, + f.Secret, + f.Match, + strconv.Itoa(f.StartLine), + strconv.Itoa(f.EndLine), + strconv.Itoa(f.StartColumn), + strconv.Itoa(f.EndColumn), + f.Author, + f.Message, + f.Date, + f.Email, + f.Fingerprint, + }) + if err != nil { + return err + } + } + + cw.Flush() + return cw.Error() +} diff --git a/report/csv_test.go b/report/csv_test.go new file mode 100644 index 000000000..c4dd4ec70 --- /dev/null +++ b/report/csv_test.go @@ -0,0 +1,85 @@ +package report + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestWriteCSV(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + }{ + { + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "csv_simple.csv"), + findings: []Finding{ + { + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Fingerprint: "fingerprint", + }, + }}, + { + + wantEmpty: true, + testReportName: "empty", + expected: filepath.Join(expectPath, "report", "this_should_not_exist.csv"), + findings: []Finding{}}, + } + + for _, test := range tests { + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".csv")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = writeCsv(test.findings, tmpfile) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".csv", ".got.csv", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/report/finding.go b/report/finding.go new file mode 100644 index 000000000..885edf711 --- /dev/null +++ b/report/finding.go @@ -0,0 +1,50 @@ +package report + +import ( + "strings" +) + +// Finding contains information about strings that +// have been captured by a tree-sitter query. +type Finding struct { + Description string + StartLine int + EndLine int + StartColumn int + EndColumn int + + Line string `json:"-"` + + Match string + + // Secret contains the full content of what is matched in + // the tree-sitter query. + Secret string + + // File is the name of the file containing the finding + File string + + Commit string + + // Entropy is the shannon entropy of Value + Entropy float32 + + Author string + Email string + Date string + Message string + Tags []string + + // Rule is the name of the rule that was matched + RuleID string + + // unique identifer + Fingerprint string +} + +// Redact removes sensitive information from a finding. +func (f *Finding) Redact() { + f.Line = strings.Replace(f.Line, f.Secret, "REDACTED", -1) + f.Match = strings.Replace(f.Match, f.Secret, "REDACTED", -1) + f.Secret = "REDACTED" +} diff --git a/report/finding_test.go b/report/finding_test.go new file mode 100644 index 000000000..8cfc2c859 --- /dev/null +++ b/report/finding_test.go @@ -0,0 +1,27 @@ +package report + +import "testing" + +func TestRedact(t *testing.T) { + tests := []struct { + findings []Finding + redact bool + }{ + { + redact: true, + findings: []Finding{ + { + Secret: "line containing secret", + Match: "secret", + }, + }}, + } + for _, test := range tests { + for _, f := range test.findings { + f.Redact() + if f.Secret != "REDACTED" { + t.Error("redact not redacting: ", f.Secret) + } + } + } +} diff --git a/report/json.go b/report/json.go new file mode 100644 index 000000000..424cb9c2f --- /dev/null +++ b/report/json.go @@ -0,0 +1,15 @@ +package report + +import ( + "encoding/json" + "io" +) + +func writeJson(findings []Finding, w io.WriteCloser) error { + if len(findings) == 0 { + findings = []Finding{} + } + encoder := json.NewEncoder(w) + encoder.SetIndent("", " ") + return encoder.Encode(findings) +} diff --git a/report/json_test.go b/report/json_test.go new file mode 100644 index 000000000..d20cf86bf --- /dev/null +++ b/report/json_test.go @@ -0,0 +1,88 @@ +package report + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestWriteJSON(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + }{ + { + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "json_simple.json"), + findings: []Finding{ + { + + Description: "", + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Tags: []string{}, + }, + }}, + { + + testReportName: "empty", + expected: filepath.Join(expectPath, "report", "empty.json"), + findings: []Finding{}}, + } + + for _, test := range tests { + // create tmp file using os.TempDir() + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".json")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = writeJson(test.findings, tmpfile) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + os.Remove(tmpfile.Name()) + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".json", ".got.json", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/report/report.go b/report/report.go new file mode 100644 index 000000000..c085c53b0 --- /dev/null +++ b/report/report.go @@ -0,0 +1,32 @@ +package report + +import ( + "os" + "strings" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + // https://cwe.mitre.org/data/definitions/798.html + CWE = "CWE-798" + CWE_DESCRIPTION = "Use of Hard-coded Credentials" +) + +func Write(findings []Finding, cfg config.Config, ext string, reportPath string) error { + file, err := os.Create(reportPath) + if err != nil { + return err + } + ext = strings.ToLower(ext) + switch ext { + case ".json", "json": + err = writeJson(findings, file) + case ".csv", "csv": + err = writeCsv(findings, file) + case ".sarif", "sarif": + err = writeSarif(cfg, findings, file) + } + + return err +} diff --git a/report/report_test.go b/report/report_test.go new file mode 100644 index 000000000..ae0b84db2 --- /dev/null +++ b/report/report_test.go @@ -0,0 +1,111 @@ +package report + +import ( + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + expectPath = "../testdata/expected/" + tmpPath = "../testdata/tmp" +) + +func TestReport(t *testing.T) { + tests := []struct { + findings []Finding + ext string + wantEmpty bool + }{ + { + ext: "json", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: ".json", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: ".jsonj", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + wantEmpty: true, + }, + { + ext: ".csv", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: "csv", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: "CSV", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + // { + // ext: "SARIF", + // findings: []Finding{ + // { + // RuleID: "test-rule", + // }, + // }, + // }, + } + + for i, test := range tests { + tmpfile, err := os.Create(filepath.Join(tmpPath, strconv.Itoa(i)+test.ext)) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = Write(test.findings, config.Config{}, test.ext, tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + os.Remove(tmpfile.Name()) + + if len(got) == 0 && !test.wantEmpty { + t.Errorf("got empty file with extension " + test.ext) + } + + if test.wantEmpty { + if len(got) > 0 { + t.Errorf("Expected empty file, got %s", got) + } + continue + } + } +} diff --git a/report/sarif.go b/report/sarif.go new file mode 100644 index 000000000..d1df25896 --- /dev/null +++ b/report/sarif.go @@ -0,0 +1,209 @@ +package report + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func writeSarif(cfg config.Config, findings []Finding, w io.WriteCloser) error { + sarif := Sarif{ + Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", + Version: "2.1.0", + Runs: getRuns(cfg, findings), + } + + encoder := json.NewEncoder(w) + encoder.SetIndent("", " ") + return encoder.Encode(sarif) +} + +func getRuns(cfg config.Config, findings []Finding) []Runs { + return []Runs{ + { + Tool: getTool(cfg), + Results: getResults(findings), + }, + } +} + +func getTool(cfg config.Config) Tool { + tool := Tool{ + Driver: Driver{ + Name: driver, + SemanticVersion: version, + Rules: getRules(cfg), + }, + } + + // if this tool has no rules, ensure that it is represented as [] instead of null/nil + if hasEmptyRules(tool) { + tool.Driver.Rules = make([]Rules, 0) + } + + return tool +} + +func hasEmptyRules(tool Tool) bool { + return len(tool.Driver.Rules) == 0 +} + +func getRules(cfg config.Config) []Rules { + // TODO for _, rule := range cfg.Rules { + var rules []Rules + for _, rule := range cfg.OrderedRules() { + shortDescription := ShortDescription{ + Text: rule.Description, + } + if rule.Regex != nil { + shortDescription = ShortDescription{ + Text: rule.Regex.String(), + } + } else if rule.Path != nil { + shortDescription = ShortDescription{ + Text: rule.Path.String(), + } + } + rules = append(rules, Rules{ + ID: rule.RuleID, + Name: rule.Description, + Description: shortDescription, + }) + } + return rules +} + +func messageText(f Finding) string { + if f.Commit == "" { + return fmt.Sprintf("%s has detected secret for file %s.", f.RuleID, f.File) + } + + return fmt.Sprintf("%s has detected secret for file %s at commit %s.", f.RuleID, f.File, f.Commit) + +} + +func getResults(findings []Finding) []Results { + results := []Results{} + for _, f := range findings { + r := Results{ + Message: Message{ + Text: messageText(f), + }, + RuleId: f.RuleID, + Locations: getLocation(f), + // This information goes in partial fingerprings until revision + // data can be added somewhere else + PartialFingerPrints: PartialFingerPrints{ + CommitSha: f.Commit, + Email: f.Email, + CommitMessage: f.Message, + Date: f.Date, + Author: f.Author, + }, + } + results = append(results, r) + } + return results +} + +func getLocation(f Finding) []Locations { + return []Locations{ + { + PhysicalLocation: PhysicalLocation{ + ArtifactLocation: ArtifactLocation{ + URI: f.File, + }, + Region: Region{ + StartLine: f.StartLine, + EndLine: f.EndLine, + StartColumn: f.StartColumn, + EndColumn: f.EndColumn, + Snippet: Snippet{ + Text: f.Secret, + }, + }, + }, + }, + } +} + +type PartialFingerPrints struct { + CommitSha string `json:"commitSha"` + Email string `json:"email"` + Author string `json:"author"` + Date string `json:"date"` + CommitMessage string `json:"commitMessage"` +} + +type Sarif struct { + Schema string `json:"$schema"` + Version string `json:"version"` + Runs []Runs `json:"runs"` +} + +type ShortDescription struct { + Text string `json:"text"` +} + +type FullDescription struct { + Text string `json:"text"` +} + +type Rules struct { + ID string `json:"id"` + Name string `json:"name"` + Description ShortDescription `json:"shortDescription"` +} + +type Driver struct { + Name string `json:"name"` + SemanticVersion string `json:"semanticVersion"` + Rules []Rules `json:"rules"` +} + +type Tool struct { + Driver Driver `json:"driver"` +} + +type Message struct { + Text string `json:"text"` +} + +type ArtifactLocation struct { + URI string `json:"uri"` +} + +type Region struct { + StartLine int `json:"startLine"` + StartColumn int `json:"startColumn"` + EndLine int `json:"endLine"` + EndColumn int `json:"endColumn"` + Snippet Snippet `json:"snippet"` +} + +type Snippet struct { + Text string `json:"text"` +} + +type PhysicalLocation struct { + ArtifactLocation ArtifactLocation `json:"artifactLocation"` + Region Region `json:"region"` +} + +type Locations struct { + PhysicalLocation PhysicalLocation `json:"physicalLocation"` +} + +type Results struct { + Message Message `json:"message"` + RuleId string `json:"ruleId"` + Locations []Locations `json:"locations"` + PartialFingerPrints `json:"partialFingerprints"` +} + +type Runs struct { + Tool Tool `json:"tool"` + Results []Results `json:"results"` +} diff --git a/report/sarif_test.go b/report/sarif_test.go new file mode 100644 index 000000000..3418fb99b --- /dev/null +++ b/report/sarif_test.go @@ -0,0 +1,111 @@ +package report + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/spf13/viper" + "github.com/zricethezav/gitleaks/v8/config" +) + +const configPath = "../testdata/config/" + +func TestWriteSarif(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + cfgName string + }{ + { + cfgName: "simple", + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "sarif_simple.sarif"), + findings: []Finding{ + { + + Description: "A test rule", + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Tags: []string{}, + }, + }}, + } + + for _, test := range tests { + // create tmp file using os.TempDir() + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".json")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(test.cfgName) + viper.SetConfigType("toml") + err = viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + + cfg, err := vc.Translate() + if err != nil { + t.Error(err) + } + err = writeSarif(cfg, test.findings, tmpfile) + fmt.Println(cfg) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + os.Remove(tmpfile.Name()) + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".sarif", ".got.sarif", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/scan/repo.go b/scan/repo.go deleted file mode 100644 index 9dcb0646e..000000000 --- a/scan/repo.go +++ /dev/null @@ -1,304 +0,0 @@ -package scan - -import ( - "context" - "crypto/md5" - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "runtime" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - - "github.com/BurntSushi/toml" - "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/storage/memory" - log "github.com/sirupsen/logrus" -) - -// Repo wraps a *git.Repository object in addition to a manager object and the name of the repo. -// Commits are inspected from the *git.Repository object. If a Commit is found then we send it -// via the manager LeakChan where the manager receives and keeps track of all leaks. -type Repo struct { - *git.Repository - - // config is used when the --repo-config option is set. - // This allows users to load up configs specific to their repos. - // Imagine the scenario where you are doing an scan of a large organization - // and you want certain repos to look for specific rules. If those specific repos - // have a gitleaks.toml or .gitleaks.toml config then those configs will be used specifically - // for those repo scans. - config config.Config - - // ctx is used to signal timeouts to running goroutines - ctx context.Context - cancel context.CancelFunc - - Name string - Manager *manager.Manager -} - -// NewRepo initializes and returns a Repo struct. -func NewRepo(m *manager.Manager) *Repo { - return &Repo{ - Manager: m, - config: m.Config, - ctx: context.Background(), - } -} - -// Run accepts a manager and begins an scan based on the options/configs set in the manager. -func Run(m *manager.Manager) error { - if m.Opts.OwnerPath != "" { - files, err := ioutil.ReadDir(m.Opts.OwnerPath) - if err != nil { - return err - } - for _, f := range files { - if !f.IsDir() { - continue - } - m.Opts.RepoPath = fmt.Sprintf("%s/%s", m.Opts.OwnerPath, f.Name()) - if err := runHelper(NewRepo(m)); err != nil { - log.Warnf("%s is not a git repo, skipping", f.Name()) - } - } - return nil - } - - return runHelper(NewRepo(m)) -} - -func runHelper(r *Repo) error { - // Ignore allowlisted repos - for _, allowListedRepo := range r.Manager.Config.Allowlist.Repos { - if RegexMatched(r.Manager.Opts.RepoPath, allowListedRepo) { - return nil - } - if RegexMatched(r.Manager.Opts.Repo, allowListedRepo) { - return nil - } - } - if r.Manager.Opts.OpenLocal() { - r.Name = path.Base(r.Manager.Opts.RepoPath) - if err := r.Open(); err != nil { - return err - } - - // Check if we are checking uncommitted files. This is the default behavior - // for a "$ gitleaks" command with no options set - if r.Manager.Opts.CheckUncommitted() { - if err := r.scanUncommitted(); err != nil { - return err - } - return nil - } - } else { - if err := r.Clone(nil); err != nil { - return err - } - } - return r.Scan() -} - -// Clone will clone a repo and return a Repo struct which contains a go-git repo. The clone method -// is determined by the clone options set in Manager.metadata.cloneOptions -func (repo *Repo) Clone(cloneOption *git.CloneOptions) error { - var ( - repository *git.Repository - err error - ) - if cloneOption == nil { - cloneOption = repo.Manager.CloneOptions - } - - log.Infof("cloning... %s", cloneOption.URL) - start := time.Now() - - if repo.Manager.CloneDir != "" { - clonePath := fmt.Sprintf("%s/%x", repo.Manager.CloneDir, md5.Sum([]byte(time.Now().String()))) - repository, err = git.PlainClone(clonePath, false, cloneOption) - } else { - repository, err = git.Clone(memory.NewStorage(), nil, cloneOption) - } - if err != nil { - return err - } - repo.Name = filepath.Base(repo.Manager.Opts.Repo) - repo.Repository = repository - repo.Manager.RecordTime(manager.CloneTime(howLong(start))) - - return nil -} - -// howManyThreads will return a number 1-GOMAXPROCS which is the number -// of goroutines that will spawn during gitleaks execution -func howManyThreads(threads int) int { - maxThreads := runtime.GOMAXPROCS(0) - if threads == 0 { - return 1 - } else if threads > maxThreads { - log.Warnf("%d threads set too high, setting to system max, %d", threads, maxThreads) - return maxThreads - } - return threads -} - -// getLogOptions determines what log options are used when iterating through commits. -// It is similar to `git log {branch}`. Default behavior is to log ALL branches so -// gitleaks gets the full git history. -func getLogOptions(repo *Repo) (*git.LogOptions, error) { - var logOpts git.LogOptions - const dateformat string = "2006-01-02" - const timeformat string = "2006-01-02T15:04:05-0700" - if repo.Manager.Opts.CommitFrom != "" { - logOpts.From = plumbing.NewHash(repo.Manager.Opts.CommitFrom) - } - if repo.Manager.Opts.CommitSince != "" { - if t, err := time.Parse(timeformat, repo.Manager.Opts.CommitSince); err == nil { - logOpts.Since = &t - } else if t, err := time.Parse(dateformat, repo.Manager.Opts.CommitSince); err == nil { - logOpts.Since = &t - } else { - return nil, err - } - } - if repo.Manager.Opts.CommitUntil != "" { - if t, err := time.Parse(timeformat, repo.Manager.Opts.CommitUntil); err == nil { - logOpts.Until = &t - } else if t, err := time.Parse(dateformat, repo.Manager.Opts.CommitUntil); err == nil { - logOpts.Until = &t - } else { - return nil, err - } - } - if repo.Manager.Opts.Branch != "" { - refs, err := repo.Storer.IterReferences() - if err != nil { - return nil, err - } - err = refs.ForEach(func(ref *plumbing.Reference) error { - if ref.Name().IsTag() { - return nil - } - // check heads first - if ref.Name().String() == "refs/heads/"+repo.Manager.Opts.Branch { - logOpts = git.LogOptions{ - From: ref.Hash(), - } - return nil - } else if ref.Name().String() == "refs/remotes/origin/"+repo.Manager.Opts.Branch { - logOpts = git.LogOptions{ - From: ref.Hash(), - } - return nil - } - return nil - }) - if err != nil { - return nil, err - } - - if logOpts.From.IsZero() { - return nil, fmt.Errorf("could not find branch %s", repo.Manager.Opts.Branch) - } - return &logOpts, nil - } - if !logOpts.From.IsZero() || logOpts.Since != nil || logOpts.Until != nil { - return &logOpts, nil - } - return &git.LogOptions{All: true}, nil -} - -// howLong accepts a time.Time object which is subtracted from time.Now() and -// converted to nanoseconds which is returned -func howLong(t time.Time) int64 { - return time.Now().Sub(t).Nanoseconds() -} - -// Open opens a local repo either from repo-path or $PWD -func (repo *Repo) Open() error { - if repo.Manager.Opts.RepoPath != "" { - // open git repo from repo path - repository, err := git.PlainOpen(repo.Manager.Opts.RepoPath) - if err != nil { - return err - } - repo.Repository = repository - } else { - // open git repo from PWD - dir, err := os.Getwd() - if err != nil { - return err - } - repository, err := git.PlainOpen(dir) - if err != nil { - return err - } - repo.Repository = repository - repo.Name = path.Base(dir) - } - return nil -} - -func (repo *Repo) loadRepoConfig() (config.Config, error) { - wt, err := repo.Repository.Worktree() - if err != nil { - return config.Config{}, err - } - var f billy.File - f, _ = wt.Filesystem.Open(".gitleaks.toml") - if f == nil { - f, err = wt.Filesystem.Open("gitleaks.toml") - if err != nil { - return config.Config{}, fmt.Errorf("problem loading repo config: %v", err) - } - } - defer f.Close() - var tomlLoader config.TomlLoader - _, err = toml.DecodeReader(f, &tomlLoader) - if err != nil { - return config.Config{}, err - } - - return tomlLoader.Parse() -} - -// timeoutReached returns true if the timeout deadline has been met. This function should be used -// at the top of loops and before potentially long running goroutines (like checking inefficient regexes) -func (repo *Repo) timeoutReached() bool { - if repo.ctx.Err() == context.DeadlineExceeded { - return true - } - return false -} - -// setupTimeout parses the --timeout option and assigns a context with timeout to the manager -// which will exit early if the timeout has been met. -func (repo *Repo) setupTimeout() error { - if repo.Manager.Opts.Timeout == "" { - return nil - } - timeout, err := time.ParseDuration(repo.Manager.Opts.Timeout) - if err != nil { - return err - } - - repo.ctx, repo.cancel = context.WithTimeout(context.Background(), timeout) - - go func() { - select { - case <-repo.ctx.Done(): - if repo.timeoutReached() { - log.Warnf("Timeout deadline (%s) exceeded for %s", timeout.String(), repo.Name) - } - } - }() - return nil -} diff --git a/scan/rule.go b/scan/rule.go deleted file mode 100644 index 28cc0f896..000000000 --- a/scan/rule.go +++ /dev/null @@ -1,395 +0,0 @@ -package scan - -import ( - "bufio" - "fmt" - "io" - "math" - "path/filepath" - "regexp" - "strconv" - "strings" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - - fdiff "github.com/go-git/go-git/v5/plumbing/format/diff" - "github.com/go-git/go-git/v5/plumbing/object" - log "github.com/sirupsen/logrus" -) - -const ( - diffAddPrefix = "+" - diffAddFilePrefix = "+++ b" - diffAddFilePrefixSlash = "+++ b/" - diffLineSignature = " @@" - diffLineSignaturePrefix = "@@ " - defaultLineNumber = -1 -) - -// CheckRules accepts bundle and checks each rule defined in the config against the bundle's content. -func (repo *Repo) CheckRules(bundle *Bundle) { - filename := filepath.Base(bundle.FilePath) - path := filepath.Dir(bundle.FilePath) - - bundle.lineLookup = make(map[string]bool) - - // We want to check if there is a allowlist for this file - if len(repo.config.Allowlist.Files) != 0 { - for _, reFileName := range repo.config.Allowlist.Files { - if RegexMatched(filename, reFileName) { - log.Debugf("allowlisted file found, skipping scan of file: %s", filename) - return - } - } - } - - // We want to check if there is a allowlist for this path - if len(repo.config.Allowlist.Paths) != 0 { - for _, reFilePath := range repo.config.Allowlist.Paths { - if RegexMatched(path, reFilePath) { - log.Debugf("file in allowlisted path found, skipping scan of file: %s", filename) - return - } - } - } - - for _, rule := range repo.config.Rules { - start := time.Now() - - // For each rule we want to check filename allowlists - if isAllowListed(filename, rule.AllowList.Files) || isAllowListed(path, rule.AllowList.Paths) { - continue - } - - // If it has fileNameRegex and it doesnt match we continue to next rule - if ruleContainFileRegex(rule) && !RegexMatched(filename, rule.File) { - continue - } - - // If it has filePathRegex and it doesnt match we continue to next rule - if ruleContainPathRegex(rule) && !RegexMatched(path, rule.Path) { - continue - } - - // If it doesnt contain a Content regex then it is a filename regex match - if !ruleContainRegex(rule) { - repo.Manager.SendLeaks(manager.Leak{ - LineNumber: defaultLineNumber, - Line: "N/A", - Offender: "Filename/path offender: " + filename, - Commit: bundle.Commit.Hash.String(), - Repo: repo.Name, - Message: bundle.Commit.Message, - Rule: rule.Description, - Author: bundle.Commit.Author.Name, - Email: bundle.Commit.Author.Email, - Date: bundle.Commit.Author.When, - Tags: strings.Join(rule.Tags, ", "), - File: filename, - Operation: diffOpToString(bundle.Operation), - }) - } else { - //otherwise we check if it matches Content regex - locs := rule.Regex.FindAllIndex([]byte(bundle.Content), -1) - if len(locs) != 0 { - for _, loc := range locs { - start := loc[0] - end := loc[1] - for start != 0 && bundle.Content[start] != '\n' { - start-- - } - - if bundle.Content[start] == '\n' { - start++ - } - - for end < len(bundle.Content)-1 && bundle.Content[end] != '\n' { - end++ - } - - line := bundle.Content[start:end] - offender := bundle.Content[loc[0]:loc[1]] - groups := rule.Regex.FindStringSubmatch(offender) - - if isAllowListed(line, append(rule.AllowList.Regexes, repo.config.Allowlist.Regexes...)) { - continue - } - - if len(rule.Entropies) != 0 && !trippedEntropy(groups, rule) { - continue - } - - leak := manager.Leak{ - LineNumber: defaultLineNumber, - Line: line, - Offender: offender, - Commit: bundle.Commit.Hash.String(), - Repo: repo.Name, - Message: bundle.Commit.Message, - Rule: rule.Description, - Author: bundle.Commit.Author.Name, - Email: bundle.Commit.Author.Email, - Date: bundle.Commit.Author.When, - Tags: strings.Join(rule.Tags, ", "), - File: bundle.FilePath, - Operation: diffOpToString(bundle.Operation), - } - - // only search for line numbers on non-deletions - if bundle.Operation != fdiff.Delete { - extractAndInjectLineNumber(&leak, bundle, repo) - } - - repo.Manager.SendLeaks(leak) - } - } - } - - repo.Manager.RecordTime(manager.RegexTime{ - Time: howLong(start), - Regex: rule.Regex.String(), - }) - } -} - -// RegexMatched matched an interface to a regular expression. The interface f can -// be a string type or go-git *object.File type. -func RegexMatched(f interface{}, re *regexp.Regexp) bool { - if re == nil { - return false - } - switch f.(type) { - case nil: - return false - case string: - if re.FindString(f.(string)) != "" { - return true - } - return false - case *object.File: - if re.FindString(f.(*object.File).Name) != "" { - return true - } - return false - } - return false -} - -// diffOpToString converts a fdiff.Operation to a string -func diffOpToString(operation fdiff.Operation) string { - switch operation { - case fdiff.Add: - return "addition" - case fdiff.Equal: - return "equal" - default: - return "deletion" - } -} - -// extractAndInjectLine accepts a leak, bundle, and repo which it uses to do a reverse search in order to extract -// the line number of a historic or present leak. The function is only called when the git operation is an addition -// or none, it does not get called when the git operation is deletion. -func extractAndInjectLineNumber(leak *manager.Leak, bundle *Bundle, repo *Repo) { - var err error - - switch bundle.scanType { - case patchScan: - if bundle.Patch == "" { - return - } - - // This is needed as some patches generate strings that are larger than - // scanners max size (MaxScanTokenSize = 64 * 1024) - // https://github.com/zricethezav/gitleaks/issues/413 - buf := make([]byte, len(bundle.Patch)) - scanner := bufio.NewScanner(strings.NewReader(bundle.Patch)) - scanner.Buffer(buf, len(bundle.Patch)) - scanner.Split(bufio.ScanLines) - - currFile := "" - currLine := 0 - currStartDiffLine := 0 - - for scanner.Scan() { - txt := scanner.Text() - if strings.HasPrefix(txt, diffAddFilePrefix) { - currStartDiffLine = 1 - currLine = 0 - currFile = strings.Split(txt, diffAddFilePrefixSlash)[1] - - // next line contains diff line information so lets scan it here - scanner.Scan() - - txt := scanner.Text() - i := strings.Index(txt, diffAddPrefix) - pairs := strings.Split(strings.Split(txt[i+1:], diffLineSignature)[0], ",") - currStartDiffLine, err = strconv.Atoi(pairs[0]) - if err != nil { - log.Debug(err) - return - } - continue - } else if strings.HasPrefix(txt, diffAddPrefix) && strings.Contains(txt, leak.Line) && leak.File == currFile { - potentialLine := currLine + currStartDiffLine - if _, ok := bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, potentialLine, currFile)]; !ok { - bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, potentialLine, currFile)] = true - leak.LineNumber = potentialLine - return - } - } else if strings.HasPrefix(txt, diffLineSignaturePrefix) && currStartDiffLine != 0 { - // This logic is used for when there are multiple leaks of the same offender within the same patch - i := strings.Index(txt, diffAddPrefix) - pairs := strings.Split(strings.Split(txt[i+1:], diffLineSignature)[0], ",") - currStartDiffLine, err = strconv.Atoi(pairs[0]) - if err != nil { - log.Debug(err) - return - } - currLine = 0 - if !strings.HasSuffix(txt, diffLineSignature) { - currLine = -1 - } - } - currLine++ - } - case commitScan: - if bundle.Commit == nil { - return - } - f, err := bundle.Commit.File(bundle.FilePath) - if err != nil { - log.Error(err) - return - } - r, err := f.Reader() - if err != nil { - log.Error(err) - return - } - leak.LineNumber = extractLineHelper(r, bundle, leak) - case uncommittedScan: - wt, err := repo.Worktree() - if err != nil { - log.Error(err) - return - } - f, err := wt.Filesystem.Open(leak.File) - if err != nil { - log.Error(err) - return - } - leak.LineNumber = extractLineHelper(f, bundle, leak) - } -} - -// extractLineHelper consolidates code for checking the leak line against the contents of a reader to find the -// line number of the leak. -func extractLineHelper(r io.Reader, bundle *Bundle, leak *manager.Leak) int { - scanner := bufio.NewScanner(r) - lineNumber := 1 - for scanner.Scan() { - if leak.Line == scanner.Text() { - if _, ok := bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, lineNumber, bundle.FilePath)]; !ok { - bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, lineNumber, bundle.FilePath)] = true - return lineNumber - } - } - lineNumber++ - } - return -1 -} - -// trippedEntropy checks if a given capture group or offender falls in between entropy ranges -// supplied by a custom gitleaks configuration. Gitleaks do not check entropy by default. -func trippedEntropy(groups []string, rule config.Rule) bool { - for _, e := range rule.Entropies { - if len(groups) > e.Group { - entropy := shannonEntropy(groups[e.Group]) - if entropy >= e.Min && entropy <= e.Max { - return true - } - } - } - return false -} - -// shannonEntropy calculates the entropy of data using the formula defined here: -// https://en.wiktionary.org/wiki/Shannon_entropy -// Another way to think about what this is doing is calculating the number of bits -// needed to on average encode the data. So, the higher the entropy, the more random the data, the -// more bits needed to encode that data. -func shannonEntropy(data string) (entropy float64) { - if data == "" { - return 0 - } - - charCounts := make(map[rune]int) - for _, char := range data { - charCounts[char]++ - } - - invLength := 1.0 / float64(len(data)) - for _, count := range charCounts { - freq := float64(count) * invLength - entropy -= freq * math.Log2(freq) - } - - return entropy -} - -// Checks if the given rule has a regex -func ruleContainRegex(rule config.Rule) bool { - if rule.Regex == nil { - return false - } - if rule.Regex.String() == "" { - return false - } - return true -} - -// Checks if the given rule has a file name regex -func ruleContainFileRegex(rule config.Rule) bool { - if rule.File == nil { - return false - } - if rule.File.String() == "" { - return false - } - return true -} - -// Checks if the given rule has a file path regex -func ruleContainPathRegex(rule config.Rule) bool { - if rule.Path == nil { - return false - } - if rule.Path.String() == "" { - return false - } - return true -} - -func isCommitAllowListed(commitHash string, allowlistedCommits []string) bool { - for _, hash := range allowlistedCommits { - if commitHash == hash { - return true - } - } - return false -} - -func isAllowListed(target string, allowList []*regexp.Regexp) bool { - if len(allowList) != 0 { - for _, re := range allowList { - if re.FindString(target) != "" { - return true - } - } - } - return false - -} diff --git a/scan/scan.go b/scan/scan.go deleted file mode 100644 index 0bad8b2d4..000000000 --- a/scan/scan.go +++ /dev/null @@ -1,493 +0,0 @@ -package scan - -import ( - "bufio" - "bytes" - "fmt" - "io" - "os" - "strings" - "sync" - "time" - - "github.com/zricethezav/gitleaks/v6/manager" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - fdiff "github.com/go-git/go-git/v5/plumbing/format/diff" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/sergi/go-diff/diffmatchpatch" - log "github.com/sirupsen/logrus" -) - -// Bundle contains various git information for scans. -type Bundle struct { - Commit *object.Commit - Patch string - Content string - FilePath string - Operation fdiff.Operation - - reader io.Reader - lineLookup map[string]bool - scanType int -} - -// commitScanner is a function signature for scanning commits. There is some -// redundant work needed by scanning all files at a commit (--files-at-commit=) and scanning -// the patches generated by a commit (--commit=). The function scanCommit wraps that redundant work -// and accepts a commitScanner for the different logic needed between the two cases described above. -type commitScanner func(c *object.Commit, repo *Repo) error - -const ( - // We need to differentiate between scans as the logic for line searching is different between - // scanning patches, commits, and uncommitted files. - patchScan int = iota + 1 - uncommittedScan - commitScan -) - -// Scan is responsible for scanning the entire history (default behavior) of a -// git repo. Options that can change the behavior of this function include: --Commit, --depth, --branch. -// See options/options.go for an explanation on these options. -func (repo *Repo) Scan() error { - if err := repo.setupTimeout(); err != nil { - return err - } - if repo.cancel != nil { - defer repo.cancel() - } - - if repo.Repository == nil { - return fmt.Errorf("%s repo is empty", repo.Name) - } - - // load up alternative config if possible, if not use manager's config - if repo.Manager.Opts.RepoConfig { - cfg, err := repo.loadRepoConfig() - if err != nil { - return err - } - repo.config = cfg - } - - scanTimeStart := time.Now() - - // See https://github.com/zricethezav/gitleaks/issues/326 - // Scan commit patches, all files at a commit, or a range of commits - if repo.Manager.Opts.Commit != "" { - return scanCommit(repo.Manager.Opts.Commit, repo, scanCommitPatches) - } else if repo.Manager.Opts.FilesAtCommit != "" { - return scanCommit(repo.Manager.Opts.FilesAtCommit, repo, scanFilesAtCommit) - } else if repo.Manager.Opts.Commits != "" { - commits := strings.Split(repo.Manager.Opts.Commits, ",") - for _, c := range commits { - err := scanCommit(c, repo, scanCommitPatches) - if err != nil { - return err - } - } - return nil - } else if repo.Manager.Opts.CommitsFile != "" { - file, err := os.Open(repo.Manager.Opts.CommitsFile) - if err != nil { - return err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - err := scanCommit(scanner.Text(), repo, scanCommitPatches) - if err != nil { - return err - } - } - return nil - } - - logOpts, err := getLogOptions(repo) - if err != nil { - return err - } - cIter, err := repo.Log(logOpts) - if err != nil { - return err - } - - cc := 0 - semaphore := make(chan bool, howManyThreads(repo.Manager.Opts.Threads)) - wg := sync.WaitGroup{} - err = cIter.ForEach(func(c *object.Commit) error { - if c == nil || repo.timeoutReached() || repo.depthReached(cc) { - return storer.ErrStop - } - - // Check if Commit is allowlisted - if isCommitAllowListed(c.Hash.String(), repo.config.Allowlist.Commits) { - return nil - } - - // Check if at root - if len(c.ParentHashes) == 0 { - cc++ - err = scanFilesAtCommit(c, repo) - if err != nil { - return err - } - return nil - } - - // increase Commit counter - cc++ - - // inspect first parent only as all other parents will be eventually reached - // (they exist as the tip of other branches, etc) - // See https://github.com/zricethezav/gitleaks/issues/413 for details - parent, err := c.Parent(0) - if err != nil { - return err - } - - defer func() { - if err := recover(); err != nil { - // sometimes the Patch generation will fail due to a known bug in - // sergi's go-diff: https://github.com/sergi/go-diff/issues/89. - // Once a fix has been merged I will remove this recover. - return - } - }() - if repo.timeoutReached() { - return nil - } - if parent == nil { - // shouldn't reach this point but just in case - return nil - } - - start := time.Now() - patch, err := parent.Patch(c) - if err != nil { - log.Errorf("could not generate Patch") - } - repo.Manager.RecordTime(manager.PatchTime(howLong(start))) - - wg.Add(1) - semaphore <- true - go func(c *object.Commit, patch *object.Patch) { - defer func() { - <-semaphore - wg.Done() - }() - scanPatch(patch, c, repo) - }(c, patch) - - if c.Hash.String() == repo.Manager.Opts.CommitTo { - return storer.ErrStop - } - return nil - }) - - wg.Wait() - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - repo.Manager.IncrementCommits(cc) - return nil -} - -// scanEmpty scans an empty repo without any commits. See https://github.com/zricethezav/gitleaks/issues/352 -func (repo *Repo) scanEmpty() error { - scanTimeStart := time.Now() - wt, err := repo.Worktree() - if err != nil { - return err - } - - status, err := wt.Status() - if err != nil { - return err - } - for fn := range status { - workTreeBuf := bytes.NewBuffer(nil) - workTreeFile, err := wt.Filesystem.Open(fn) - if err != nil { - continue - } - if _, err := io.Copy(workTreeBuf, workTreeFile); err != nil { - return err - } - repo.CheckRules(&Bundle{ - Content: workTreeBuf.String(), - FilePath: workTreeFile.Name(), - Commit: emptyCommit(), - scanType: uncommittedScan, - }) - } - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - return nil -} - -// scanUncommitted will do a `git diff` and scan changed files that are being tracked. This is useful functionality -// for a pre-Commit hook so you can make sure your code does not have any leaks before committing. -func (repo *Repo) scanUncommitted() error { - // load up alternative config if possible, if not use manager's config - if repo.Manager.Opts.RepoConfig { - cfg, err := repo.loadRepoConfig() - if err != nil { - return err - } - repo.config = cfg - } - - if err := repo.setupTimeout(); err != nil { - return err - } - - r, err := repo.Head() - if err == plumbing.ErrReferenceNotFound { - // possibly an empty repo, or maybe its not, either way lets scan all the files in the directory - return repo.scanEmpty() - } else if err != nil { - return err - } - - scanTimeStart := time.Now() - - c, err := repo.CommitObject(r.Hash()) - if err != nil { - return err - } - // Staged change so the Commit details do not yet exist. Insert empty defaults. - c.Hash = plumbing.Hash{} - c.Message = "***STAGED CHANGES***" - c.Author.Name = "" - c.Author.Email = "" - c.Author.When = time.Unix(0, 0).UTC() - - prevTree, err := c.Tree() - if err != nil { - return err - } - wt, err := repo.Worktree() - if err != nil { - return err - } - - status, err := wt.Status() - for fn, state := range status { - var ( - prevFileContents string - currFileContents string - filename string - ) - - if state.Staging != git.Untracked { - if state.Staging == git.Deleted { - // file in staging has been deleted, aka it is not on the filesystem - // so the contents of the file are "" - currFileContents = "" - } else { - workTreeBuf := bytes.NewBuffer(nil) - workTreeFile, err := wt.Filesystem.Open(fn) - if err != nil { - continue - } - if _, err := io.Copy(workTreeBuf, workTreeFile); err != nil { - return err - } - currFileContents = workTreeBuf.String() - filename = workTreeFile.Name() - } - - // get files at HEAD state - prevFile, err := prevTree.File(fn) - if err != nil { - prevFileContents = "" - - } else { - prevFileContents, err = prevFile.Contents() - if err != nil { - return err - } - if filename == "" { - filename = prevFile.Name - } - } - - dmp := diffmatchpatch.New() - diffs := dmp.DiffCleanupSemantic(dmp.DiffMain(prevFileContents, currFileContents, false)) - var diffContents string - for _, d := range diffs { - if d.Type == diffmatchpatch.DiffInsert { - diffContents += fmt.Sprintf("%s\n", d.Text) - } - } - repo.CheckRules(&Bundle{ - Content: diffContents, - FilePath: filename, - Commit: c, - scanType: uncommittedScan, - }) - } - } - - if err != nil { - return err - } - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - return nil -} - -// scan accepts a Patch, Commit, and repo. If the patches contains files that are -// binary, then gitleaks will skip scanning that file OR if a file is matched on -// allowlisted files set in the configuration. If a global rule for files is defined and a filename -// matches said global rule, then a leak is sent to the manager. -// After that, file chunks are created which are then inspected by InspectString() -func scanPatch(patch *object.Patch, c *object.Commit, repo *Repo) { - bundle := Bundle{ - Commit: c, - Patch: patch.String(), - scanType: patchScan, - } - for _, f := range patch.FilePatches() { - if repo.timeoutReached() { - return - } - if f.IsBinary() { - continue - } - for _, chunk := range f.Chunks() { - if chunk.Type() == fdiff.Add || (repo.Manager.Opts.Deletion && chunk.Type() == fdiff.Delete) { - bundle.Content = chunk.Content() - bundle.Operation = chunk.Type() - - // get filepath - from, to := f.Files() - if from != nil { - bundle.FilePath = from.Path() - } else if to != nil { - bundle.FilePath = to.Path() - } else { - bundle.FilePath = "???" - } - repo.CheckRules(&bundle) - } - } - } -} - -// scanCommit accepts a Commit hash, repo, and commit scanning function. A new Commit -// object will be created from the hash which will be passed into either scanCommitPatches -// or scanFilesAtCommit depending on the options set. -func scanCommit(commit string, repo *Repo, f commitScanner) error { - if commit == "latest" { - ref, err := repo.Repository.Head() - if err != nil { - return err - } - commit = ref.Hash().String() - } - repo.Manager.IncrementCommits(1) - h := plumbing.NewHash(commit) - c, err := repo.CommitObject(h) - if err != nil { - return err - } - return f(c, repo) -} - -// scanCommitPatches accepts a Commit object and a repo. This function is only called when the --Commit= -// option has been set. That option tells gitleaks to look only at a single Commit and check the contents -// of said Commit. Similar to scan(), if the files contained in the Commit are a binaries or if they are -// allowlisted then those files will be skipped. -func scanCommitPatches(c *object.Commit, repo *Repo) error { - if len(c.ParentHashes) == 0 { - err := scanFilesAtCommit(c, repo) - if err != nil { - return err - } - } - - return c.Parents().ForEach(func(parent *object.Commit) error { - defer func() { - if err := recover(); err != nil { - // sometimes the Patch generation will fail due to a known bug in - // sergi's go-diff: https://github.com/sergi/go-diff/issues/89. - // Once a fix has been merged I will remove this recover. - return - } - }() - if repo.timeoutReached() { - return nil - } - if parent == nil { - return nil - } - start := time.Now() - patch, err := parent.Patch(c) - if err != nil { - return fmt.Errorf("could not generate Patch") - } - repo.Manager.RecordTime(manager.PatchTime(howLong(start))) - - scanPatch(patch, c, repo) - - return nil - }) -} - -// scanFilesAtCommit accepts a Commit object and a repo. This function is only called when the --files-at-Commit= -// option has been set. That option tells gitleaks to look only at ALL the files at a Commit and check the contents -// of said Commit. Similar to scan(), if the files contained in the Commit are a binaries or if they are -// allowlisted then those files will be skipped. -func scanFilesAtCommit(c *object.Commit, repo *Repo) error { - fIter, err := c.Files() - if err != nil { - return err - } - - err = fIter.ForEach(func(f *object.File) error { - bin, err := f.IsBinary() - if bin || repo.timeoutReached() { - return nil - } else if err != nil { - return err - } - - content, err := f.Contents() - if err != nil { - return err - } - - repo.CheckRules(&Bundle{ - Content: content, - FilePath: f.Name, - Commit: c, - scanType: commitScan, - Operation: fdiff.Add, - }) - return nil - }) - return err -} - -// depthReached checks if i meets the depth (--depth=) if set -func (repo *Repo) depthReached(i int) bool { - if repo.Manager.Opts.Depth != 0 && repo.Manager.Opts.Depth == i { - log.Warnf("Exceeded depth limit (%d)", i) - return true - } - return false -} - -// emptyCommit generates an empty commit used for scanning uncommitted changes -func emptyCommit() *object.Commit { - return &object.Commit{ - Hash: plumbing.Hash{}, - Message: "***STAGED CHANGES***", - Author: object.Signature{ - Name: "", - Email: "", - When: time.Unix(0, 0).UTC(), - }, - } -} diff --git a/scan/scan_test.go b/scan/scan_test.go deleted file mode 100644 index 210c035fa..000000000 --- a/scan/scan_test.go +++ /dev/null @@ -1,628 +0,0 @@ -package scan - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "reflect" - "runtime" - "sort" - "testing" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/sergi/go-diff/diffmatchpatch" -) - -const testRepoBase = "../test_data/test_repos/" - -func TestScan(t *testing.T) { - moveDotGit("dotGit", ".git") - defer moveDotGit(".git", "dotGit") - tests := []struct { - description string - opts options.Options - wantPath string - wantErr error - emptyRepo bool - wantEmpty bool - }{ - { - description: "test local repo one aws leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test local repo one aws leak threaded", - opts: options.Options{ - Threads: runtime.GOMAXPROCS(0), - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test non existent repo", - opts: options.Options{ - RepoPath: "../test_data/test_repos/no_repo_here", - ReportFormat: "json", - }, - emptyRepo: true, - }, - { - description: "test local repo one aws leak allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - ReportFormat: "json", - Config: "../test_data/test_configs/aws_key_allowlist_python_files.toml", - }, - wantEmpty: true, - }, - { - description: "test local repo two leaks", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_two_leaks.json", - }, - { - description: "test local repo two leaks from Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_from.json.got", - ReportFormat: "json", - CommitFrom: "996865bb912f3bc45898a370a13aadb315014b55", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_from.json", - }, - { - description: "test local repo two leaks to Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_to.json.got", - ReportFormat: "json", - CommitTo: "996865bb912f3bc45898a370a13aadb315014b55", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_to.json", - }, - { - description: "test local repo two leaks to from Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_to_from.json.got", - ReportFormat: "json", - CommitFrom: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a", - CommitTo: "51f6dcf6b89b93f4075ba92c400b075631a6cc93", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_to_from.json", - }, - { - description: "test local repo two leaks list Commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_range.json.got", - ReportFormat: "json", - Commits: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a,996865bb912f3bc45898a370a13aadb315014b55,17471a5fda722a9e423f1a0d3f0d267ea009d41c,51f6dcf6b89b93f4075ba92c400b075631a6cc93,b10b3e2cb320a8c211fda94c4567299d37de7776", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_range.json", - }, - { - description: "test local repo two leaks file list commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_file_commit_range.json.got", - ReportFormat: "json", - CommitsFile: "../test_data/test_options/test_local_repo_commits.txt", - }, - wantPath: "../test_data/test_local_repo_two_leaks_file_commit_range.json", - }, - { - description: "test local repo two leaks globally allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Config: "../test_data/test_configs/aws_key_global_allowlist_file.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo two leaks allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Config: "../test_data/test_configs/aws_key_allowlist_files.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo three leaks dev branch", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_3", - Report: "../test_data/test_local_repo_three_leaks.json.got", - Config: "../test_data/test_configs/aws_key.toml", - Branch: "dev", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_three_leaks.json", - }, - { - description: "test local repo branch does not exist", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_3", - Branch: "nobranch", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak single Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_commit.json.got", - Commit: "6557c92612d3b35979bd426d429255b3bf9fab74", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_commit.json", - }, - { - description: "test local repo one aws leak AND leak on python files", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json.got", - Config: "../test_data/test_configs/aws_key_file_regex.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json", - }, - { - description: "test owner path", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_owner_aws_leak.json", - }, - { - description: "test owner path allowlist repo", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak_allowlist_repo.json.got", - ReportFormat: "json", - Config: "../test_data/test_configs/aws_key_local_owner_allowlist_repo.toml", - }, - wantPath: "../test_data/test_local_owner_aws_leak_allowlist_repo.json", - }, - { - description: "test entropy and regex", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_regex_entropy.json.got", - Config: "../test_data/test_configs/regex_entropy.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_regex_entropy.json", - }, - { - description: "test local repo four entropy alternative config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_4", - Report: "../test_data/test_local_repo_four_alt_config_entropy.json.got", - RepoConfig: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_four_alt_config_entropy.json", - }, - { - description: "test local repo four entropy alternative config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_regex_allowlist.json.got", - Config: "../test_data/test_configs/aws_key_aws_allowlisted.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak timeout", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - Timeout: "10ns", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak long timeout", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - Timeout: "2m", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test owner path depth=2", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak_depth_2.json.got", - ReportFormat: "json", - Depth: 2, - }, - wantPath: "../test_data/test_local_owner_aws_leak_depth_2.json", - }, - { - description: "test local repo five files at Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_files_at_commit.json.got", - FilesAtCommit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_five_files_at_commit.json", - }, - { - description: "test local repo five files at latest Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_files_at_latest_commit.json.got", - FilesAtCommit: "latest", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_five_files_at_commit.json", - }, - { - description: "test local repo five at Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_commit.json.got", - Commit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - ReportFormat: "json", - Config: "../test_data/test_configs/generic.toml", - }, - wantPath: "../test_data/test_local_repo_five_commit.json", - }, - { - description: "test local repo five at latest Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_at_latest_commit.json.got", - Commit: "latest", - ReportFormat: "json", - Config: "../test_data/test_configs/generic.toml", - }, - wantPath: "../test_data/test_local_repo_five_at_latest_commit.json", - }, - { - description: "test local repo six filename", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filename.json.got", - Config: "../test_data/test_configs/regex_filename.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filename.json", - }, - { - description: "test local repo six filepath", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filepath.json.got", - Config: "../test_data/test_configs/regex_filepath.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filepath.json", - }, - { - description: "test local repo six filename and filepath", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filepath_filename.json.got", - Config: "../test_data/test_configs/regex_filepath_filename.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filepath_filename.json", - }, - { - description: "test local repo six path globally allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_path_globally_allowlisted.json.got", - Config: "../test_data/test_configs/aws_key_global_allowlist_path.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_path_globally_allowlisted.json", - }, - { - description: "test local repo six leaks since date", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_leaks_since_date.json.got", - ReportFormat: "json", - CommitSince: "2019-10-25", - }, - wantPath: "../test_data/test_local_repo_six_leaks_since_date.json", - }, - { - description: "test local repo two leaks until date", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_leaks_until_date.json.got", - ReportFormat: "json", - CommitUntil: "2019-10-25", - }, - wantPath: "../test_data/test_local_repo_six_leaks_until_date.json", - }, - { - description: "test local repo four leaks timerange Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_4", - Report: "../test_data/test_local_repo_four_leaks_commit_timerange.json.got", - ReportFormat: "json", - CommitSince: "2019-10-25T13:01:27-0400", - CommitUntil: "2019-10-25T13:12:32-0400", - }, - wantPath: "../test_data/test_local_repo_four_leaks_commit_timerange.json", - }, - { - description: "test local repo two allowlist Commit config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_allowlist_commits.json.got", - Config: "../test_data/test_configs/allowlist_commit.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_two_allowlist_commits.json", - }, - { - description: "test local repo two deletion", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_deletion.json.got", - ReportFormat: "json", - Deletion: true, - }, - wantPath: "../test_data/test_local_repo_two_leaks_deletion.json", - }, - { - description: "test local repo eight (merges)", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_8", - Report: "../test_data/test_local_repo_eight.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_eight.json", - }, - { - description: "test local repo nine", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_9", - Report: "../test_data/test_local_repo_nine_aws_leak.json.got", - Config: "../test_data/test_configs/large_with_global_allowlist_regex.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_nine_aws_leak.json", - }, - } - - for _, test := range tests { - fmt.Println(test.description) - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - - err = Run(m) - - if test.wantErr != nil { - if err == nil { - t.Errorf("did not receive wantErr: %v", test.wantErr) - } - if err.Error() != test.wantErr.Error() { - t.Errorf("wantErr does not equal err received: %v", err.Error()) - } - continue - } - - err = m.Report() - if err != nil { - t.Error(err) - } - - if test.wantEmpty { - if len(m.GetLeaks()) != 0 { - t.Errorf("wanted no leaks but got some instead: %+v", m.GetLeaks()) - } - continue - } - - if test.wantPath != "" { - err := fileCheck(test.wantPath, test.opts.Report) - if err != nil { - t.Error(err) - } - } - } -} - -func TestScanUncommited(t *testing.T) { - moveDotGit("dotGit", ".git") - defer moveDotGit(".git", "dotGit") - tests := []struct { - description string - opts options.Options - wantPath string - wantErr error - emptyRepo bool - wantEmpty bool - fileToChange string - addition string - }{ - { - description: "test scan local one leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_uncommitted.json.got", - Uncommited: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_uncommitted.json", - fileToChange: "server.test.py", - addition: " aws_access_key_id='AKIAIO5FODNN7DXAMPLE'\n\n", - }, - { - description: "test scan local no leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Uncommited: true, - ReportFormat: "json", - }, - wantEmpty: true, - fileToChange: "server.test.py", - addition: "nothing bad", - }, - { - description: "test scan repo with no commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_7", - Report: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json.got", - Uncommited: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json", - }, - } - for _, test := range tests { - var ( - old []byte - err error - ) - fmt.Println(test.description) - if test.fileToChange != "" { - old, err = ioutil.ReadFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange)) - if err != nil { - t.Error(err) - } - altered, err := os.OpenFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange), - os.O_WRONLY|os.O_APPEND, 0644) - if err != nil { - t.Error(err) - } - - _, err = altered.WriteString(test.addition) - if err != nil { - t.Error(err) - } - - } - - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - - if err := Run(m); err != nil { - t.Error(err) - } - - if err := m.Report(); err != nil { - t.Error(err) - } - - if test.fileToChange != "" { - err = ioutil.WriteFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange), old, 0) - if err != nil { - t.Error(err) - } - } - - if test.wantEmpty { - continue - } - - if test.wantPath != "" { - err := fileCheck(test.wantPath, test.opts.Report) - if err != nil { - t.Error(err) - } - } - } -} - -func fileCheck(wantPath, gotPath string) error { - var ( - gotLeaks []manager.Leak - wantLeaks []manager.Leak - ) - want, err := ioutil.ReadFile(wantPath) - if err != nil { - return err - } - - got, err := ioutil.ReadFile(gotPath) - if err != nil { - return err - } - - err = json.Unmarshal(got, &gotLeaks) - if err != nil { - return err - } - - err = json.Unmarshal(want, &wantLeaks) - if err != nil { - return nil - } - - sort.Slice(gotLeaks, func(i, j int) bool { return (gotLeaks)[i].Commit < (gotLeaks)[j].Commit }) - sort.Slice(wantLeaks, func(i, j int) bool { return (wantLeaks)[i].Commit < (wantLeaks)[j].Commit }) - - if !reflect.DeepEqual(gotLeaks, wantLeaks) { - dmp := diffmatchpatch.New() - diffs := dmp.DiffMain(string(want), string(got), false) - return fmt.Errorf("%s does not equal %s: %s", wantPath, gotPath, dmp.DiffPrettyText(diffs)) - } - if err := os.Remove(gotPath); err != nil { - return err - } - return nil -} - -func moveDotGit(from, to string) error { - repoDirs, err := ioutil.ReadDir("../test_data/test_repos") - if err != nil { - return err - } - for _, dir := range repoDirs { - if !dir.IsDir() { - continue - } - err = os.Rename(fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), from), - fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), to)) - if err != nil { - return err - } - } - return nil -} diff --git a/scripts/pre-commit.py b/scripts/pre-commit.py new file mode 100644 index 000000000..64d48d595 --- /dev/null +++ b/scripts/pre-commit.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +"""Helper script to be used as a pre-commit hook.""" +import os +import sys +import subprocess + + +def gitleaksEnabled(): + """Determine if the pre-commit hook for gitleaks is enabled.""" + out = subprocess.getoutput("git config --bool hooks.gitleaks") + if out == "false": + return False + return True + + +if gitleaksEnabled(): + exitCode = os.WEXITSTATUS(os.system('gitleaks protect -v --staged')) + if exitCode == 1: + print('''Warning: gitleaks has detected sensitive information in your changes. +To disable the gitleaks precommit hook run the following command: + + git config hooks.gitleaks false +''') + sys.exit(1) +else: + print('gitleaks precommit disabled\ + (enable with `git config hooks.gitleaks true`)') diff --git a/test_data/test_configs/allowlist_commit.toml b/test_data/test_configs/allowlist_commit.toml deleted file mode 100644 index 9ee75ea2e..000000000 --- a/test_data/test_configs/allowlist_commit.toml +++ /dev/null @@ -1,13 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - - -[allowlist] - commits = [ - "b10b3e2cb320a8c211fda94c4567299d37de7776", - "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "996865bb912f3bc45898a370a13aadb315014b55" - ] - diff --git a/test_data/test_configs/aws_key.toml b/test_data/test_configs/aws_key.toml deleted file mode 100644 index a781099bc..000000000 --- a/test_data/test_configs/aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/aws_key_allowlist_files.toml b/test_data/test_configs/aws_key_allowlist_files.toml deleted file mode 100644 index 5dc6608e4..000000000 --- a/test_data/test_configs/aws_key_allowlist_files.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore sample regex md files" - files = ['''(.*)?md$'''] - regexes = ['''ignore$'''] diff --git a/test_data/test_configs/aws_key_allowlist_python_files.toml b/test_data/test_configs/aws_key_allowlist_python_files.toml deleted file mode 100644 index c33012029..000000000 --- a/test_data/test_configs/aws_key_allowlist_python_files.toml +++ /dev/null @@ -1,7 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore python files" - files = ['''(.*)?py$'''] diff --git a/test_data/test_configs/aws_key_aws_allowlisted.toml b/test_data/test_configs/aws_key_aws_allowlisted.toml deleted file mode 100644 index e8d7cf6d7..000000000 --- a/test_data/test_configs/aws_key_aws_allowlisted.toml +++ /dev/null @@ -1,7 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore aws key" - regexes = ['''AKIAIO5FODNN7EXAMPLE.*'''] diff --git a/test_data/test_configs/aws_key_file_regex.toml b/test_data/test_configs/aws_key_file_regex.toml deleted file mode 100644 index 5af8aa2ea..000000000 --- a/test_data/test_configs/aws_key_file_regex.toml +++ /dev/null @@ -1,14 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -## this is an example of a rule that won't work -[[rules]] - description = "Python files" - fileRegex = "(?i)*.py" diff --git a/test_data/test_configs/aws_key_global_allowlist_file.toml b/test_data/test_configs/aws_key_global_allowlist_file.toml deleted file mode 100644 index 35f7b65d6..000000000 --- a/test_data/test_configs/aws_key_global_allowlist_file.toml +++ /dev/null @@ -1,10 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[allowlist] - description = "ignore md files" - files = [ - '''(.*)?md$''' - ] \ No newline at end of file diff --git a/test_data/test_configs/aws_key_global_allowlist_path.toml b/test_data/test_configs/aws_key_global_allowlist_path.toml deleted file mode 100644 index 9b2fd0877..000000000 --- a/test_data/test_configs/aws_key_global_allowlist_path.toml +++ /dev/null @@ -1,10 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[allowlist] - description = "ignore config folders" - paths = [ - '''config(uration)?''' - ] \ No newline at end of file diff --git a/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml b/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml deleted file mode 100644 index 93877130f..000000000 --- a/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [allowlist] - description = "allowlist repo" - repos = [ - '''test_repo_1''' - ] diff --git a/test_data/test_configs/bad_aws_key.toml b/test_data/test_configs/bad_aws_key.toml deleted file mode 100644 index 15d691cc9..000000000 --- a/test_data/test_configs/bad_aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/bad_aws_key_file_regex.toml b/test_data/test_configs/bad_aws_key_file_regex.toml deleted file mode 100644 index 624d1a71b..000000000 --- a/test_data/test_configs/bad_aws_key_file_regex.toml +++ /dev/null @@ -1,13 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[Global] - file = '''?????????????''' - diff --git a/test_data/test_configs/bad_entropy_1.toml b/test_data/test_configs/bad_entropy_1.toml deleted file mode 100644 index 36aba7cb8..000000000 --- a/test_data/test_configs/bad_entropy_1.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "4.1" - diff --git a/test_data/test_configs/bad_entropy_2.toml b/test_data/test_configs/bad_entropy_2.toml deleted file mode 100644 index adae692da..000000000 --- a/test_data/test_configs/bad_entropy_2.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "x" - diff --git a/test_data/test_configs/bad_entropy_3.toml b/test_data/test_configs/bad_entropy_3.toml deleted file mode 100644 index e063ec52e..000000000 --- a/test_data/test_configs/bad_entropy_3.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "x" - Max = "4.1" - diff --git a/test_data/test_configs/bad_entropy_4.toml b/test_data/test_configs/bad_entropy_4.toml deleted file mode 100644 index 2b8e189d8..000000000 --- a/test_data/test_configs/bad_entropy_4.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8" - Group = "x" - diff --git a/test_data/test_configs/bad_entropy_5.toml b/test_data/test_configs/bad_entropy_5.toml deleted file mode 100644 index 6e99b792f..000000000 --- a/test_data/test_configs/bad_entropy_5.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "-2" - diff --git a/test_data/test_configs/bad_entropy_6.toml b/test_data/test_configs/bad_entropy_6.toml deleted file mode 100644 index b6601fc70..000000000 --- a/test_data/test_configs/bad_entropy_6.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "2" - diff --git a/test_data/test_configs/bad_entropy_7.toml b/test_data/test_configs/bad_entropy_7.toml deleted file mode 100644 index ff72eccba..000000000 --- a/test_data/test_configs/bad_entropy_7.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "0" - diff --git a/test_data/test_configs/bad_regex_aws_key.toml b/test_data/test_configs/bad_regex_aws_key.toml deleted file mode 100644 index 47ebe941a..000000000 --- a/test_data/test_configs/bad_regex_aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''$$$???$$$??$?$?$''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/entropy.toml b/test_data/test_configs/entropy.toml deleted file mode 100644 index f3b4ffdbf..000000000 --- a/test_data/test_configs/entropy.toml +++ /dev/null @@ -1,11 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{40,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "4.7" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" - diff --git a/test_data/test_configs/generic.toml b/test_data/test_configs/generic.toml deleted file mode 100644 index 22884cd94..000000000 --- a/test_data/test_configs/generic.toml +++ /dev/null @@ -1,4 +0,0 @@ -[[rules]] - description = "Generic Credential" - regex = '''(?i)(api_key|apikey|secret|password|pass|pw|key)(.{0,20})?[0-9a-zA-Z]{16,45}''' - tags = ["key", "API", "generic"] \ No newline at end of file diff --git a/test_data/test_configs/large.toml b/test_data/test_configs/large.toml deleted file mode 100644 index 78c3a50ca..000000000 --- a/test_data/test_configs/large.toml +++ /dev/null @@ -1,148 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - -[[rules]] - description = "Generic API key" - regex = '''(?i)(api_key|apikey)(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Generic Secret" - regex = '''(?i)secret(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "Secret", "generic"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore common jenkins functions" - regexes = [ - '''allowlistme''' - ] - files = [ - '''(.*)?Jenkinsfile$''' - ] - -# Global rules. This instructs gitleaks to ignore all .pem files or if a message with -[[rules]] - description = "Files with keys and credentials" - file = '''(.*?)(pem)''' - -[allowlist] - description = "File allowlists" - files = [ - '''(.*?)(jpg|gif)$''', - '''(.*?)(doc|pdf|bin)$''' - ] - diff --git a/test_data/test_configs/large_with_global_allowlist_regex.toml b/test_data/test_configs/large_with_global_allowlist_regex.toml deleted file mode 100644 index 1d63f47da..000000000 --- a/test_data/test_configs/large_with_global_allowlist_regex.toml +++ /dev/null @@ -1,151 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - -[[rules]] - description = "Generic API key" - regex = '''(?i)(api_key|apikey)(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Generic Secret" - regex = '''(?i)secret(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "Secret", "generic"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore common jenkins functions" - regexes = [ - '''allowlistme''' - ] - files = [ - '''(.*)?Jenkinsfile$''' - ] - -[[rules]] - description = "Files with keys and credentials" - file = '''(.*?)(pem)''' - -# Global allowlist -[allowlist] - description = "global allowlists" - files = [ - '''(.*?)(jpg|gif)$''', - '''(.*?)(doc|pdf|bin)$''' - ] - regexes = [ - '''(.*?)gitleaks:allow''' - ] - diff --git a/test_data/test_configs/regex_entropy.toml b/test_data/test_configs/regex_entropy.toml deleted file mode 100644 index 2cac46ee1..000000000 --- a/test_data/test_configs/regex_entropy.toml +++ /dev/null @@ -1,14 +0,0 @@ -[[rules]] - description = "entropy and regex" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "4.7" - Group = "1" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" - Group = "1" - - diff --git a/test_data/test_configs/regex_filename.toml b/test_data/test_configs/regex_filename.toml deleted file mode 100644 index a9b9cd2f8..000000000 --- a/test_data/test_configs/regex_filename.toml +++ /dev/null @@ -1,6 +0,0 @@ - -[[rules]] - description = "Generic password" - regex = '''(?i)(password|token).{0,20}?\s*[:|=]\s*?(?-i)([0-9a-zA-Z\/+]{4,40})''' - file = '''.*\.ya?ml''' - tags = ["key", "Yml", "Yaml"] diff --git a/test_data/test_configs/regex_filepath.toml b/test_data/test_configs/regex_filepath.toml deleted file mode 100644 index 0d5ce04e5..000000000 --- a/test_data/test_configs/regex_filepath.toml +++ /dev/null @@ -1,6 +0,0 @@ - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - path = '''config(guration)?''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/regex_filepath_filename.toml b/test_data/test_configs/regex_filepath_filename.toml deleted file mode 100644 index d4ab0bbd8..000000000 --- a/test_data/test_configs/regex_filepath_filename.toml +++ /dev/null @@ -1,7 +0,0 @@ - -[[rules]] - description = "Generic password" - regex = '''(?i)(password|token).{0,20}?\s*[:|=]\s*?(?-i)([0-9a-zA-Z\/+]{4,40})''' - file = '''.*\.properties''' - path = '''config(guration)?''' - tags = ["key", "Yml", "Yaml"] diff --git a/test_data/test_entropy.json b/test_data/test_entropy.json deleted file mode 100644 index 4c418cbd4..000000000 --- a/test_data/test_entropy.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "offender": "Entropy range [{P1:4.5 P2:4.7} {P1:5.5 P2:6.3}]", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "entropy", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "entropy" - } -] diff --git a/test_data/test_local_owner_aws_leak.json b/test_data/test_local_owner_aws_leak.json deleted file mode 100644 index e5fbaf14a..000000000 --- a/test_data/test_local_owner_aws_leak.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "1f2a4abc47dabf991e6af6f9770867ce0ac1f360", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:07:34-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_owner_aws_leak_allowlist_repo.json b/test_data/test_local_owner_aws_leak_allowlist_repo.json deleted file mode 100644 index 112f031f0..000000000 --- a/test_data/test_local_owner_aws_leak_allowlist_repo.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "1f2a4abc47dabf991e6af6f9770867ce0ac1f360", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:07:34-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_owner_aws_leak_depth_2.json b/test_data/test_local_owner_aws_leak_depth_2.json deleted file mode 100644 index 42be9a684..000000000 --- a/test_data/test_local_owner_aws_leak_depth_2.json +++ /dev/null @@ -1,107 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_eight.json b/test_data/test_local_repo_eight.json deleted file mode 100644 index 66673c606..000000000 --- a/test_data/test_local_repo_eight.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_at_latest_commit.json b/test_data/test_local_repo_five_at_latest_commit.json deleted file mode 100644 index ce5cf8b33..000000000 --- a/test_data/test_local_repo_five_at_latest_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "more_secrets = '99432bfewaf823ec3294e231'", - "lineNumber": 7, - "offender": "secrets = '99432bfewaf823ec3294e231", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "Generic Credential", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, API, generic", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_commit.json b/test_data/test_local_repo_five_commit.json deleted file mode 100644 index ce5cf8b33..000000000 --- a/test_data/test_local_repo_five_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "more_secrets = '99432bfewaf823ec3294e231'", - "lineNumber": 7, - "offender": "secrets = '99432bfewaf823ec3294e231", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "Generic Credential", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, API, generic", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_files_at_commit.json b/test_data/test_local_repo_five_files_at_commit.json deleted file mode 100644 index 16168a820..000000000 --- a/test_data/test_local_repo_five_files_at_commit.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_files_at_latest_commit.json b/test_data/test_local_repo_five_files_at_latest_commit.json deleted file mode 100644 index 16168a820..000000000 --- a/test_data/test_local_repo_five_files_at_latest_commit.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_four_alt_config_entropy.json b/test_data/test_local_repo_four_alt_config_entropy.json deleted file mode 100644 index 6fe84f27d..000000000 --- a/test_data/test_local_repo_four_alt_config_entropy.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "const AWSSECRET = \"99432bfewaf823ec3294e231\"", - "lineNumber": 5, - "offender": "\"99432bfewaf823ec3294e231\"", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_4", - "rule": "entropy", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "entropy", - "operation": "addition" - }, - { - "line": " const AWSSECRET = \"99432bfewaf823ec3294e231\"", - "lineNumber": 6, - "offender": "\"99432bfewaf823ec3294e231\"", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_4", - "rule": "entropy", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "entropy", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_four_leaks_commit_timerange.json b/test_data/test_local_repo_four_leaks_commit_timerange.json deleted file mode 100644 index e7fac1c55..000000000 --- a/test_data/test_local_repo_four_leaks_commit_timerange.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_4", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_4", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_nine_aws_leak.json b/test_data/test_local_repo_nine_aws_leak.json deleted file mode 100644 index ab418b8d9..000000000 --- a/test_data/test_local_repo_nine_aws_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak.json b/test_data/test_local_repo_one_aws_leak.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_and_file_leak.json b/test_data/test_local_repo_one_aws_leak_and_file_leak.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak_and_file_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_commit.json b/test_data/test_local_repo_one_aws_leak_commit.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_uncommitted.json b/test_data/test_local_repo_one_aws_leak_uncommitted.json deleted file mode 100644 index 620df24aa..000000000 --- a/test_data/test_local_repo_one_aws_leak_uncommitted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7DXAMPLE'", - "lineNumber": 10, - "offender": "AKIAIO5FODNN7DXAMPLE", - "commit": "0000000000000000000000000000000000000000", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "***STAGED CHANGES***", - "author": "", - "email": "", - "file": "server.test.py", - "date": "1970-01-01T00:00:00Z", - "tags": "key, AWS", - "operation": "equal" - } -] diff --git a/test_data/test_local_repo_seven_aws_leak_uncommitted.json b/test_data/test_local_repo_seven_aws_leak_uncommitted.json deleted file mode 100644 index b7d1965f7..000000000 --- a/test_data/test_local_repo_seven_aws_leak_uncommitted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "AKIAIO5FODNN7EXAMPLE", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "0000000000000000000000000000000000000000", - "repo": "test_repo_7", - "rule": "AWS Manager ID", - "commitMessage": "***STAGED CHANGES***", - "author": "", - "email": "", - "file": "file", - "date": "1970-01-01T00:00:00Z", - "tags": "key, AWS", - "operation": "equal" - } -] diff --git a/test_data/test_local_repo_six.json b/test_data/test_local_repo_six.json deleted file mode 100644 index 8c0cf9d72..000000000 --- a/test_data/test_local_repo_six.json +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "line": "api_token: exampleSecretPassword", - "lineNumber": 3, - "offender": "token: exampleSecretPassword", - "commit": "e7bf376f855ae9bc6e3bb27b5f9d65c57eba799d", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "More secrets\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/config.yaml", - "date": "2020-02-19T04:08:26-05:00", - "tags": "key, Yml, Yaml" - }, - { - "line": "db_password_token: exampleSecretPassword", - "lineNumber": 3, - "offender": "password_token: exampleSecretPassword", - "commit": "e7bf376f855ae9bc6e3bb27b5f9d65c57eba799d", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "More secrets\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/config.yaml", - "date": "2020-02-19T04:08:26-05:00", - "tags": "key, Yml, Yaml" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "95cf0237f8cdfc0686a29df08260d8635f46c9b0", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "AWS Key in properties\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-19T04:04:15-05:00", - "tags": "key, AWS" - } -] diff --git a/test_data/test_local_repo_six_filename.json b/test_data/test_local_repo_six_filename.json deleted file mode 100644 index 00f633ada..000000000 --- a/test_data/test_local_repo_six_filename.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "api_token: exampleSecretPassword", - "lineNumber": 2, - "offender": "token: exampleSecretPassword", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "application.yaml", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - }, - { - "line": "db_password: verySecretProductionPassword", - "lineNumber": 3, - "offender": "password: verySecretProductionPassword", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "application.yaml", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_filepath.json b/test_data/test_local_repo_six_filepath.json deleted file mode 100644 index 31ffd8857..000000000 --- a/test_data/test_local_repo_six_filepath.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_filepath_filename.json b/test_data/test_local_repo_six_filepath_filename.json deleted file mode 100644 index 242da22c1..000000000 --- a/test_data/test_local_repo_six_filepath_filename.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "apiToken=d41d8cd98f00b204e9800998ecf8427e", - "lineNumber": 2, - "offender": "Token=d41d8cd98f00b204e9800998ecf8427e", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_leaks_since_date.json b/test_data/test_local_repo_six_leaks_since_date.json deleted file mode 100644 index 31ffd8857..000000000 --- a/test_data/test_local_repo_six_leaks_since_date.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_leaks_until_date.json b/test_data/test_local_repo_six_leaks_until_date.json deleted file mode 100644 index 9cd7bc61f..000000000 --- a/test_data/test_local_repo_six_leaks_until_date.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_path_globally_allowlisted.json b/test_data/test_local_repo_six_path_globally_allowlisted.json deleted file mode 100644 index 9cd7bc61f..000000000 --- a/test_data/test_local_repo_six_path_globally_allowlisted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_three_leaks.json b/test_data/test_local_repo_three_leaks.json deleted file mode 100644 index 745242b8a..000000000 --- a/test_data/test_local_repo_three_leaks.json +++ /dev/null @@ -1,62 +0,0 @@ -[ - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_allowlist_commits.json b/test_data/test_local_repo_two_allowlist_commits.json deleted file mode 100644 index 9e315f6d0..000000000 --- a/test_data/test_local_repo_two_allowlist_commits.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks.json b/test_data/test_local_repo_two_leaks.json deleted file mode 100644 index 39eedddeb..000000000 --- a/test_data/test_local_repo_two_leaks.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_from.json b/test_data/test_local_repo_two_leaks_commit_from.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_commit_from.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_range.json b/test_data/test_local_repo_two_leaks_commit_range.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_commit_range.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_to.json b/test_data/test_local_repo_two_leaks_commit_to.json deleted file mode 100644 index 9e315f6d0..000000000 --- a/test_data/test_local_repo_two_leaks_commit_to.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_to_from.json b/test_data/test_local_repo_two_leaks_commit_to_from.json deleted file mode 100644 index aa4e907d9..000000000 --- a/test_data/test_local_repo_two_leaks_commit_to_from.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_deletion.json b/test_data/test_local_repo_two_leaks_deletion.json deleted file mode 100644 index 57b396e4d..000000000 --- a/test_data/test_local_repo_two_leaks_deletion.json +++ /dev/null @@ -1,92 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIB", - "commit": "f61cd8587b7ac1d75a89a0c9af870a2f24c60263", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "rm secrets again\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:32-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIA", - "commit": "996865bb912f3bc45898a370a13aadb315014b55", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "committing pem\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:07:41-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_file_commit_range.json b/test_data/test_local_repo_two_leaks_file_commit_range.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_file_commit_range.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_options/test_local_repo_commits.txt b/test_data/test_options/test_local_repo_commits.txt deleted file mode 100644 index b3b16ca01..000000000 --- a/test_data/test_options/test_local_repo_commits.txt +++ /dev/null @@ -1,5 +0,0 @@ -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a -996865bb912f3bc45898a370a13aadb315014b55 -17471a5fda722a9e423f1a0d3f0d267ea009d41c -51f6dcf6b89b93f4075ba92c400b075631a6cc93 -b10b3e2cb320a8c211fda94c4567299d37de7776 diff --git a/test_data/test_regex_entropy.json b/test_data/test_regex_entropy.json deleted file mode 100644 index 8f20b73b4..000000000 --- a/test_data/test_regex_entropy.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE'", - "lineNumber": 6, - "offender": "'ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE'", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "entropy and regex", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "entropy", - "operation": "addition" - } -] diff --git a/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 60c9e47f1..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -comment diff --git a/test_data/test_repos/test_repo_1/dotGit/HEAD b/test_data/test_repos/test_repo_1/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_1/dotGit/config b/test_data/test_repos/test_repo_1/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_1/dotGit/index b/test_data/test_repos/test_repo_1/dotGit/index deleted file mode 100644 index 3a76f3781..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/index and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/logs/HEAD b/test_data/test_repos/test_repo_1/dotGit/logs/HEAD deleted file mode 100644 index cb19a50e8..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/logs/HEAD +++ /dev/null @@ -1,2 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment diff --git a/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master deleted file mode 100644 index cb19a50e8..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,2 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d4..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 b/test_data/test_repos/test_repo_1/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 deleted file mode 100644 index eb42e8687..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee5333..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 b/test_data/test_repos/test_repo_1/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 deleted file mode 100644 index 0d57232e8..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d6946..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c b/test_data/test_repos/test_repo_1/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c deleted file mode 100644 index 86d326ddc..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 b/test_data/test_repos/test_repo_1/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 deleted file mode 100644 index 62de872c7..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 +++ /dev/null @@ -1 +0,0 @@ -x-j0;)< SJB@A ۿlI_Y쑃޳S)|nѶYoe&SWǭ5r:EVfC _Y .Zu\\Tz"GdQօW*)f<=ƂD%ˣYSC \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 b/test_data/test_repos/test_repo_1/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 deleted file mode 100644 index cafdfdb17..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ce..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab b/test_data/test_repos/test_repo_1/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab deleted file mode 100644 index 692983a56..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab +++ /dev/null @@ -1,2 +0,0 @@ -x -1 SMf+"JXY O^00FB\=k`%!9J0̎轐\5 ;x%T4r:}*A ֳH۾TؖԒ~g7xdr}l3.E EܸLمǖT%P\ ~P7oq,\ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 b/test_data/test_repos/test_repo_1/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 deleted file mode 100644 index 142e1a6d5..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077b..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4..000000000 Binary files a/test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 and /dev/null differ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAH 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again diff --git a/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master deleted file mode 100644 index 95800b46f..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,8 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc b/test_data/test_repos/test_repo_2/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc deleted file mode 100644 index df43f2604..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e15..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c b/test_data/test_repos/test_repo_2/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c deleted file mode 100644 index 915763a28..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 b/test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 deleted file mode 100644 index b211c238f..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e18..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafa..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 b/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 deleted file mode 100644 index 4258020ff..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 +++ /dev/null @@ -1,3 +0,0 @@ -xA -1 E]Ҥf -"^%M#8Su{zv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e b/test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e deleted file mode 100644 index f1090fb35..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 b/test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 deleted file mode 100644 index d93d42c3b..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c b/test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c deleted file mode 100644 index 1fe46e522..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e b/test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e deleted file mode 100644 index d94489820..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 b/test_data/test_repos/test_repo_2/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 deleted file mode 100644 index 312b2c1d5..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f93275..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e b/test_data/test_repos/test_repo_2/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e deleted file mode 100644 index f9dc2d4b2..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f1..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba b/test_data/test_repos/test_repo_2/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba deleted file mode 100644 index 41025422d..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 b/test_data/test_repos/test_repo_2/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 deleted file mode 100644 index 5e07a2040..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 b/test_data/test_repos/test_repo_2/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 deleted file mode 100644 index bd76a1d59..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f4420..000000000 Binary files a/test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 and /dev/null differ diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 b/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 deleted file mode 100644 index fac916106..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 +++ /dev/null @@ -1,2 +0,0 @@ -xA - Es5JUƙI1^xS-e`sM<{:!I&J.GQ6Y;d+yp8J1);DL>Rd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/refs/heads/master b/test_data/test_repos/test_repo_2/dotGit/refs/heads/master deleted file mode 100644 index 605b789d6..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 diff --git a/test_data/test_repos/test_repo_2/no_secrets.md b/test_data/test_repos/test_repo_2/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_2/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_2/secrets.md b/test_data/test_repos/test_repo_2/secrets.md deleted file mode 100644 index 8cb188824..000000000 --- a/test_data/test_repos/test_repo_2/secrets.md +++ /dev/null @@ -1,3 +0,0 @@ -### This file contains some secrets - -again, no more diff --git a/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 5f0f3ea61..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/HEAD b/test_data/test_repos/test_repo_3/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_3/dotGit/config b/test_data/test_repos/test_repo_3/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_3/dotGit/description b/test_data/test_repos/test_repo_3/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_3/dotGit/index b/test_data/test_repos/test_repo_3/dotGit/index deleted file mode 100644 index f00886b57..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/index and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/info/exclude b/test_data/test_repos/test_repo_3/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_3/dotGit/logs/HEAD b/test_data/test_repos/test_repo_3/dotGit/logs/HEAD deleted file mode 100644 index 33abb9ce9..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/logs/HEAD +++ /dev/null @@ -1,14 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 checkout: moving from master to dev -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets -64cfcee9aad1c84581631636bfc54f2050718d1a f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024992 -0400 checkout: moving from dev to master -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev b/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev deleted file mode 100644 index b6e041366..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 branch: Created from HEAD -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master deleted file mode 100644 index 4ee29a707..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,10 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc b/test_data/test_repos/test_repo_3/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc deleted file mode 100644 index df43f2604..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e15..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c b/test_data/test_repos/test_repo_3/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c deleted file mode 100644 index 915763a28..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e b/test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e deleted file mode 100644 index 03bf1d87b..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 b/test_data/test_repos/test_repo_3/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 deleted file mode 100644 index b211c238f..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e18..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafa..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb b/test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb deleted file mode 100644 index 6efcf07da..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d b/test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d deleted file mode 100644 index 15e9e9276..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 b/test_data/test_repos/test_repo_3/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 deleted file mode 100644 index 4258020ff..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 +++ /dev/null @@ -1,3 +0,0 @@ -xA -1 E]Ҥf -"^%M#8Su{zv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e b/test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e deleted file mode 100644 index f1090fb35..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 b/test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 deleted file mode 100644 index d93d42c3b..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c b/test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c deleted file mode 100644 index 1fe46e522..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a b/test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a deleted file mode 100644 index 261fe7f66..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 b/test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 deleted file mode 100644 index 78d82a50d..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e b/test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e deleted file mode 100644 index d94489820..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/82/4b8a2b468fcfa244e096bd54b83508b85ef488 b/test_data/test_repos/test_repo_3/dotGit/objects/82/4b8a2b468fcfa244e096bd54b83508b85ef488 deleted file mode 100644 index 24e40b2ed..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/82/4b8a2b468fcfa244e096bd54b83508b85ef488 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 b/test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 deleted file mode 100644 index d5dd750a5..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 b/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 deleted file mode 100644 index 3d207fd18..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 +++ /dev/null @@ -1,3 +0,0 @@ -xQ -0PsYl -"^e҂1Oo~0`v Cofq^ty<@U=٣ÜN9fYO%cQh )REh\hg>rv!b+l>G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 b/test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 deleted file mode 100644 index 312b2c1d5..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f93275..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e b/test_data/test_repos/test_repo_3/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e deleted file mode 100644 index f9dc2d4b2..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 b/test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 deleted file mode 100644 index f3a3ba397..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f1..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba b/test_data/test_repos/test_repo_3/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba deleted file mode 100644 index 41025422d..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 b/test_data/test_repos/test_repo_3/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 deleted file mode 100644 index ff582f60d..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 b/test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 deleted file mode 100644 index 5e07a2040..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 b/test_data/test_repos/test_repo_3/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 deleted file mode 100644 index bd76a1d59..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 b/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 deleted file mode 100644 index 1533a3b46..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 +++ /dev/null @@ -1,3 +0,0 @@ -x] -0})JDJ҂i6+401j]; Kf09}4Q(3kletXԞ$2t1%Hх b>hsw>}igd% yzjZ7j wQU -p?G| \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 b/test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 deleted file mode 100644 index 7ed4768c5..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f4420..000000000 Binary files a/test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 and /dev/null differ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 b/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 deleted file mode 100644 index fac916106..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 +++ /dev/null @@ -1,2 +0,0 @@ -xA - Es5JUƙI1^xS-e`sM<{:!I&J.GQ6Y;d+yp8J1);DL>Rd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev b/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev deleted file mode 100644 index 986aea9ec..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev +++ /dev/null @@ -1 +0,0 @@ -64cfcee9aad1c84581631636bfc54f2050718d1a diff --git a/test_data/test_repos/test_repo_3/dotGit/refs/heads/master b/test_data/test_repos/test_repo_3/dotGit/refs/heads/master deleted file mode 100644 index 95078805f..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 diff --git a/test_data/test_repos/test_repo_3/no_secrets.md b/test_data/test_repos/test_repo_3/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_3/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_3/secrets.md b/test_data/test_repos/test_repo_3/secrets.md deleted file mode 100644 index 83c50b16f..000000000 --- a/test_data/test_repos/test_repo_3/secrets.md +++ /dev/null @@ -1,2 +0,0 @@ -### This file contains some secrets - diff --git a/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 0f22e864d..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/HEAD b/test_data/test_repos/test_repo_4/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_4/dotGit/config b/test_data/test_repos/test_repo_4/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_4/dotGit/description b/test_data/test_repos/test_repo_4/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_4/dotGit/index b/test_data/test_repos/test_repo_4/dotGit/index deleted file mode 100644 index 94eec663c..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/index and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/info/exclude b/test_data/test_repos/test_repo_4/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/HEAD b/test_data/test_repos/test_repo_4/dotGit/logs/HEAD deleted file mode 100644 index 99399d233..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/HEAD +++ /dev/null @@ -1,18 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 checkout: moving from master to dev -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets -64cfcee9aad1c84581631636bfc54f2050718d1a f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024992 -0400 checkout: moving from dev to master -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 828595723b76e4a35b5253d9f2ccb4f897f1845a zach rice 1573429084 -0500 commit: adding repo config -828595723b76e4a35b5253d9f2ccb4f897f1845a ce835da266b3f8c34e4b7f398693ed068f67cb30 zach rice 1573431270 -0500 commit: epstein didnt kill himself -ce835da266b3f8c34e4b7f398693ed068f67cb30 5accbc40c35906d99f073881fb8746c314f9d59f zach rice 1573431335 -0500 commit: removing a really important link -5accbc40c35906d99f073881fb8746c314f9d59f 7b2eba252004b7c867413def2a0984d545daab8b zach rice 1573431386 -0500 commit: gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev b/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev deleted file mode 100644 index b6e041366..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 branch: Created from HEAD -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master deleted file mode 100644 index 6daf2b8ca..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,14 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 828595723b76e4a35b5253d9f2ccb4f897f1845a zach rice 1573429084 -0500 commit: adding repo config -828595723b76e4a35b5253d9f2ccb4f897f1845a ce835da266b3f8c34e4b7f398693ed068f67cb30 zach rice 1573431270 -0500 commit: epstein didnt kill himself -ce835da266b3f8c34e4b7f398693ed068f67cb30 5accbc40c35906d99f073881fb8746c314f9d59f zach rice 1573431335 -0500 commit: removing a really important link -5accbc40c35906d99f073881fb8746c314f9d59f 7b2eba252004b7c867413def2a0984d545daab8b zach rice 1573431386 -0500 commit: gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc b/test_data/test_repos/test_repo_4/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc deleted file mode 100644 index df43f2604..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e15..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c b/test_data/test_repos/test_repo_4/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c deleted file mode 100644 index 915763a28..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c b/test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c deleted file mode 100644 index 46ccb0d09..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e b/test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e deleted file mode 100644 index 03bf1d87b..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 b/test_data/test_repos/test_repo_4/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 deleted file mode 100644 index b211c238f..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e18..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 b/test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 deleted file mode 100644 index 14a0321b1..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafa..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb b/test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb deleted file mode 100644 index 6efcf07da..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d b/test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d deleted file mode 100644 index 15e9e9276..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/4b/c47c2d3aaa25385e3354ea34136456c2260a12 b/test_data/test_repos/test_repo_4/dotGit/objects/4b/c47c2d3aaa25385e3354ea34136456c2260a12 deleted file mode 100644 index d60091180..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/4b/c47c2d3aaa25385e3354ea34136456c2260a12 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 b/test_data/test_repos/test_repo_4/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 deleted file mode 100644 index 4258020ff..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 +++ /dev/null @@ -1,3 +0,0 @@ -xA -1 E]Ҥf -"^%M#8Su{zv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f b/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f deleted file mode 100644 index 7ab6cbedd..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f +++ /dev/null @@ -1 +0,0 @@ -xQj!S*hOϮ8bgr|rv!b+l>G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 b/test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 deleted file mode 100644 index 312b2c1d5..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f93275..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e b/test_data/test_repos/test_repo_4/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e deleted file mode 100644 index f9dc2d4b2..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 b/test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 deleted file mode 100644 index f3a3ba397..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f1..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba b/test_data/test_repos/test_repo_4/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba deleted file mode 100644 index 41025422d..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b4/70f07d2aaf2b537808b285cab667259b4e0ca7 b/test_data/test_repos/test_repo_4/dotGit/objects/b4/70f07d2aaf2b537808b285cab667259b4e0ca7 deleted file mode 100644 index 3d9899afa..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/b4/70f07d2aaf2b537808b285cab667259b4e0ca7 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 b/test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 deleted file mode 100644 index ff582f60d..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 b/test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 deleted file mode 100644 index 5e07a2040..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 b/test_data/test_repos/test_repo_4/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 deleted file mode 100644 index bd76a1d59..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 b/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 deleted file mode 100644 index 1533a3b46..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 +++ /dev/null @@ -1,3 +0,0 @@ -x] -0})JDJ҂i6+401j]; Kf09}4Q(3kletXԞ$2t1%Hх b>hsw>}igd% yzjZ7j wQU -p?G| \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 b/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 deleted file mode 100644 index 62c73ed71..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 +++ /dev/null @@ -1 +0,0 @@ -xAj0 EgS-lE Wป9}+t?>j-OU!z"#96D $3#-ѫM攮ǀp]Y8%cJp'13-i^}6Q쟩/wK֚{lֲ޹ﰕz/FMq \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 b/test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 deleted file mode 100644 index 7ed4768c5..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace b/test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace deleted file mode 100644 index e80123615..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f4420..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 b/test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 deleted file mode 100644 index 6de092554..000000000 Binary files a/test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 and /dev/null differ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 b/test_data/test_repos/test_repo_4/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 deleted file mode 100644 index fac916106..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 +++ /dev/null @@ -1,2 +0,0 @@ -xA - Es5JUƙI1^xS-e`sM<{:!I&J.GQ6Y;d+yp8J1);DL>Rd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev b/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev deleted file mode 100644 index 986aea9ec..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev +++ /dev/null @@ -1 +0,0 @@ -64cfcee9aad1c84581631636bfc54f2050718d1a diff --git a/test_data/test_repos/test_repo_4/dotGit/refs/heads/master b/test_data/test_repos/test_repo_4/dotGit/refs/heads/master deleted file mode 100644 index b05755804..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -7b2eba252004b7c867413def2a0984d545daab8b diff --git a/test_data/test_repos/test_repo_4/gitleaks.toml b/test_data/test_repos/test_repo_4/gitleaks.toml deleted file mode 100644 index a09fee0fd..000000000 --- a/test_data/test_repos/test_repo_4/gitleaks.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "3.3" - Max = "3.5" - Group = "1" diff --git a/test_data/test_repos/test_repo_4/no_secrets.md b/test_data/test_repos/test_repo_4/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_4/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_4/secrets.md b/test_data/test_repos/test_repo_4/secrets.md deleted file mode 100644 index 67c45b604..000000000 --- a/test_data/test_repos/test_repo_4/secrets.md +++ /dev/null @@ -1,21 +0,0 @@ -### This file contains some secrets - - - hey, if you type in your pw, it will show as stars - ********* see! - hunter2 - doesnt look like stars to me - ******* - thats what I see - oh, really? - Absolutely - you can go hunter2 my hunter2-ing hunter2 - haha, does that look funny to you? - lol, yes. See, when YOU type hunter2, it shows to us as ******* - thats neat, I didnt know IRC did that - yep, no matter how many times you type hunter2, it will show to us as ******* - awesome! - wait, how do you know my pw? - er, I just copy pasted YOUR ******'s and it appears to YOU as hunter2 cause its your pw - oh, ok. - diff --git a/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG deleted file mode 100644 index c629f60f5..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/HEAD b/test_data/test_repos/test_repo_5/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_5/dotGit/config b/test_data/test_repos/test_repo_5/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_5/dotGit/description b/test_data/test_repos/test_repo_5/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_5/dotGit/index b/test_data/test_repos/test_repo_5/dotGit/index deleted file mode 100644 index c4a9350ce..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/index and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/info/exclude b/test_data/test_repos/test_repo_5/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_5/dotGit/logs/HEAD b/test_data/test_repos/test_repo_5/dotGit/logs/HEAD deleted file mode 100644 index f4063b514..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/logs/HEAD +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec Zach Rice 1580490269 -0500 commit (initial): init -547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec 1f2a4abc47dabf991e6af6f9770867ce0ac1f360 Zach Rice 1580569654 -0500 commit: introduce secrets -1f2a4abc47dabf991e6af6f9770867ce0ac1f360 ca71fcdeda15f25f0cc661d90e8785c255925c27 Zach Rice 1580569684 -0500 commit: introduce more secrets -ca71fcdeda15f25f0cc661d90e8785c255925c27 a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0 Zach Rice 1580571022 -0500 commit: even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master deleted file mode 100644 index f4063b514..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec Zach Rice 1580490269 -0500 commit (initial): init -547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec 1f2a4abc47dabf991e6af6f9770867ce0ac1f360 Zach Rice 1580569654 -0500 commit: introduce secrets -1f2a4abc47dabf991e6af6f9770867ce0ac1f360 ca71fcdeda15f25f0cc661d90e8785c255925c27 Zach Rice 1580569684 -0500 commit: introduce more secrets -ca71fcdeda15f25f0cc661d90e8785c255925c27 a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0 Zach Rice 1580571022 -0500 commit: even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 b/test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 deleted file mode 100644 index 33381fc0a..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/1f/2a4abc47dabf991e6af6f9770867ce0ac1f360 b/test_data/test_repos/test_repo_5/dotGit/objects/1f/2a4abc47dabf991e6af6f9770867ce0ac1f360 deleted file mode 100644 index cadf400d9..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/objects/1f/2a4abc47dabf991e6af6f9770867ce0ac1f360 +++ /dev/null @@ -1,2 +0,0 @@ -xM -0F]&db4xzsWFfgjw;H \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 b/test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 deleted file mode 100644 index d98e1094c..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec b/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec deleted file mode 100644 index 9e502d7f8..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec +++ /dev/null @@ -1,4 +0,0 @@ -xA -!F[{@1)DttLi ->xG&>d*3@hμZB$olEL.dT>&<pop5gW' -qe"!Eכj&Q3 \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 b/test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 deleted file mode 100644 index 1dbbf398b..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb b/test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb deleted file mode 100644 index 058a16644..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/97/2ea8fcf4f3d9a216644c8eb11df1382b6e02ab b/test_data/test_repos/test_repo_5/dotGit/objects/97/2ea8fcf4f3d9a216644c8eb11df1382b6e02ab deleted file mode 100644 index a0c87faa2..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/97/2ea8fcf4f3d9a216644c8eb11df1382b6e02ab and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/a4/c9fb737d5552fd96fce5cc7eedb23353ba9ed0 b/test_data/test_repos/test_repo_5/dotGit/objects/a4/c9fb737d5552fd96fce5cc7eedb23353ba9ed0 deleted file mode 100644 index 8cf14f842..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/objects/a4/c9fb737d5552fd96fce5cc7eedb23353ba9ed0 +++ /dev/null @@ -1,2 +0,0 @@ -xA -0E]se2$-xl#it\=x_.P*$% .291O 58n$d)ZN EӀڇ5uQf-pc8$#DpDF4ͶwU~t5]h\ES \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/ca/71fcdeda15f25f0cc661d90e8785c255925c27 b/test_data/test_repos/test_repo_5/dotGit/objects/ca/71fcdeda15f25f0cc661d90e8785c255925c27 deleted file mode 100644 index d3f4ab8ce..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/objects/ca/71fcdeda15f25f0cc661d90e8785c255925c27 +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)tyl(gȲ;YN\ggՇ6aYc3Xk)![)Z#'Zj>bd}oD)Ji9{#i23&b5-:y[#z˦quR/k•2'\Aw>G#a06 G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 b/test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 deleted file mode 100644 index 54825cb8c..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e b/test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e deleted file mode 100644 index 0f4f49571..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 b/test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 deleted file mode 100644 index 6ea38dfc8..000000000 Binary files a/test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 and /dev/null differ diff --git a/test_data/test_repos/test_repo_5/dotGit/refs/heads/master b/test_data/test_repos/test_repo_5/dotGit/refs/heads/master deleted file mode 100644 index 14220c0ed..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0 diff --git a/test_data/test_repos/test_repo_5/notes.md b/test_data/test_repos/test_repo_5/notes.md deleted file mode 100644 index 972ea8fcf..000000000 --- a/test_data/test_repos/test_repo_5/notes.md +++ /dev/null @@ -1 +0,0 @@ -Init diff --git a/test_data/test_repos/test_repo_5/secrets.py b/test_data/test_repos/test_repo_5/secrets.py deleted file mode 100644 index 009114bb4..000000000 --- a/test_data/test_repos/test_repo_5/secrets.py +++ /dev/null @@ -1,9 +0,0 @@ -aws_access_key_id='AKIAIO5FODNN7EXAMPLE' -print(aws_access_key_id) - -aws_access_key_id='AKIAIO5FODNN7EXAMPL2' -print(aws_access_key_id) - -more_secrets = '99432bfewaf823ec3294e231' -print(more_secrets) - diff --git a/test_data/test_repos/test_repo_6/application.yaml b/test_data/test_repos/test_repo_6/application.yaml deleted file mode 100644 index dd6e8207f..000000000 --- a/test_data/test_repos/test_repo_6/application.yaml +++ /dev/null @@ -1,3 +0,0 @@ -appName: "Gitleaks-Testing-App" -api_token: exampleSecretPassword -db_password: verySecretProductionPassword \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/config/application.properties b/test_data/test_repos/test_repo_6/config/application.properties deleted file mode 100644 index 5cb000d0f..000000000 --- a/test_data/test_repos/test_repo_6/config/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -language=en_EN -apiToken=d41d8cd98f00b204e9800998ecf8427e -aws_access_key_id=AKIAIO5FODNN7EXAMPLE \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_6/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 60c9e47f1..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -comment diff --git a/test_data/test_repos/test_repo_6/dotGit/HEAD b/test_data/test_repos/test_repo_6/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_6/dotGit/config b/test_data/test_repos/test_repo_6/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_6/dotGit/description b/test_data/test_repos/test_repo_6/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_6/dotGit/index b/test_data/test_repos/test_repo_6/dotGit/index deleted file mode 100644 index 9a4f995b2..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/index and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/info/exclude b/test_data/test_repos/test_repo_6/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_6/dotGit/logs/HEAD b/test_data/test_repos/test_repo_6/dotGit/logs/HEAD deleted file mode 100644 index 1dee1f5f5..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/logs/HEAD +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571595 -0500 commit: Adding some secrets in config folder -98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571636 -0500 discard: [bc379e22c22a97ca5ffc871c1449af854f6f26c4] diff --git a/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master deleted file mode 100644 index 1112c7dbc..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571595 -0500 commit: Adding some secrets in config folder diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d4..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 b/test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 deleted file mode 100644 index 8226e0266..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 b/test_data/test_repos/test_repo_6/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 deleted file mode 100644 index eb42e8687..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 b/test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 deleted file mode 100644 index e59352e95..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee5333..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 b/test_data/test_repos/test_repo_6/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 deleted file mode 100644 index 0d57232e8..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d6946..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c b/test_data/test_repos/test_repo_6/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c deleted file mode 100644 index 86d326ddc..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 b/test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 deleted file mode 100644 index f3467bbd4..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 b/test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 deleted file mode 100644 index 0867e75c9..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 b/test_data/test_repos/test_repo_6/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 deleted file mode 100644 index 62de872c7..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 +++ /dev/null @@ -1 +0,0 @@ -x-j0;)< SJB@A ۿlI_Y쑃޳S)|nѶYoe&SWǭ5r:EVfC _Y .Zu\\Tz"GdQօW*)f<=ƂD%ˣYSC \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 b/test_data/test_repos/test_repo_6/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 deleted file mode 100644 index cafdfdb17..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 b/test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 deleted file mode 100644 index ad8ee05b4..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ce..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab b/test_data/test_repos/test_repo_6/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab deleted file mode 100644 index 692983a56..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab +++ /dev/null @@ -1,2 +0,0 @@ -x -1 SMf+"JXY O^00FB\=k`%!9J0̎轐\5 ;x%T4r:}*A ֳH۾TؖԒ~g7xdr}l3.E EܸLمǖT%P\ ~P7oq,\ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 b/test_data/test_repos/test_repo_6/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 deleted file mode 100644 index 142e1a6d5..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 b/test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 deleted file mode 100644 index 7f8431777..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 b/test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 deleted file mode 100644 index db5b596ed..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/dd/cd9ac6904950dcc48e4c04ba043707e9e0117f b/test_data/test_repos/test_repo_6/dotGit/objects/dd/cd9ac6904950dcc48e4c04ba043707e9e0117f deleted file mode 100644 index 44c4916c6..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/dd/cd9ac6904950dcc48e4c04ba043707e9e0117f and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077b..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4..000000000 Binary files a/test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 and /dev/null differ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAH 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master deleted file mode 100644 index c1e43ae7b..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 748f11eaf2c38c3cf0ac6a22e44208777e79fa6f Zach Rice 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD b/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD deleted file mode 100644 index c1e43ae7b..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 748f11eaf2c38c3cf0ac6a22e44208777e79fa6f Zach Rice 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a b/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a deleted file mode 100644 index 1f425766c..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a +++ /dev/null @@ -1,4 +0,0 @@ -xuRn8@Z TdYqEK@Rb[LQVO7̻C^zRGs2дlJuf۔SmrRfZꎝ*4u!_$6 a :*:)Ǩg ptjnFM]s8eiZjd6#.QH'ZawxxiD-KE3fj'`$ (崣9_R2Op$a0G+@}F{-N]fG(!~4ґfL~9>ӹ|x ʰw inN#>ǘyvtfaz.Cw5o{}t,'Fߨ_ XBy<֢e)lb3Q@\1d#rGWΤi0y_.4G:Z`2(M$zE8>k,o- -LJ'zv.n 9mEn)׋}2FPn/7 %J~0' ;9ЈRfy' -AOh̟wcJEAӝ@k[ u~,@n?HVHgđp =ŌSvw*iR7)diz0mʌB c ÐZi-b1U:%*mBPbZjP,ɲ)*FlLTU"^ L -`] -9k.?HSn리ϫ'JPR} -xKQ6<3XzKmK@!BB+g2W35q 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 8d1fb60d2d80f0590f191ed5ace1e45ef780909a Zach Rice 1597253780 -0400 commit: gitleaks allow secret diff --git a/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master deleted file mode 100644 index 8244f3823..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 8d1fb60d2d80f0590f191ed5ace1e45ef780909a Zach Rice 1597253780 -0400 commit: gitleaks allow secret diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d4..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 b/test_data/test_repos/test_repo_9/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 deleted file mode 100644 index eb42e8687..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee5333..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 b/test_data/test_repos/test_repo_9/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 deleted file mode 100644 index 0d57232e8..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d6946..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c b/test_data/test_repos/test_repo_9/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c deleted file mode 100644 index 86d326ddc..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a b/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a deleted file mode 100644 index e086a5ae9..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a +++ /dev/null @@ -1,2 +0,0 @@ -xM -0F]se߀gpn2bk$zWEmeFwMԯ*t_湼aG* \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 b/test_data/test_repos/test_repo_9/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 deleted file mode 100644 index 62de872c7..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 +++ /dev/null @@ -1 +0,0 @@ -x-j0;)< SJB@A ۿlI_Y쑃޳S)|nѶYoe&SWǭ5r:EVfC _Y .Zu\\Tz"GdQօW*)f<=ƂD%ˣYSC \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 b/test_data/test_repos/test_repo_9/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 deleted file mode 100644 index cafdfdb17..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 b/test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 deleted file mode 100644 index 7a69ceae3..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ce..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab b/test_data/test_repos/test_repo_9/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab deleted file mode 100644 index 692983a56..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab +++ /dev/null @@ -1,2 +0,0 @@ -x -1 SMf+"JXY O^00FB\=k`%!9J0̎轐\5 ;x%T4r:}*A ֳH۾TؖԒ~g7xdr}l3.E EܸLمǖT%P\ ~P7oq,\ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 b/test_data/test_repos/test_repo_9/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 deleted file mode 100644 index 142e1a6d5..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077b..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4..000000000 Binary files a/test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 and /dev/null differ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAH|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]''' +secretGroup = 5 +entropy = 3.5 diff --git a/testdata/config/base.toml b/testdata/config/base.toml new file mode 100644 index 000000000..ba7b2ce2c --- /dev/null +++ b/testdata/config/base.toml @@ -0,0 +1,10 @@ +title = "gitleaks config" + +[extend] +path="../testdata/config/extend_1.toml" + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/entropy_group.toml b/testdata/config/entropy_group.toml new file mode 100755 index 000000000..eacfc50ea --- /dev/null +++ b/testdata/config/entropy_group.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" + +[[rules]] +id = "discord-api-key" +description = "Discord API key" +regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]''' +secretGroup = 3 +entropy = 3.5 diff --git a/testdata/config/escaped_character_group.toml b/testdata/config/escaped_character_group.toml new file mode 100644 index 000000000..b28039539 --- /dev/null +++ b/testdata/config/escaped_character_group.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" +# https://learnxinyminutes.com/docs/toml/ for toml reference + +[[rules]] + id = "pypi-upload-token" + description = "PyPI upload token" + regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' + tags = ["key", "pypi"] \ No newline at end of file diff --git a/testdata/config/extend_1.toml b/testdata/config/extend_1.toml new file mode 100644 index 000000000..1f4eec0f0 --- /dev/null +++ b/testdata/config/extend_1.toml @@ -0,0 +1,10 @@ +title = "gitleaks extended 1" + +[extend] +path="../testdata/config/extend_2.toml" + +[[rules]] + description = "AWS Access Key" + id = "aws-access-key" + regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' + tags = ["key", "AWS"] diff --git a/testdata/config/extend_2.toml b/testdata/config/extend_2.toml new file mode 100644 index 000000000..7532c99e6 --- /dev/null +++ b/testdata/config/extend_2.toml @@ -0,0 +1,10 @@ +title = "gitleaks extended 2" + +[extend] +path="../testdata/config/extend_3.toml" + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key-again" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/extend_3.toml b/testdata/config/extend_3.toml new file mode 100644 index 000000000..47644c296 --- /dev/null +++ b/testdata/config/extend_3.toml @@ -0,0 +1,9 @@ +title = "gitleaks extended 3" + +## This should not be loaded since we can only extend configs to a depth of 3 + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key-again-again" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/generic.toml b/testdata/config/generic.toml new file mode 100644 index 000000000..625e44efc --- /dev/null +++ b/testdata/config/generic.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)((key|api|token|secret|password)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]''' +entropy = 3.7 +secretGroup = 4 diff --git a/testdata/config/generic_with_py_path.toml b/testdata/config/generic_with_py_path.toml new file mode 100644 index 000000000..a528893e9 --- /dev/null +++ b/testdata/config/generic_with_py_path.toml @@ -0,0 +1,36 @@ +title = "gitleaks config" + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)((key|api|token|secret|password)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]''' +path = '''.py''' +entropy = 3.7 +secretGroup = 4 + +[allowlist] +description = "global allow lists" +regexes = [ + '''219-09-9999''', + '''078-05-1120''', + '''(9[0-9]{2}|666)-\d{2}-\d{4}''', + '''process''', + '''getenv''', + '''\.env''', + '''env\(''', + '''env\.''', + '''setting''', + '''load''', + '''token''', + '''password''', + '''secret''', + '''api\_key''', + '''apikey''', + '''api\-key''', + ] +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''' +] + diff --git a/testdata/config/path_only.toml b/testdata/config/path_only.toml new file mode 100644 index 000000000..97a8a4870 --- /dev/null +++ b/testdata/config/path_only.toml @@ -0,0 +1,6 @@ +title = "gitleaks config" + +[[rules]] +description = "Python Files" +id = "python-files-only" +path = '''.py''' diff --git a/testdata/config/simple.toml b/testdata/config/simple.toml new file mode 100644 index 000000000..c5fbea1c3 --- /dev/null +++ b/testdata/config/simple.toml @@ -0,0 +1,222 @@ +title = "gitleaks config" +# https://learnxinyminutes.com/docs/toml/ for toml reference + +[[rules]] + description = "AWS Access Key" + id = "aws-access-key" + regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' + tags = ["key", "AWS"] + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] + +[[rules]] + description = "AWS MWS key" + id = "aws-mws-key" + regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' + tags = ["key", "AWS", "MWS"] + +[[rules]] + description = "Facebook Secret Key" + id = "facebook-secret-key" + regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' + tags = ["key", "Facebook"] + +[[rules]] + description = "Facebook Client ID" + id = "facebook-client-id" + regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' + tags = ["key", "Facebook"] + +[[rules]] + description = "Twitter Secret Key" + id = "twitter-secret-key" + regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' + tags = ["key", "Twitter"] + +[[rules]] + description = "Twitter Client ID" + id = "twitter-client-id" + regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' + tags = ["client", "Twitter"] + +[[rules]] + description = "Github Personal Access Token" + id = "github-pat" + regex = '''ghp_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + description = "Github OAuth Access Token" + id = "github-oauth" + regex = '''gho_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + id = "github-app" + description = "Github App Token" + regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + id = "github-refresh" + description = "Github Refresh Token" + regex = '''ghr_[0-9a-zA-Z]{76}''' + tags = ["key", "Github"] + +[[rules]] + id = "linkedin-client" + description = "LinkedIn Client ID" + regex = '''(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}''' + tags = ["client", "LinkedIn"] + +[[rules]] + id = "linkedin-secret" + description = "LinkedIn Secret Key" + regex = '''(?i)linkedin(.{0,20})?[0-9a-z]{16}''' + tags = ["secret", "LinkedIn"] + +[[rules]] + id = "slack" + description = "Slack" + regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' + tags = ["key", "Slack"] + +[[rules]] + id = "apkey" + description = "Asymmetric Private Key" + regex = '''-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----''' + tags = ["key", "AsymmetricPrivateKey"] + +[[rules]] + id = "google" + description = "Google API key" + regex = '''AIza[0-9A-Za-z\-_]{35}''' + tags = ["key", "Google"] + +[[rules]] + id = "google" + description = "Google (GCP) Service Account" + regex = '''"type": "service_account"''' + tags = ["key", "Google"] + +[[rules]] + id = "heroku" + description = "Heroku API key" + regex = '''(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' + tags = ["key", "Heroku"] + +[[rules]] + id = "mailchimp" + description = "MailChimp API key" + regex = '''(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}''' + tags = ["key", "Mailchimp"] + +[[rules]] + id = "mailgun" + description = "Mailgun API key" + regex = '''((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}''' + tags = ["key", "Mailgun"] + +[[rules]] + id = "paypal" + description = "PayPal Braintree access token" + regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' + tags = ["key", "Paypal"] + +[[rules]] + id = "piacatic" + description = "Picatic API key" + regex = '''sk_live_[0-9a-z]{32}''' + tags = ["key", "Picatic"] + +[[rules]] + id = "sendgrid" + description = "SendGrid API Key" + regex = '''SG\.[\w_]{16,32}\.[\w_]{16,64}''' + tags = ["key", "SendGrid"] + +[[rules]] + description = "Sidekiq Secret" + id = "sidekiq-secret" + regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' + secretGroup = 1 + keywords = [ + "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", + ] + +[[rules]] + description = "Sidekiq Sensitive URL" + id = "sidekiq-sensitive-url" + regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' + secretGroup = 2 + keywords = [ + "gems.contribsys.com","enterprise.contribsys.com", + ] + +[[rules]] + id = "slack-webhook" + description = "Slack Webhook" + regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}''' + tags = ["key", "slack"] + +[[rules]] + id = "stripe" + description = "Stripe API key" + regex = '''(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}''' + tags = ["key", "Stripe"] + +[[rules]] + id = "square" + description = "Square access token" + regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' + tags = ["key", "square"] + +[[rules]] + id = "square-oauth" + description = "Square OAuth secret" + regex = '''sq0csp-[0-9A-Za-z\-_]{43}''' + tags = ["key", "square"] + +[[rules]] + id = "twilio" + description = "Twilio API key" + regex = '''(?i)twilio(.{0,20})?SK[0-9a-f]{32}''' + tags = ["key", "twilio"] + +[[rules]] + id = "dynatrace" + description = "Dynatrace ttoken" + regex = '''dt0[a-zA-Z]{1}[0-9]{2}\.[A-Z0-9]{24}\.[A-Z0-9]{64}''' + tags = ["key", "Dynatrace"] + +[[rules]] + id = "shopify" + description = "Shopify shared secret" + regex = '''shpss_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-access" + description = "Shopify access token" + regex = '''shpat_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-custom" + description = "Shopify custom app access token" + regex = '''shpca_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-private" + description = "Shopify private app access token" + regex = '''shppa_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "pypi" + description = "PyPI upload token" + regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}''' + tags = ["key", "pypi"] + diff --git a/testdata/expected/git/small-branch-foo.txt b/testdata/expected/git/small-branch-foo.txt new file mode 100644 index 000000000..b3554c7ac --- /dev/null +++ b/testdata/expected/git/small-branch-foo.txt @@ -0,0 +1,17 @@ +import ( + "fmt" + "os" +) + // seems safer + aws_token := os.Getenv("AWS_TOKEN") +package foo + +import "fmt" + +func Foo() { + fmt.Println("foo") + + // seems safe + aws_token := "AKIALALEMEL33243OLIA" + fmt.Println(aws_token) +} diff --git a/testdata/expected/git/small.txt b/testdata/expected/git/small.txt new file mode 100644 index 000000000..7235dd3a8 --- /dev/null +++ b/testdata/expected/git/small.txt @@ -0,0 +1,67 @@ +import ( + "fmt" + "os" +) + // seems safer + aws_token := os.Getenv("AWS_TOKEN") +package foo + +import "fmt" + +func Foo() { + fmt.Println("foo") + + // seems safe + aws_token := "AKIALALEMEL33243OLIA" + fmt.Println(aws_token) +} +package api + +import "fmt" + +func PrintHello() { + fmt.Println("hello") +} +import ( + "fmt" + "os" +) + var a = "initial" + fmt.Println(a) + var b, c int = 1, 2 + fmt.Println(b, c) + var d = true + fmt.Println(d) + var e int + fmt.Println(e) + // load secret via env + awsToken := os.Getenv("AWS_TOKEN") + + f := "apple" + fmt.Println(f) + + // opps I added a secret at line 20 + awsToken := "AKIALALEMEL33243OLIA" +package main + +import "fmt" + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + f := "apple" + fmt.Println(f) +} +# test +This is a repo used for testing gitleaks diff --git a/testdata/expected/report/csv_simple.csv b/testdata/expected/report/csv_simple.csv new file mode 100644 index 000000000..ca3cb0a02 --- /dev/null +++ b/testdata/expected/report/csv_simple.csv @@ -0,0 +1,2 @@ +RuleID,Commit,File,Secret,Match,StartLine,EndLine,StartColumn,EndColumn,Author,Message,Date,Email,Fingerprint +test-rule,0000000000000000,auth.py,a secret,line containing secret,1,2,1,2,John Doe,opps,10-19-2003,johndoe@gmail.com,fingerprint diff --git a/testdata/expected/report/empty.json b/testdata/expected/report/empty.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/testdata/expected/report/empty.json @@ -0,0 +1 @@ +[] diff --git a/testdata/expected/report/json_simple.json b/testdata/expected/report/json_simple.json new file mode 100644 index 000000000..9d0a521ba --- /dev/null +++ b/testdata/expected/report/json_simple.json @@ -0,0 +1,21 @@ +[ + { + "Description": "", + "StartLine": 1, + "EndLine": 2, + "StartColumn": 1, + "EndColumn": 2, + "Match": "line containing secret", + "Secret": "a secret", + "File": "auth.py", + "Commit": "0000000000000000", + "Entropy": 0, + "Author": "John Doe", + "Email": "johndoe@gmail.com", + "Date": "10-19-2003", + "Message": "opps", + "Tags": [], + "RuleID": "test-rule", + "Fingerprint": "" + } +] diff --git a/testdata/expected/report/sarif_simple.sarif b/testdata/expected/report/sarif_simple.sarif new file mode 100644 index 000000000..802f415fb --- /dev/null +++ b/testdata/expected/report/sarif_simple.sarif @@ -0,0 +1,301 @@ +{ + "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "gitleaks", + "semanticVersion": "v8.0.0", + "rules": [ + { + "id": "aws-access-key", + "name": "AWS Access Key", + "shortDescription": { + "text": "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}" + } + }, + { + "id": "aws-secret-key", + "name": "AWS Secret Key", + "shortDescription": { + "text": "(?i)aws_(.{0,20})?=?.[\\'\\\"0-9a-zA-Z\\/+]{40}" + } + }, + { + "id": "aws-mws-key", + "name": "AWS MWS key", + "shortDescription": { + "text": "amzn\\.mws\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" + } + }, + { + "id": "facebook-secret-key", + "name": "Facebook Secret Key", + "shortDescription": { + "text": "(?i)(facebook|fb)(.{0,20})?(?-i)['\\\"][0-9a-f]{32}['\\\"]" + } + }, + { + "id": "facebook-client-id", + "name": "Facebook Client ID", + "shortDescription": { + "text": "(?i)(facebook|fb)(.{0,20})?['\\\"][0-9]{13,17}['\\\"]" + } + }, + { + "id": "twitter-secret-key", + "name": "Twitter Secret Key", + "shortDescription": { + "text": "(?i)twitter(.{0,20})?['\\\"][0-9a-z]{35,44}['\\\"]" + } + }, + { + "id": "twitter-client-id", + "name": "Twitter Client ID", + "shortDescription": { + "text": "(?i)twitter(.{0,20})?['\\\"][0-9a-z]{18,25}['\\\"]" + } + }, + { + "id": "github-pat", + "name": "Github Personal Access Token", + "shortDescription": { + "text": "ghp_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-oauth", + "name": "Github OAuth Access Token", + "shortDescription": { + "text": "gho_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-app", + "name": "Github App Token", + "shortDescription": { + "text": "(ghu|ghs)_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-refresh", + "name": "Github Refresh Token", + "shortDescription": { + "text": "ghr_[0-9a-zA-Z]{76}" + } + }, + { + "id": "linkedin-client", + "name": "LinkedIn Client ID", + "shortDescription": { + "text": "(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}" + } + }, + { + "id": "linkedin-secret", + "name": "LinkedIn Secret Key", + "shortDescription": { + "text": "(?i)linkedin(.{0,20})?[0-9a-z]{16}" + } + }, + { + "id": "slack", + "name": "Slack", + "shortDescription": { + "text": "xox[baprs]-([0-9a-zA-Z]{10,48})?" + } + }, + { + "id": "apkey", + "name": "Asymmetric Private Key", + "shortDescription": { + "text": "-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----" + } + }, + { + "id": "google", + "name": "Google (GCP) Service Account", + "shortDescription": { + "text": "\"type\": \"service_account\"" + } + }, + { + "id": "google", + "name": "Google (GCP) Service Account", + "shortDescription": { + "text": "\"type\": \"service_account\"" + } + }, + { + "id": "heroku", + "name": "Heroku API key", + "shortDescription": { + "text": "(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" + } + }, + { + "id": "mailchimp", + "name": "MailChimp API key", + "shortDescription": { + "text": "(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}" + } + }, + { + "id": "mailgun", + "name": "Mailgun API key", + "shortDescription": { + "text": "((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}" + } + }, + { + "id": "paypal", + "name": "PayPal Braintree access token", + "shortDescription": { + "text": "access_token\\$production\\$[0-9a-z]{16}\\$[0-9a-f]{32}" + } + }, + { + "id": "piacatic", + "name": "Picatic API key", + "shortDescription": { + "text": "sk_live_[0-9a-z]{32}" + } + }, + { + "id": "sendgrid", + "name": "SendGrid API Key", + "shortDescription": { + "text": "SG\\.[\\w_]{16,32}\\.[\\w_]{16,64}" + } + }, + { + "id": "sidekiq-secret", + "name": "Sidekiq Secret", + "shortDescription": { + "text": "(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\\-_\\t .]{0,20})(?:[\\s|']|[\\s|\"]){0,3}(?:=|\u003e|:=|\\|\\|:|\u003c=|=\u003e|:)(?:'|\\\"|\\s|=|\\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\\\"|\\n|\\r|\\s|\\x60|;]|$)" + } + }, + { + "id": "sidekiq-sensitive-url", + "name": "Sidekiq Sensitive URL", + "shortDescription": { + "text": "(?i)\\b(http(?:s??):\\/\\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\\/|\\#|\\?|:]|$)" + } + }, + { + "id": "slack-webhook", + "name": "Slack Webhook", + "shortDescription": { + "text": "https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}" + } + }, + { + "id": "stripe", + "name": "Stripe API key", + "shortDescription": { + "text": "(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}" + } + }, + { + "id": "square", + "name": "Square access token", + "shortDescription": { + "text": "sq0atp-[0-9A-Za-z\\-_]{22}" + } + }, + { + "id": "square-oauth", + "name": "Square OAuth secret", + "shortDescription": { + "text": "sq0csp-[0-9A-Za-z\\-_]{43}" + } + }, + { + "id": "twilio", + "name": "Twilio API key", + "shortDescription": { + "text": "(?i)twilio(.{0,20})?SK[0-9a-f]{32}" + } + }, + { + "id": "dynatrace", + "name": "Dynatrace ttoken", + "shortDescription": { + "text": "dt0[a-zA-Z]{1}[0-9]{2}\\.[A-Z0-9]{24}\\.[A-Z0-9]{64}" + } + }, + { + "id": "shopify", + "name": "Shopify shared secret", + "shortDescription": { + "text": "shpss_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-access", + "name": "Shopify access token", + "shortDescription": { + "text": "shpat_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-custom", + "name": "Shopify custom app access token", + "shortDescription": { + "text": "shpca_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-private", + "name": "Shopify private app access token", + "shortDescription": { + "text": "shppa_[a-fA-F0-9]{32}" + } + }, + { + "id": "pypi", + "name": "PyPI upload token", + "shortDescription": { + "text": "pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}" + } + } + ] + } + }, + "results": [ + { + "message": { + "text": "test-rule has detected secret for file auth.py at commit 0000000000000000." + }, + "ruleId": "test-rule", + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "auth.py" + }, + "region": { + "startLine": 1, + "startColumn": 1, + "endLine": 2, + "endColumn": 2, + "snippet": { + "text": "a secret" + } + } + } + } + ], + "partialFingerprints": { + "commitSha": "0000000000000000", + "email": "johndoe@gmail.com", + "author": "John Doe", + "date": "10-19-2003", + "commitMessage": "opps" + } + } + ] + } + ] +} diff --git a/testdata/repos/nogit/main.go b/testdata/repos/nogit/main.go new file mode 100644 index 000000000..acbef43fd --- /dev/null +++ b/testdata/repos/nogit/main.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + // opps I added a secret at line 20 + awsToken := "AKIALALEMEL33243OLIA" + + f := "apple" + fmt.Println(f) +} diff --git a/testdata/repos/small/README.md b/testdata/repos/small/README.md new file mode 100644 index 000000000..5cc9baf4d --- /dev/null +++ b/testdata/repos/small/README.md @@ -0,0 +1,2 @@ +# test +This is a repo used for testing gitleaks diff --git a/testdata/repos/small/api/api.go b/testdata/repos/small/api/api.go new file mode 100644 index 000000000..d83247911 --- /dev/null +++ b/testdata/repos/small/api/api.go @@ -0,0 +1,7 @@ +package api + +import "fmt" + +func PrintHello() { + fmt.Println("hello") +} diff --git a/testdata/repos/small/dotGit/COMMIT_EDITMSG b/testdata/repos/small/dotGit/COMMIT_EDITMSG new file mode 100644 index 000000000..0ba1543fd --- /dev/null +++ b/testdata/repos/small/dotGit/COMMIT_EDITMSG @@ -0,0 +1 @@ +removing secret from foo package diff --git a/testdata/repos/small/dotGit/FETCH_HEAD b/testdata/repos/small/dotGit/FETCH_HEAD new file mode 100644 index 000000000..66c1c77ce --- /dev/null +++ b/testdata/repos/small/dotGit/FETCH_HEAD @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e branch 'main' of github.com:gitleaks/test diff --git a/testdata/repos/small/dotGit/HEAD b/testdata/repos/small/dotGit/HEAD new file mode 100644 index 000000000..b870d8262 --- /dev/null +++ b/testdata/repos/small/dotGit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/testdata/repos/small/dotGit/ORIG_HEAD b/testdata/repos/small/dotGit/ORIG_HEAD new file mode 100644 index 000000000..96321ccd4 --- /dev/null +++ b/testdata/repos/small/dotGit/ORIG_HEAD @@ -0,0 +1 @@ +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 diff --git a/test_data/test_repos/test_repo_8/dotGit/config b/testdata/repos/small/dotGit/config similarity index 68% rename from test_data/test_repos/test_repo_8/dotGit/config rename to testdata/repos/small/dotGit/config index 137b81bbb..374df60b1 100644 --- a/test_data/test_repos/test_repo_8/dotGit/config +++ b/testdata/repos/small/dotGit/config @@ -6,8 +6,8 @@ ignorecase = true precomposeunicode = true [remote "origin"] - url = https://github.com/zricethezav/test_repo_8.git + url = git@github.com:gitleaks/test.git fetch = +refs/heads/*:refs/remotes/origin/* -[branch "master"] +[branch "main"] remote = origin - merge = refs/heads/master + merge = refs/heads/main diff --git a/test_data/test_repos/test_repo_1/dotGit/description b/testdata/repos/small/dotGit/description similarity index 100% rename from test_data/test_repos/test_repo_1/dotGit/description rename to testdata/repos/small/dotGit/description diff --git a/testdata/repos/small/dotGit/index b/testdata/repos/small/dotGit/index new file mode 100644 index 000000000..fec9889ae Binary files /dev/null and b/testdata/repos/small/dotGit/index differ diff --git a/test_data/test_repos/test_repo_1/dotGit/info/exclude b/testdata/repos/small/dotGit/info/exclude similarity index 100% rename from test_data/test_repos/test_repo_1/dotGit/info/exclude rename to testdata/repos/small/dotGit/info/exclude diff --git a/testdata/repos/small/dotGit/logs/HEAD b/testdata/repos/small/dotGit/logs/HEAD new file mode 100644 index 000000000..8fc59bb3b --- /dev/null +++ b/testdata/repos/small/dotGit/logs/HEAD @@ -0,0 +1,13 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896362 -0500 checkout: moving from main to remove-secrets +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 906335481df9a4b48906c90318b4fac76b67fe73 Zach Rice 1635896426 -0500 commit: load token via env var +906335481df9a4b48906c90318b4fac76b67fe73 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896518 -0500 commit: add api package +a122b33c6bad3ee54724f52f2caad385ab1982ab a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896543 -0500 checkout: moving from remove-secrets to api-pkg +a122b33c6bad3ee54724f52f2caad385ab1982ab 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896644 -0500 checkout: moving from api-pkg to main +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: Fast-forward +2e1db472eeba53f06c4026ae4566ea022e36598e 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896716 -0500 checkout: moving from main to foo +2e1db472eeba53f06c4026ae4566ea022e36598e 491504d5a31946ce75e22554cc34203d8e5ff3ca Zach Rice 1635896886 -0500 commit: adding foo package with secret +491504d5a31946ce75e22554cc34203d8e5ff3ca f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896931 -0500 commit: removing secret from foo package +f1b58b97808f8e744f6a23c693859df5b5968901 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635897009 -0500 checkout: moving from foo to main +2e1db472eeba53f06c4026ae4566ea022e36598e f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635897062 -0500 checkout: moving from main to foo +f1b58b97808f8e744f6a23c693859df5b5968901 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635897508 -0500 checkout: moving from foo to main diff --git a/testdata/repos/small/dotGit/logs/refs/heads/api-pkg b/testdata/repos/small/dotGit/logs/refs/heads/api-pkg new file mode 100644 index 000000000..18e1cff1a --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/api-pkg @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896543 -0500 branch: Created from HEAD diff --git a/testdata/repos/small/dotGit/logs/refs/heads/foo b/testdata/repos/small/dotGit/logs/refs/heads/foo new file mode 100644 index 000000000..0588ad530 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/foo @@ -0,0 +1,3 @@ +0000000000000000000000000000000000000000 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896716 -0500 branch: Created from HEAD +2e1db472eeba53f06c4026ae4566ea022e36598e 491504d5a31946ce75e22554cc34203d8e5ff3ca Zach Rice 1635896886 -0500 commit: adding foo package with secret +491504d5a31946ce75e22554cc34203d8e5ff3ca f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896931 -0500 commit: removing secret from foo package diff --git a/testdata/repos/small/dotGit/logs/refs/heads/main b/testdata/repos/small/dotGit/logs/refs/heads/main new file mode 100644 index 000000000..50148f0e8 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/main @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: Fast-forward diff --git a/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets b/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets new file mode 100644 index 000000000..58344a340 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets @@ -0,0 +1,3 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896362 -0500 branch: Created from HEAD +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 906335481df9a4b48906c90318b4fac76b67fe73 Zach Rice 1635896426 -0500 commit: load token via env var +906335481df9a4b48906c90318b4fac76b67fe73 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896518 -0500 commit: add api package diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD b/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD new file mode 100644 index 000000000..a2076e59a --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg b/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg new file mode 100644 index 000000000..9c8e059cf --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896552 -0500 update by push diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo b/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo new file mode 100644 index 000000000..f6aed264f --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896935 -0500 update by push diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/main b/testdata/repos/small/dotGit/logs/refs/remotes/origin/main new file mode 100644 index 000000000..530a7894d --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/main @@ -0,0 +1 @@ +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: fast-forward diff --git a/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 b/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 new file mode 100644 index 000000000..dab89999a --- /dev/null +++ b/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 @@ -0,0 +1 @@ +xU1 0`ܯ8nJ.:*(8\ɕ$ w3 Nox{$6f1~wF'0YbF TBpND|*]uCST kL>a#(Jm(sԴ]=>03 \ No newline at end of file diff --git a/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 b/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 new file mode 100644 index 000000000..f9ada0721 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 differ diff --git a/testdata/repos/small/dotGit/objects/2e/1db472eeba53f06c4026ae4566ea022e36598e b/testdata/repos/small/dotGit/objects/2e/1db472eeba53f06c4026ae4566ea022e36598e new file mode 100644 index 000000000..5dd33dfc9 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/2e/1db472eeba53f06c4026ae4566ea022e36598e differ diff --git a/testdata/repos/small/dotGit/objects/49/1504d5a31946ce75e22554cc34203d8e5ff3ca b/testdata/repos/small/dotGit/objects/49/1504d5a31946ce75e22554cc34203d8e5ff3ca new file mode 100644 index 000000000..754d7397e Binary files /dev/null and b/testdata/repos/small/dotGit/objects/49/1504d5a31946ce75e22554cc34203d8e5ff3ca differ diff --git a/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 b/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 new file mode 100644 index 000000000..5bddb82e2 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 differ diff --git a/testdata/repos/small/dotGit/objects/78/9ba677976d5db481de55c799d67acbf8e3f16a b/testdata/repos/small/dotGit/objects/78/9ba677976d5db481de55c799d67acbf8e3f16a new file mode 100644 index 000000000..93acde0f5 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/78/9ba677976d5db481de55c799d67acbf8e3f16a differ diff --git a/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 b/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 new file mode 100644 index 000000000..ce4a269d3 --- /dev/null +++ b/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 @@ -0,0 +1,3 @@ +xM +0F]s%t +"I2E۔ >x_2w@;z㑈ءCX@6 5)M&F:l'FTHďFF1iPSm4cNo;ݷV{]ߗT`=aZw d}fuKK \ No newline at end of file diff --git a/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad b/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad new file mode 100644 index 000000000..5e51e39d4 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad differ diff --git a/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab b/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab new file mode 100644 index 000000000..fbcf357cc Binary files /dev/null and b/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab differ diff --git a/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 b/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 new file mode 100644 index 000000000..8be258a32 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 differ diff --git a/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a b/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a new file mode 100644 index 000000000..9221b3c0a Binary files /dev/null and b/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a differ diff --git a/testdata/repos/small/dotGit/objects/bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886 b/testdata/repos/small/dotGit/objects/bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886 new file mode 100644 index 000000000..ec618b7a9 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886 differ diff --git a/testdata/repos/small/dotGit/objects/d8/32479114dc6be7207edc7c37ce91dd11b93161 b/testdata/repos/small/dotGit/objects/d8/32479114dc6be7207edc7c37ce91dd11b93161 new file mode 100644 index 000000000..0bd9a371a Binary files /dev/null and b/testdata/repos/small/dotGit/objects/d8/32479114dc6be7207edc7c37ce91dd11b93161 differ diff --git a/testdata/repos/small/dotGit/objects/da/2622b4d97e32c5801511244b809144b6b3ea78 b/testdata/repos/small/dotGit/objects/da/2622b4d97e32c5801511244b809144b6b3ea78 new file mode 100644 index 000000000..d4a8c3de9 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/da/2622b4d97e32c5801511244b809144b6b3ea78 differ diff --git a/testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb b/testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb new file mode 100644 index 000000000..53b83ef00 Binary files /dev/null and b/testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb differ diff --git a/testdata/repos/small/dotGit/objects/f1/b58b97808f8e744f6a23c693859df5b5968901 b/testdata/repos/small/dotGit/objects/f1/b58b97808f8e744f6a23c693859df5b5968901 new file mode 100644 index 000000000..a7bf9018e Binary files /dev/null and b/testdata/repos/small/dotGit/objects/f1/b58b97808f8e744f6a23c693859df5b5968901 differ diff --git a/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.idx b/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.idx new file mode 100644 index 000000000..3cdb2bd0f Binary files /dev/null and b/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.idx differ diff --git a/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.pack b/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.pack new file mode 100644 index 000000000..975d3711a Binary files /dev/null and b/testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.pack differ diff --git a/testdata/repos/small/dotGit/packed-refs b/testdata/repos/small/dotGit/packed-refs new file mode 100644 index 000000000..859b8c5a8 --- /dev/null +++ b/testdata/repos/small/dotGit/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 refs/remotes/origin/main diff --git a/testdata/repos/small/dotGit/refs/heads/api-pkg b/testdata/repos/small/dotGit/refs/heads/api-pkg new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/api-pkg @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/heads/foo b/testdata/repos/small/dotGit/refs/heads/foo new file mode 100644 index 000000000..57d584841 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/foo @@ -0,0 +1 @@ +f1b58b97808f8e744f6a23c693859df5b5968901 diff --git a/testdata/repos/small/dotGit/refs/heads/main b/testdata/repos/small/dotGit/refs/heads/main new file mode 100644 index 000000000..98f12e928 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/main @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e diff --git a/testdata/repos/small/dotGit/refs/heads/remove-secrets b/testdata/repos/small/dotGit/refs/heads/remove-secrets new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/remove-secrets @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/HEAD b/testdata/repos/small/dotGit/refs/remotes/origin/HEAD new file mode 100644 index 000000000..4b0a87595 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg b/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/foo b/testdata/repos/small/dotGit/refs/remotes/origin/foo new file mode 100644 index 000000000..57d584841 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/foo @@ -0,0 +1 @@ +f1b58b97808f8e744f6a23c693859df5b5968901 diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/main b/testdata/repos/small/dotGit/refs/remotes/origin/main new file mode 100644 index 000000000..98f12e928 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/main @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e diff --git a/testdata/repos/small/main.go b/testdata/repos/small/main.go new file mode 100644 index 000000000..9a932e37e --- /dev/null +++ b/testdata/repos/small/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + // load secret via env + awsToken := os.Getenv("AWS_TOKEN") + + f := "apple" + fmt.Println(f) +} diff --git a/testdata/tmp/note.txt b/testdata/tmp/note.txt new file mode 100644 index 000000000..429d60380 --- /dev/null +++ b/testdata/tmp/note.txt @@ -0,0 +1 @@ +nothing should be saved here diff --git a/version/version.go b/version/version.go deleted file mode 100644 index ddc9ca1a2..000000000 --- a/version/version.go +++ /dev/null @@ -1,6 +0,0 @@ -package version - -// Version is loaded via LDFLAGS: -// VERSION := `git fetch --tags && git tag | sort -V | tail -1` -// LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks-ng/version.Version=$(VERSION)" -var Version string