pax_global_header00006660000000000000000000000064143766710170014526gustar00rootroot0000000000000052 comment=4b5e8e1829465f633334a914d05c903f537119d8 gitleaks-8.16.0/000077500000000000000000000000001437667101700134255ustar00rootroot00000000000000gitleaks-8.16.0/.github/000077500000000000000000000000001437667101700147655ustar00rootroot00000000000000gitleaks-8.16.0/.github/FUNDING.yml000066400000000000000000000001051437667101700165760ustar00rootroot00000000000000# These are supported funding model platforms github: [zricethezav] gitleaks-8.16.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001437667101700171505ustar00rootroot00000000000000gitleaks-8.16.0/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000010721437667101700216420ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Basic Info (please complete the following information):** - OS: - Gitleaks Version: **Additional context** Add any other context about the problem here. cc @zricethezav gitleaks-8.16.0/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000011551437667101700226770ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. cc @zricethezav gitleaks-8.16.0/.github/ISSUE_TEMPLATE/maintenance.md000066400000000000000000000005071437667101700217560ustar00rootroot00000000000000--- 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 gitleaks-8.16.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000003161437667101700205660ustar00rootroot00000000000000### Description: Explain the purpose of the PR. ### Checklist: * [ ] Does your PR pass tests? * [ ] Have you written new tests for your changes? * [ ] Have you lint your code locally prior to submission? gitleaks-8.16.0/.github/workflows/000077500000000000000000000000001437667101700170225ustar00rootroot00000000000000gitleaks-8.16.0/.github/workflows/gitleaks.yml000066400000000000000000000004661437667101700213560ustar00rootroot00000000000000name: 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-8.16.0/.github/workflows/release.yml000066400000000000000000000031771437667101700211750ustar00rootroot00000000000000name: 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 }} gitleaks-8.16.0/.github/workflows/test.yml000066400000000000000000000006511437667101700205260ustar00rootroot00000000000000name: 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 gitleaks-8.16.0/.gitignore000066400000000000000000000003031437667101700154110ustar00rootroot00000000000000# Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib *.DS_STORE *.idea *.got gitleaks build # configs .gitleaks.toml cmd/generate/config/gitleaks.toml # Test binary *.out dist/ gitleaks-8.16.0/.gitleaksignore000066400000000000000000002167541437667101700164540ustar00rootroot00000000000000418edf165dbb63d6f46993ae8f8818ffd87ea582: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 6d801ed61cf4d75d176cbf9062ec6ad706c9d1eb:detect/detect_test.go:private-key:567 6d801ed61cf4d75d176cbf9062ec6ad706c9d1eb:testdata/repos/symlinks/source_file/id_ed25519:private-key:1 acce01f2338434a78f6a4a06a097b0fd23280484:README.md:aws-access-token:218 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 acce01f2338434a78f6a4a06a097b0fd23280484:README.md:aws-access-token:220 99d620c719020fa24baa831299f0c964da79875e:detect/detect_test.go:aws-access-token:514 111c8b47b65627db117bd20be85ff0aee8961eb9:detect/detect_test.go:private-key:567 99d620c719020fa24baa831299f0c964da79875e:detect/detect_test.go:aws-access-token:512 99d620c719020fa24baa831299f0c964da79875e:detect/detect_test.go:aws-access-token:513 69f161c0a0cc0f7858f7d0609d656f4edcedd84c:detect/detect_test.go:discord-api-token:326 gitleaks-8.16.0/.goreleaser.yml000066400000000000000000000007541437667101700163640ustar00rootroot00000000000000project_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 gitleaks-8.16.0/.pre-commit-hooks.yaml000066400000000000000000000006211437667101700175630ustar00rootroot00000000000000- 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 gitleaks-8.16.0/CONTRIBUTING.md000066400000000000000000000103041437667101700156540ustar00rootroot00000000000000# 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 readable 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 gitleaks-8.16.0/Dockerfile000066400000000000000000000007661437667101700154300ustar00rootroot00000000000000FROM golang:1.19 AS build WORKDIR /go/src/github.com/zricethezav/gitleaks COPY . . 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.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/ USER gitleaks RUN git config --global --add safe.directory '*' ENTRYPOINT ["gitleaks"] gitleaks-8.16.0/LICENSE000066400000000000000000000020551437667101700144340ustar00rootroot00000000000000MIT License Copyright (c) 2019 Zachary Rice Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gitleaks-8.16.0/Makefile000066400000000000000000000010571437667101700150700ustar00rootroot00000000000000.PHONY: test test-cover PKG=github.com/zricethezav/gitleaks 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 -v ./... --race $(COVER) $(PKG) go tool cover -html=cover.out format: go fmt ./... test: format go vet ./... go test -v ./... --race $(PKG) build: format go vet ./... go mod tidy go build $(LDFLAGS) clean: find . -type f -name '*.got.*' -delete find . -type f -name '*.out' -delete gitleaks-8.16.0/README.md000066400000000000000000000400101437667101700146770ustar00rootroot00000000000000# Gitleaks ``` ┌─○───┐ │ │╲ │ │ │ ○ │ │ ○ ░ │ └─░───┘ ```

Github Test gitleaks badge Follow @zricethezav

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.15.3 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: -b, --baseline-path string path to baseline with issues that can be ignored -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 int exit code when leaks have been encountered (default 1) -h, --help help for gitleaks -l, --log-level string log level (trace, debug, info, warn, error, fatal) (default "info") --max-target-megabytes int files larger than this will be skipped --no-banner suppress banner --redact redact secrets from logs and stdout -f, --report-format string output format (json, csv, sarif) (default "json") -r, --report-path string report file -s, --source string path to source (default: $PWD) (default ".") -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 ``` 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 ``` After running the detect command with the --baseline-path parameter, report output (findings.json) will only contain new issues. ### Verify Findings You can verify a finding found by gitleaks using a `git log` command. Example output: ``` Finding: aws_secret="AKIAIMNOJVGFDXXXE4OA" RuleID: aws-access-token Secret AKIAIMNOJVGFDXXXE4OA Entropy: 3.65 File: checks_test.go Line: 37 Commit: ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29 Author: Zachary Rice Email: z@email.com Date: 2018-01-28T17:39:00Z Fingerprint: ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29:checks_test.go:aws-access-token:37 ``` 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''' ] # note: (rule) regexTarget defaults to check the _Secret_ in the finding. # if regexTarget is not specified then _Secret_ will be used. # Acceptable values for regexTarget are "match" and "line" regexTarget = "match" 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)''' ] # note: (global) regexTarget defaults to check the _Secret_ in the finding. # if regexTarget is not specified then _Secret_ will be used. # Acceptable values for regexTarget are "match" and "line" regexTarget = "match" 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) if you would like to contribute to the default configuration. Additionally, you can check out [this gitleaks blog post](https://blog.gitleaks.io/stop-leaking-secrets-configuration-2-3-aeed293b1fbf) which covers advanced configuration setups. ### 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 experimental 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

## Exit Codes 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 ``` gitleaks-8.16.0/USERS.md000066400000000000000000000017261437667101700146560ustar00rootroot00000000000000## 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. [GitLab](https://docs.gitlab.com/ee/user/application_security/secret_detection/) 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). gitleaks-8.16.0/cmd/000077500000000000000000000000001437667101700141705ustar00rootroot00000000000000gitleaks-8.16.0/cmd/detect.go000066400000000000000000000126771437667101700160040ustar00rootroot00000000000000package 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") detectCmd.Flags().Bool("pipe", false, "scan input from stdin, ex: `cat some_file | gitleaks detect --pipe`") detectCmd.Flags().Bool("follow-symlinks", false, "scan files that are symlinks to other files") } 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 detector.MaxTargetMegaBytes, err = cmd.Flags().GetInt("max-target-megabytes"); 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, source) 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 follow symlinks flag if detector.FollowSymlinks, err = cmd.Flags().GetBool("follow-symlinks"); err != nil { log.Fatal().Err(err).Msg("") } // 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") } fromPipe, err := cmd.Flags().GetBool("pipe") if err != nil { log.Fatal().Err(err) } // 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 if fromPipe { findings, err = detector.DetectReader(os.Stdin, 10) if err != nil { // log fatal to exit, no need to continue since a report // will not be generated when scanning from a pipe...for now log.Fatal().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() } gitleaks-8.16.0/cmd/generate/000077500000000000000000000000001437667101700157625ustar00rootroot00000000000000gitleaks-8.16.0/cmd/generate/config/000077500000000000000000000000001437667101700172275ustar00rootroot00000000000000gitleaks-8.16.0/cmd/generate/config/main.go000066400000000000000000000234731437667101700205130ustar00rootroot00000000000000package 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.GitHubFineGrainedPat()) configRules = append(configRules, rules.GitHubOauth()) configRules = append(configRules, rules.GitHubApp()) configRules = append(configRules, rules.GitHubRefresh()) configRules = append(configRules, rules.GitlabPat()) configRules = append(configRules, rules.GitlabPipelineTriggerToken()) configRules = append(configRules, rules.GitlabRunnerRegistrationToken()) 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") } } gitleaks-8.16.0/cmd/generate/config/rules/000077500000000000000000000000001437667101700203615ustar00rootroot00000000000000gitleaks-8.16.0/cmd/generate/config/rules/adafruit.go000066400000000000000000000011061437667101700225050ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/adobe.go000066400000000000000000000016351437667101700217670ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/age.go000066400000000000000000000010301437667101700214360ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/airtable.go000066400000000000000000000010461437667101700224740ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/algolia.go000066400000000000000000000007721437667101700223260ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/alibaba.go000066400000000000000000000016701437667101700222670ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/asana.go000066400000000000000000000017001437667101700217710ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/atlassian.go000066400000000000000000000012471437667101700226730ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/aws.go000066400000000000000000000010531437667101700215010ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/beamer.go000066400000000000000000000010471437667101700221450ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/bitbucket.go000066400000000000000000000020021437667101700226560ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/bittrex.go000066400000000000000000000017341437667101700223760ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/clojars.go000066400000000000000000000010271437667101700223450ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/codecov.go000066400000000000000000000010721437667101700223320ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/coinbase.go000066400000000000000000000011321437667101700224700ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/config.tmpl000066400000000000000000000036771437667101700225410ustar00rootroot00000000000000# 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''', '''package-lock.json''', '''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}} gitleaks-8.16.0/cmd/generate/config/rules/confluent.go000066400000000000000000000020041437667101700227010ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/contentful.go000066400000000000000000000011151437667101700230670ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/databricks.go000066400000000000000000000010041437667101700230120ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/datadog.go000066400000000000000000000010741437667101700223150ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/digitalocean.go000066400000000000000000000024651437667101700233420ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/discord.go000066400000000000000000000025611437667101700223430ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/doppler.go000066400000000000000000000011671437667101700223620ustar00rootroot00000000000000package 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 gitleaks-8.16.0/cmd/generate/config/rules/droneci.go000066400000000000000000000010721437667101700223330ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/dropbox.go000066400000000000000000000023421437667101700223660ustar00rootroot00000000000000package 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 } gitleaks-8.16.0/cmd/generate/config/rules/duffel.go000066400000000000000000000010531437667101700221540ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/dynatrace.go000066400000000000000000000011261437667101700226620ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/easypost.go000066400000000000000000000016301437667101700225570ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/etsy.go000066400000000000000000000010501437667101700216700ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/facebook.go000066400000000000000000000010041437667101700224540ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/fastly.go000066400000000000000000000010641437667101700222130ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/finicity.go000066400000000000000000000017341437667101700225330ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/finnhub.go000066400000000000000000000010721437667101700223410ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/flickr.go000066400000000000000000000010641437667101700221630ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/flutterwave.go000066400000000000000000000026521437667101700232650ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/frameio.go000066400000000000000000000010351437667101700223310ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/freshbooks.go000066400000000000000000000011141437667101700230520ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/gcp.go000066400000000000000000000017161437667101700214660ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/generic.go000066400000000000000000000022751437667101700223320ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/github.go000066400000000000000000000042541437667101700221770ustar00rootroot00000000000000package 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 GitHubFineGrainedPat() *config.Rule { // define rule r := config.Rule{ Description: "GitHub Fine-Grained Personal Access Token", RuleID: "github-fine-grained-pat", Regex: regexp.MustCompile(`github_pat_[0-9a-zA-Z_]{82}`), Keywords: []string{"github_pat_"}, } // validate tps := []string{ generateSampleSecret("github", "github_pat_"+secrets.NewSecret(alphaNumeric("82"))), } 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) } gitleaks-8.16.0/cmd/generate/config/rules/gitlab.go000066400000000000000000000025211437667101700221520ustar00rootroot00000000000000package rules import ( "regexp" "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" "github.com/zricethezav/gitleaks/v8/config" ) func GitlabPat() *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) } func GitlabPipelineTriggerToken() *config.Rule { // define rule r := config.Rule{ Description: "GitLab Pipeline Trigger Token", RuleID: "gitlab-ptt", Regex: regexp.MustCompile(`glptt-[0-9a-f]{40}`), Keywords: []string{"glptt-"}, } // validate tps := []string{ generateSampleSecret("gitlab", "glptt-"+secrets.NewSecret(hex("40"))), } return validate(r, tps, nil) } func GitlabRunnerRegistrationToken() *config.Rule { // define rule r := config.Rule{ Description: "GitLab Runner Registration Token", RuleID: "gitlab-rrt", Regex: regexp.MustCompile(`GR1348941[0-9a-zA-Z\-\_]{20}`), Keywords: []string{"GR1348941"}, } // validate tps := []string{ generateSampleSecret("gitlab", "GR1348941"+secrets.NewSecret(alphaNumeric("20"))), } return validate(r, tps, nil) } gitleaks-8.16.0/cmd/generate/config/rules/gitter.go000066400000000000000000000011161437667101700222050ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/gocardless.go000066400000000000000000000011401437667101700230320ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/grafana.go000066400000000000000000000031051437667101700223060ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/hashicorp.go000066400000000000000000000011671437667101700226750ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/heroku.go000066400000000000000000000007441437667101700222120ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/hubspot.go000066400000000000000000000010271437667101700223740ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/intercom.go000066400000000000000000000010701437667101700225260ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/jwt.go000066400000000000000000000024461437667101700215220ustar00rootroot00000000000000package 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}={0,2}`), 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) } gitleaks-8.16.0/cmd/generate/config/rules/kraken.go000066400000000000000000000011221437667101700221570ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/kucoin.go000066400000000000000000000017101437667101700221770ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/launchdarkly.go000066400000000000000000000011501437667101700233660ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/linear.go000066400000000000000000000016661437667101700221730ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/linkedin.go000066400000000000000000000020741437667101700225100ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/lob.go000066400000000000000000000017761437667101700214770ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/mailchimp.go000066400000000000000000000010611437667101700226510ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/mailgun.go000066400000000000000000000027431437667101700223520ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/mapbox.go000066400000000000000000000011341437667101700221750ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/mattermost.go000066400000000000000000000011141437667101700231040ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/messagebird.go000066400000000000000000000025231437667101700231770ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/netlify.go000066400000000000000000000011151437667101700223600ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/newrelic.go000066400000000000000000000031251437667101700225210ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/npm.go000066400000000000000000000010311437667101700214750ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/nytimes.go000066400000000000000000000012161437667101700224000ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/okta.go000066400000000000000000000010551437667101700216470ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/plaid.go000066400000000000000000000027521437667101700220070ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/planetscale.go000066400000000000000000000042631437667101700232100ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/postman.go000066400000000000000000000011201437667101700223630ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/prefect.go000066400000000000000000000010321437667101700223340ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/privatekey.go000066400000000000000000000012721437667101700230750ustar00rootroot00000000000000package 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( BLOCK)?----`), Keywords: []string{"-----BEGIN"}, } // validate tps := []string{`-----BEGIN PRIVATE KEY----- anything -----END PRIVATE KEY-----`, `-----BEGIN RSA PRIVATE KEY----- abcdefghijklmnopqrstuvwxyz -----END RSA PRIVATE KEY----- `, `-----BEGIN PRIVATE KEY BLOCK----- anything -----END PRIVATE KEY BLOCK-----`, } // gitleaks:allow return validate(r, tps, nil) } gitleaks-8.16.0/cmd/generate/config/rules/pulumi.go000066400000000000000000000010351437667101700222220ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/pypi.go000066400000000000000000000011251437667101700216700ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/rapidapi.go000066400000000000000000000011321437667101700224760ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/readme.go000066400000000000000000000010321437667101700221410ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/rubygems.go000066400000000000000000000010611437667101700225430ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/rule.go000066400000000000000000000055321437667101700216640ustar00rootroot00000000000000package 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}` } gitleaks-8.16.0/cmd/generate/config/rules/sendbird.go000066400000000000000000000017351437667101700225100ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/sendgrid.go000066400000000000000000000010731437667101700225100ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/sendinblue.go000066400000000000000000000011531437667101700230400ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/sentry.go000066400000000000000000000010421437667101700222310ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/shippo.go000066400000000000000000000011741437667101700222150ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/shopify.go000066400000000000000000000032771437667101700224020ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/sidekiq.go000066400000000000000000000043601437667101700223440ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/slack.go000066400000000000000000000021611437667101700220050ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/square.go000066400000000000000000000016471437667101700222200ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/squarespace.go000066400000000000000000000011141437667101700232210ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/stopwords.go000066400000000000000000000374311437667101700227640ustar00rootroot00000000000000package 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", } gitleaks-8.16.0/cmd/generate/config/rules/stripe.go000066400000000000000000000011071437667101700222150ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/sumologic.go000066400000000000000000000017351437667101700227170ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/teams.go000066400000000000000000000016741437667101700220310ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/telegram.go000066400000000000000000000032331437667101700225110ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/travisci.go000066400000000000000000000010731437667101700225350ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/trello.go000066400000000000000000000010641437667101700222120ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/twilio.go000066400000000000000000000007611437667101700222230ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/twitch.go000066400000000000000000000010531437667101700222110ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/twitter.go000066400000000000000000000044371437667101700224220ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/typeform.go000066400000000000000000000011051437667101700225520ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/vault.go000066400000000000000000000016721437667101700220510ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/yandex.go000066400000000000000000000027701437667101700222060ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/config/rules/zendesk.go000066400000000000000000000010641437667101700223540ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/cmd/generate/secrets/000077500000000000000000000000001437667101700174325ustar00rootroot00000000000000gitleaks-8.16.0/cmd/generate/secrets/regen.go000066400000000000000000000005141437667101700210610ustar00rootroot00000000000000// 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) } gitleaks-8.16.0/cmd/protect.go000066400000000000000000000055361437667101700162100ustar00rootroot00000000000000package 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") protectCmd.Flags().String("log-opts", "", "git log options") 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("") } if detector.MaxTargetMegaBytes, err = cmd.Flags().GetInt("max-target-megabytes"); 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) } } gitleaks-8.16.0/cmd/root.go000066400000000000000000000111041437667101700154770ustar00rootroot00000000000000package 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().Int("max-target-megabytes", 0, "files larger than this will be skipped") 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()) } } gitleaks-8.16.0/cmd/version.go000066400000000000000000000005311437667101700162030ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/config/000077500000000000000000000000001437667101700146725ustar00rootroot00000000000000gitleaks-8.16.0/config/allowlist.go000066400000000000000000000030041437667101700172300ustar00rootroot00000000000000package 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 // RegexTarget RegexTarget string // 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 } gitleaks-8.16.0/config/allowlist_test.go000066400000000000000000000034111437667101700202710ustar00rootroot00000000000000package 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)) } } gitleaks-8.16.0/config/config.go000066400000000000000000000144541437667101700164760ustar00rootroot00000000000000package config import ( _ "embed" "fmt" "regexp" "strings" "github.com/rs/zerolog/log" "github.com/spf13/viper" ) //go:embed gitleaks.toml var DefaultConfig string // use to keep track of how many configs we can extend // yea I know, globals bad var extendDepth int const maxExtendDepth = 2 // 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 Extend Extend Rules []struct { ID string Description string Entropy float64 SecretGroup int Regex string Keywords []string Path string Tags []string Allowlist struct { RegexTarget string Regexes []string Paths []string Commits []string StopWords []string } } Allowlist struct { RegexTarget string Regexes []string Paths []string Commits []string StopWords []string } } // 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 // used to keep sarif results consistent orderedRules []string } // 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 } 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)) } var allowlistPaths []*regexp.Regexp for _, a := range r.Allowlist.Paths { allowlistPaths = append(allowlistPaths, regexp.MustCompile(a)) } if r.Keywords == nil { r.Keywords = []string{} } else { for _, k := range r.Keywords { keywords = append(keywords, strings.ToLower(k)) } } if r.Tags == nil { r.Tags = []string{} } var configRegex *regexp.Regexp var configPathRegex *regexp.Regexp if r.Regex == "" { configRegex = nil } else { configRegex = regexp.MustCompile(r.Regex) } if r.Path == "" { configPathRegex = nil } else { configPathRegex = regexp.MustCompile(r.Path) } r := Rule{ Description: r.Description, RuleID: r.ID, Regex: configRegex, Path: configPathRegex, SecretGroup: r.SecretGroup, Entropy: r.Entropy, Tags: r.Tags, Keywords: r.Keywords, Allowlist: Allowlist{ RegexTarget: r.Allowlist.RegexTarget, Regexes: allowlistRegexes, Paths: allowlistPaths, Commits: r.Allowlist.Commits, StopWords: r.Allowlist.StopWords, }, } orderedRules = append(orderedRules, r.RuleID) 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{ RegexTarget: vc.Allowlist.RegexTarget, Regexes: allowlistRegexes, Paths: allowlistPaths, Commits: vc.Allowlist.Commits, StopWords: vc.Allowlist.StopWords, }, Keywords: keywords, orderedRules: orderedRules, } 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() } } 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]) } } return orderedRules } 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) } 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) } 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...) } } // 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...) } gitleaks-8.16.0/config/config_test.go000066400000000000000000000072561437667101700175370ustar00rootroot00000000000000package config import ( "fmt" "regexp" "testing" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) const configPath = "../testdata/config/" func TestTranslate(t *testing.T) { tests := []struct { cfgName string cfg Config wantError error }{ { 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"), }, }, }, }, }, }, { 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"}, }, }, }, }, }, { 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"), }, }, }, }, }, }, { 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{}, }, }, }, }, { cfgName: "bad_entropy_group", cfg: Config{}, wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"), }, { 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", }, }, }, }, } 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 { 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) } } gitleaks-8.16.0/config/gitleaks.toml000066400000000000000000001604021437667101700173750ustar00rootroot00000000000000# 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''', '''package-lock.json''', '''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 Fine-Grained Personal Access Token" id = "github-fine-grained-pat" regex = '''github_pat_[0-9a-zA-Z_]{82}''' keywords = [ "github_pat_", ] [[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 = "GitLab Pipeline Trigger Token" id = "gitlab-ptt" regex = '''glptt-[0-9a-f]{40}''' keywords = [ "glptt-", ] [[rules]] description = "GitLab Runner Registration Token" id = "gitlab-rrt" regex = '''GR1348941[0-9a-zA-Z\-\_]{20}''' keywords = [ "gr1348941", ] [[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}={0,2})(?:['|\"|\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( BLOCK)?----''' 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", ] gitleaks-8.16.0/config/rule.go000066400000000000000000000022301437667101700161650ustar00rootroot00000000000000package 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 } gitleaks-8.16.0/config/utils.go000066400000000000000000000005221437667101700163600ustar00rootroot00000000000000package 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 } gitleaks-8.16.0/detect/000077500000000000000000000000001437667101700146755ustar00rootroot00000000000000gitleaks-8.16.0/detect/baseline.go000066400000000000000000000034161437667101700170120ustar00rootroot00000000000000package 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 } gitleaks-8.16.0/detect/baseline_test.go000066400000000000000000000051111437667101700200430ustar00rootroot00000000000000package 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)) } } gitleaks-8.16.0/detect/detect.go000066400000000000000000000404161437667101700165010ustar00rootroot00000000000000package detect import ( "bufio" "context" "fmt" "io" "io/fs" "os" "path/filepath" "regexp" "strings" "sync" "github.com/h2non/filetype" "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" 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 // files larger than this will be skipped MaxTargetMegaBytes int // followSymlinks is a flag to enable scanning symlink files FollowSymlinks 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 SymlinkFile 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, source string) error { if baselinePath != "" { absoluteSource, err := filepath.Abs(source) if err != nil { return err } absoluteBaseline, err := filepath.Abs(baselinePath) if err != nil { return err } relativeBaseline, err := filepath.Rel(absoluteSource, absoluteBaseline) if err != nil { return err } baseline, err := LoadBaseline(baselinePath) if err != nil { return err } d.baseline = baseline baselinePath = relativeBaseline } 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, SymlinkFile: fragment.SymlinkFile, 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 } // If flag configure and raw data size bigger then the flag if d.MaxTargetMegaBytes > 0 { rawLength := len(fragment.Raw) / 1000000 if rawLength > d.MaxTargetMegaBytes { log.Debug().Msgf("skipping file: %s scan due to size: %d", fragment.FilePath, rawLength) 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, SymlinkFile: fragment.SymlinkFile, 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 regexTarget is defined in the allowlist "regexes" entry allowlistTarget := finding.Secret switch rule.Allowlist.RegexTarget { case "match": allowlistTarget = finding.Match case "line": allowlistTarget = finding.Line } globalAllowlistTarget := finding.Secret switch d.Config.Allowlist.RegexTarget { case "match": globalAllowlistTarget = finding.Match case "line": globalAllowlistTarget = finding.Line } if rule.Allowlist.RegexAllowed(allowlistTarget) || d.Config.Allowlist.RegexAllowed(globalAllowlistTarget) { 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 } type scanTarget struct { Path string Symlink string } // 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 scanTarget) 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 <- scanTarget{ Path: path, Symlink: "", } } if fInfo.Mode().Type() == fs.ModeSymlink && d.FollowSymlinks { realPath, err := filepath.EvalSymlinks(path) if err != nil { return err } realPathFileInfo, _ := os.Stat(realPath) if realPathFileInfo.IsDir() { log.Debug().Msgf("found symlinked directory: %s -> %s [skipping]", path, realPath) return nil } paths <- scanTarget{ Path: realPath, Symlink: path, } } return nil }) }) for pa := range paths { p := pa s.Go(func() error { b, err := os.ReadFile(p.Path) 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.Path, } if p.Symlink != "" { fragment.SymlinkFile = p.Symlink } 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 } // DetectReader accepts an io.Reader and a buffer size for the reader in KB func (d *Detector) DetectReader(r io.Reader, bufSize int) ([]report.Finding, error) { reader := bufio.NewReader(r) buf := make([]byte, 0, 1000*bufSize) findings := []report.Finding{} for { n, err := reader.Read(buf[:cap(buf)]) buf = buf[:n] if err != nil { if err != io.EOF { return findings, err } break } fragment := Fragment{ Raw: string(buf), } for _, finding := range d.Detect(fragment) { findings = append(findings, finding) if d.Verbose { printFinding(finding) } } } return 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 } gitleaks-8.16.0/detect/detect_test.go000066400000000000000000000434661437667101700175500ustar00rootroot00000000000000package 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 baselinePath string fragment Fragment // NOTE: for expected findings, all line numbers will be 0 // because line deltas are added _after_ the finding is created. // I.e, if the finding is from a --no-git file, the line number will be // increase by 1 in DetectFromFiles(). If the finding is from git, // the line number will be increased by the patch delta. 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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: 0, EndLine: 0, 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{}, }, { cfgName: "path_only", baselinePath: ".baseline.json", fragment: Fragment{ Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, FilePath: ".baseline.json", }, 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) d.baselinePath = tt.baselinePath 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) } } // TestFromFiles tests the FromFiles 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", SymlinkFile: "", 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) detector.FollowSymlinks = true findings, err := detector.DetectFiles(tt.source) if err != nil { t.Error(err) } assert.ElementsMatch(t, tt.expectedFindings, findings) } } func TestDetectWithSymlinks(t *testing.T) { tests := []struct { cfgName string source string expectedFindings []report.Finding }{ { source: filepath.Join(repoBasePath, "symlinks/file_symlink"), cfgName: "simple", expectedFindings: []report.Finding{ { Description: "Asymmetric Private Key", StartLine: 1, EndLine: 1, StartColumn: 1, EndColumn: 35, Match: "-----BEGIN OPENSSH PRIVATE KEY-----", Secret: "-----BEGIN OPENSSH PRIVATE KEY-----", Line: "-----BEGIN OPENSSH PRIVATE KEY-----", File: "../testdata/repos/symlinks/source_file/id_ed25519", SymlinkFile: "../testdata/repos/symlinks/file_symlink/symlinked_id_ed25519", RuleID: "apkey", Tags: []string{"key", "AsymmetricPrivateKey"}, Entropy: 3.587164, Fingerprint: "../testdata/repos/symlinks/source_file/id_ed25519:apkey:1", }, }, }, } 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) detector.FollowSymlinks = true 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 } gitleaks-8.16.0/detect/git/000077500000000000000000000000001437667101700154605ustar00rootroot00000000000000gitleaks-8.16.0/detect/git/git.go000066400000000000000000000065761437667101700166100ustar00rootroot00000000000000package 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 } } } gitleaks-8.16.0/detect/git/git_test.go000066400000000000000000000077701437667101700176440ustar00rootroot00000000000000package 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 // } gitleaks-8.16.0/detect/location.go000066400000000000000000000040421437667101700170340ustar00rootroot00000000000000package 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 // Fixes: https://github.com/zricethezav/gitleaks/issues/1037 // When a fragment does NOT have any newlines, a default "newline" // will be counted to make the subsequent location calculation logic work // for fragments will no newlines. if len(fragment.newlineIndices) == 0 { fragment.newlineIndices = [][]int{ {len(fragment.Raw), len(fragment.Raw) + 1}, } } 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 } gitleaks-8.16.0/detect/location_test.go000066400000000000000000000023131437667101700200720ustar00rootroot00000000000000package 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) } } } gitleaks-8.16.0/detect/utils.go000066400000000000000000000116431437667101700163710ustar00rootroot00000000000000package 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) skipColor := false if matchInLineIDX == -1 { skipColor = true matchInLineIDX = 0 } 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) if skipColor { fmt.Printf("%-12s %s\n", "Finding:", f.Match) } else { 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) if f.File == "" { fmt.Println("") return } 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 } gitleaks-8.16.0/go.mod000066400000000000000000000034121437667101700145330ustar00rootroot00000000000000module github.com/zricethezav/gitleaks/v8 go 1.19 require ( 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 ) gitleaks-8.16.0/go.sum000066400000000000000000001721601437667101700145670ustar00rootroot00000000000000cloud.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= 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/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/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.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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.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-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/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/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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 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/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-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-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-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-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-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-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.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/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.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-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.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= gitleaks-8.16.0/main.go000066400000000000000000000011431437667101700146770ustar00rootroot00000000000000package main import ( "os" "os/signal" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/zricethezav/gitleaks/v8/cmd" ) func main() { // send all logs to stdout log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) // 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) cmd.Execute() } func listenForInterrupt(stopScan chan os.Signal) { <-stopScan log.Fatal().Msg("Interrupt signal received. Exiting...") } gitleaks-8.16.0/report/000077500000000000000000000000001437667101700147405ustar00rootroot00000000000000gitleaks-8.16.0/report/constants.go000066400000000000000000000001031437667101700172750ustar00rootroot00000000000000package report const version = "v8.0.0" const driver = "gitleaks" gitleaks-8.16.0/report/csv.go000066400000000000000000000016011437667101700160600ustar00rootroot00000000000000package 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", "SymlinkFile", "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.SymlinkFile, 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() } gitleaks-8.16.0/report/csv_test.go000066400000000000000000000035601437667101700171250ustar00rootroot00000000000000package 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", SymlinkFile: "", 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()) } } gitleaks-8.16.0/report/finding.go000066400000000000000000000017411437667101700167100ustar00rootroot00000000000000package 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 SymlinkFile 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" } gitleaks-8.16.0/report/finding_test.go000066400000000000000000000006571437667101700177540ustar00rootroot00000000000000package 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) } } } } gitleaks-8.16.0/report/json.go000066400000000000000000000004031437667101700162350ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/report/json_test.go000066400000000000000000000036511437667101700173040ustar00rootroot00000000000000package 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", SymlinkFile: "", 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()) } } gitleaks-8.16.0/report/report.go000066400000000000000000000011641437667101700166040ustar00rootroot00000000000000package 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 } gitleaks-8.16.0/report/report_test.go000066400000000000000000000032371437667101700176460ustar00rootroot00000000000000package 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 } } } gitleaks-8.16.0/report/sarif.go000066400000000000000000000110611437667101700163720ustar00rootroot00000000000000package 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 { uri := f.File if f.SymlinkFile != "" { uri = f.SymlinkFile } return []Locations{ { PhysicalLocation: PhysicalLocation{ ArtifactLocation: ArtifactLocation{ URI: uri, }, 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"` } gitleaks-8.16.0/report/sarif_test.go000066400000000000000000000044751437667101700174440ustar00rootroot00000000000000package 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()) } } gitleaks-8.16.0/scripts/000077500000000000000000000000001437667101700151145ustar00rootroot00000000000000gitleaks-8.16.0/scripts/pre-commit.py000066400000000000000000000014011437667101700175360ustar00rootroot00000000000000#!/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`)') gitleaks-8.16.0/testdata/000077500000000000000000000000001437667101700152365ustar00rootroot00000000000000gitleaks-8.16.0/testdata/baseline/000077500000000000000000000000001437667101700170205ustar00rootroot00000000000000gitleaks-8.16.0/testdata/baseline/baseline.csv000066400000000000000000000002131437667101700213130ustar00rootroot00000000000000RuleID,Commit,File,Secret,Match,StartLine,EndLine,StartColumn,EndColumn,Author,Message,Date,Email,Fingerprint 1,b,c,f,s,m,s,e,s,e,a,m,f,r,fgitleaks-8.16.0/testdata/baseline/baseline.json000066400000000000000000000025071437667101700215010ustar00rootroot00000000000000[ { "Description": "PyPI upload token", "StartLine": 32, "EndLine": 32, "StartColumn": 21, "EndColumn": 106, "Match": "************************", "Secret": "************************", "File": "detect/detect_test.go", "Commit": "9326f35380636bcbe61e94b0584d1618c4b5c2c2", "Entropy": 1.9606875, "Author": "****", "Email": "****", "Date": "2022-03-07T14:33:06Z", "Message": "Escape - character in regex character groups (#802)\n\n* fix char escape\n\n* add test\n\n* fix verbosity in make test", "Tags": [], "RuleID": "pypi-upload-token", "Fingerprint": "9326f35380636bcbe61e94b0584d1618c4b5c2c2:detect/detect_test.go:pypi-upload-token:32" }, { "Description": "PyPI upload token", "StartLine": 33, "EndLine": 33, "StartColumn": 21, "EndColumn": 106, "Match": "************************", "Secret": "************************", "File": "detect/detect_test.go", "Commit": "9326f35380636bcbe61e94b0584d1618c4b5c2c2", "Entropy": 1.9606875, "Author": "****", "Email": "****", "Date": "2022-03-07T14:33:06Z", "Message": "Escape - character in regex character groups (#802)\n\n* fix char escape\n\n* add test\n\n* fix verbosity in make test", "Tags": [], "RuleID": "pypi-upload-token", "Fingerprint": "9326f35380636bcbe61e94b0584d1618c4b5c2c2:detect/detect_test.go:pypi-upload-token:33" } ] gitleaks-8.16.0/testdata/baseline/baseline.sarif000066400000000000000000000002001437667101700216200ustar00rootroot00000000000000{ "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", "version": "2.1.0", "runs": [ ] } gitleaks-8.16.0/testdata/config/000077500000000000000000000000001437667101700165035ustar00rootroot00000000000000gitleaks-8.16.0/testdata/config/allow_aws_re.toml000066400000000000000000000004521437667101700220570ustar00rootroot00000000000000title = "simple config with allowlist for aws" [[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.allowlist] regexes = ['''AKIALALEMEL33243OLIA'''] gitleaks-8.16.0/testdata/config/allow_commit.toml000066400000000000000000000004631437667101700220710ustar00rootroot00000000000000title = "simple config with allowlist for a specific commit" [[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.allowlist] commits = ['''allowthiscommit'''] gitleaks-8.16.0/testdata/config/allow_global_aws_re.toml000066400000000000000000000003551437667101700234010ustar00rootroot00000000000000[[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"] [allowlist] regexes = ['''AKIALALEMEL33243OLIA'''] gitleaks-8.16.0/testdata/config/allow_path.toml000066400000000000000000000004351437667101700215340ustar00rootroot00000000000000title = "simple config with allowlist for .go files" [[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.allowlist] paths = ['''.go'''] gitleaks-8.16.0/testdata/config/bad_entropy_group.toml000077500000000000000000000003361437667101700231270ustar00rootroot00000000000000title = "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 = 5 entropy = 3.5 gitleaks-8.16.0/testdata/config/base.toml000066400000000000000000000003541437667101700203140ustar00rootroot00000000000000title = "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"] gitleaks-8.16.0/testdata/config/entropy_group.toml000077500000000000000000000003361437667101700223210ustar00rootroot00000000000000title = "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 gitleaks-8.16.0/testdata/config/escaped_character_group.toml000066400000000000000000000003751437667101700242410ustar00rootroot00000000000000title = "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"]gitleaks-8.16.0/testdata/config/extend_1.toml000066400000000000000000000004061437667101700211070ustar00rootroot00000000000000title = "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"] gitleaks-8.16.0/testdata/config/extend_2.toml000066400000000000000000000003661437667101700211150ustar00rootroot00000000000000title = "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"] gitleaks-8.16.0/testdata/config/extend_3.toml000066400000000000000000000004311437667101700211070ustar00rootroot00000000000000title = "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"] gitleaks-8.16.0/testdata/config/generic.toml000066400000000000000000000003771437667101700210230ustar00rootroot00000000000000title = "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 gitleaks-8.16.0/testdata/config/generic_with_py_path.toml000066400000000000000000000013441437667101700235750ustar00rootroot00000000000000title = "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)$''' ] gitleaks-8.16.0/testdata/config/path_only.toml000066400000000000000000000001541437667101700213750ustar00rootroot00000000000000title = "gitleaks config" [[rules]] description = "Python Files" id = "python-files-only" path = '''.py''' gitleaks-8.16.0/testdata/config/simple.toml000066400000000000000000000142671437667101700207030ustar00rootroot00000000000000title = "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"] gitleaks-8.16.0/testdata/expected/000077500000000000000000000000001437667101700170375ustar00rootroot00000000000000gitleaks-8.16.0/testdata/expected/git/000077500000000000000000000000001437667101700176225ustar00rootroot00000000000000gitleaks-8.16.0/testdata/expected/git/small-branch-foo.txt000066400000000000000000000003301437667101700235030ustar00rootroot00000000000000import ( "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) } gitleaks-8.16.0/testdata/expected/git/small.txt000066400000000000000000000016131437667101700214740ustar00rootroot00000000000000import ( "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 gitleaks-8.16.0/testdata/expected/report/000077500000000000000000000000001437667101700203525ustar00rootroot00000000000000gitleaks-8.16.0/testdata/expected/report/csv_simple.csv000066400000000000000000000003751437667101700232400ustar00rootroot00000000000000RuleID,Commit,File,SymlinkFile,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 gitleaks-8.16.0/testdata/expected/report/empty.json000066400000000000000000000000031437667101700223740ustar00rootroot00000000000000[] gitleaks-8.16.0/testdata/expected/report/json_simple.json000066400000000000000000000006361437667101700235740ustar00rootroot00000000000000[ { "Description": "", "StartLine": 1, "EndLine": 2, "StartColumn": 1, "EndColumn": 2, "Match": "line containing secret", "Secret": "a secret", "File": "auth.py", "SymlinkFile": "", "Commit": "0000000000000000", "Entropy": 0, "Author": "John Doe", "Email": "johndoe@gmail.com", "Date": "10-19-2003", "Message": "opps", "Tags": [], "RuleID": "test-rule", "Fingerprint": "" } ] gitleaks-8.16.0/testdata/expected/report/sarif_simple.sarif000066400000000000000000000171131437667101700240600ustar00rootroot00000000000000{ "$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" } } ] } ] } gitleaks-8.16.0/testdata/repos/000077500000000000000000000000001437667101700163665ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/nogit/000077500000000000000000000000001437667101700175065ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/nogit/main.go000066400000000000000000000004351437667101700207630ustar00rootroot00000000000000package 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) } gitleaks-8.16.0/testdata/repos/small/000077500000000000000000000000001437667101700174765ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/README.md000066400000000000000000000000601437667101700207510ustar00rootroot00000000000000# test This is a repo used for testing gitleaks gitleaks-8.16.0/testdata/repos/small/api/000077500000000000000000000000001437667101700202475ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/api/api.go000066400000000000000000000001071437667101700213450ustar00rootroot00000000000000package api import "fmt" func PrintHello() { fmt.Println("hello") } gitleaks-8.16.0/testdata/repos/small/dotGit/000077500000000000000000000000001437667101700207305ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/COMMIT_EDITMSG000066400000000000000000000000411437667101700230120ustar00rootroot00000000000000removing secret from foo package gitleaks-8.16.0/testdata/repos/small/dotGit/FETCH_HEAD000066400000000000000000000001241437667101700222620ustar00rootroot000000000000002e1db472eeba53f06c4026ae4566ea022e36598e branch 'main' of github.com:gitleaks/test gitleaks-8.16.0/testdata/repos/small/dotGit/HEAD000066400000000000000000000000251437667101700213510ustar00rootroot00000000000000ref: refs/heads/main gitleaks-8.16.0/testdata/repos/small/dotGit/ORIG_HEAD000066400000000000000000000000511437667101700221700ustar00rootroot000000000000001b6da43b82b22e4eaa10bcf8ee591e91abbfc587 gitleaks-8.16.0/testdata/repos/small/dotGit/config000066400000000000000000000004521437667101700221210ustar00rootroot00000000000000[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = git@github.com:gitleaks/test.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "main"] remote = origin merge = refs/heads/main gitleaks-8.16.0/testdata/repos/small/dotGit/description000066400000000000000000000001111437667101700231670ustar00rootroot00000000000000Unnamed repository; edit this file 'description' to name the repository. gitleaks-8.16.0/testdata/repos/small/dotGit/index000066400000000000000000000004751437667101700217700ustar00rootroot00000000000000DIRCb%p![b%p![D0\ɺΫUC (>Ag README.mdb%p!b%p!DG2Gk ~|7Α1a api/api.goawJaH+T.7dGYɲGmain.goTREE53 1 ~O)~S api1 0 \T~BYL95jA@fqǧ1gitleaks-8.16.0/testdata/repos/small/dotGit/info/000077500000000000000000000000001437667101700216635ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/info/exclude000066400000000000000000000003601437667101700232360ustar00rootroot00000000000000# 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] # *~ gitleaks-8.16.0/testdata/repos/small/dotGit/logs/000077500000000000000000000000001437667101700216745ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/logs/HEAD000066400000000000000000000042331437667101700223220ustar00rootroot000000000000000000000000000000000000000000000000000000 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 gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/000077500000000000000000000000001437667101700226335ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/heads/000077500000000000000000000000001437667101700237175ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/heads/api-pkg000066400000000000000000000002371437667101700251740ustar00rootroot000000000000000000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896543 -0500 branch: Created from HEAD gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/heads/foo000066400000000000000000000007711437667101700244320ustar00rootroot000000000000000000000000000000000000000000000000000000 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 gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/heads/main000066400000000000000000000005221437667101700245650ustar00rootroot000000000000000000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: Fast-forward gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets000066400000000000000000000007401437667101700266060ustar00rootroot000000000000000000000000000000000000000000000000000000 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 gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/000077500000000000000000000000001437667101700243115ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/origin/000077500000000000000000000000001437667101700256005ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD000066400000000000000000000002561437667101700262270ustar00rootroot000000000000000000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg000066400000000000000000000002241437667101700270510ustar00rootroot000000000000000000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896552 -0500 update by push gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo000066400000000000000000000002241437667101700263040ustar00rootroot000000000000000000000000000000000000000000000000000000 f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896935 -0500 update by push gitleaks-8.16.0/testdata/repos/small/dotGit/logs/refs/remotes/origin/main000066400000000000000000000002441437667101700264470ustar00rootroot000000000000001b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: fast-forward gitleaks-8.16.0/testdata/repos/small/dotGit/objects/000077500000000000000000000000001437667101700223615ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/02/000077500000000000000000000000001437667101700226025ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760000066400000000000000000000002171437667101700276460ustar00rootroot00000000000000xU1 0`ܯ8nJ.:*(8\ɕ$ w3 Nox{$6f1~wF'0YbF TBpND|*]uCST kL>a#(Jm(sԴ]=>03gitleaks-8.16.0/testdata/repos/small/dotGit/objects/15/000077500000000000000000000000001437667101700226065ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738000066400000000000000000000001261437667101700274420ustar00rootroot00000000000000x+)JMU07b040031QrutuMa9M VpѸo瘾(713O/=ad=W+lEM'Nl gitleaks-8.16.0/testdata/repos/small/dotGit/objects/2e/000077500000000000000000000000001437667101700226675ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/2e/1db472eeba53f06c4026ae4566ea022e36598e000066400000000000000000000011521437667101700300120ustar00rootroot00000000000000xuOo@{SԣRRlL `` ӗꭝh~z3u݄_zN)):e N3ji#$LPЄqz큄 )26 *!IoDM äjH20YPa*d*’i@4E"8my77߁ɪajh'QEarۀᴭ׼g-o[_e; A칁o.7ؖe,+mX^̽ѲY>U+$v׋]"vt]2[bI݄wnԨEG]->z uqjl]vV4>jNJ+Γϣbӹϩs߂1lti*RwS(+wB w˴4,;^L+=\Wo~rNb}rBc=M28 6;T9]՘ul=.bЍr4"=Rӓ4YƼr\EASSU8zW 0`m`e"rA9 dtgitleaks-8.16.0/testdata/repos/small/dotGit/objects/49/000077500000000000000000000000001437667101700226155ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/49/1504d5a31946ce75e22554cc34203d8e5ff3ca000066400000000000000000000002571437667101700276640ustar00rootroot00000000000000xAj0{+ 뵴!֫U,R[FQ(zV:oD)e(gI iwH mHl0fdH, !Kt[Qv]V{7)' <9<3c@t=+vRkC!wWx6NOgitleaks-8.16.0/testdata/repos/small/dotGit/objects/5c/000077500000000000000000000000001437667101700226705ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112000066400000000000000000000000631437667101700276600ustar00rootroot00000000000000x+)JMU06a040031QH,Kga>QNs;5&i gitleaks-8.16.0/testdata/repos/small/dotGit/objects/78/000077500000000000000000000000001437667101700226175ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/78/9ba677976d5db481de55c799d67acbf8e3f16a000066400000000000000000000000631437667101700301540ustar00rootroot00000000000000x+)JMU06a040031QHKg`c|* hcIgitleaks-8.16.0/testdata/repos/small/dotGit/objects/90/000077500000000000000000000000001437667101700226115ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73000066400000000000000000000002521437667101700276260ustar00rootroot00000000000000xM 0F]s%t "I2E۔ >x_2w@;z㑈ءCX@6 5)M&F:l'FTHďFF1iPSm4cNo;ݷV{]ߗT`=aZw d}fuKKgitleaks-8.16.0/testdata/repos/small/dotGit/objects/9a/000077500000000000000000000000001437667101700226725ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad000066400000000000000000000003041437667101700302700ustar00rootroot00000000000000x]1 0]{BQAPAQUBӤ7)8}{\Lz5lؒuC$ L/ 87@4EIR^J픎WFHDyub67}Ԩ~Ȕq`*C\Zv8HBDꯦaM?߳q,z:"@u>Tgitleaks-8.16.0/testdata/repos/small/dotGit/objects/a1/000077500000000000000000000000001437667101700226625ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab000066400000000000000000000002431437667101700302120ustar00rootroot00000000000000xA = ,:܉pY;umu}\17kv/+VT 6FϭIgitleaks-8.16.0/testdata/repos/small/dotGit/objects/a5/000077500000000000000000000000001437667101700226665ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5000066400000000000000000000002061437667101700302540ustar00rootroot00000000000000xU 0]fh\2T(HZ)mJ ڑ[ܩf`=3@&3;0 V}c,hI\Hw +=2.錤ZmkeԚG@,gitleaks-8.16.0/testdata/repos/small/dotGit/objects/a9/000077500000000000000000000000001437667101700226725ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a000066400000000000000000000002171437667101700301000ustar00rootroot00000000000000x+)JMU046b040031QrutuMa9M VpѸo瘾 2bBDoFXW,G!lZ~>-5-7댎6 x7LtٶUԂ<|Y_a'78(7gitleaks-8.16.0/testdata/repos/small/dotGit/objects/bc/000077500000000000000000000000001437667101700227455ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886000066400000000000000000000001641437667101700305060ustar00rootroot00000000000000x+)JMU040b040031QrutuMa9M VpѸo瘾 2bBDoFXW,G!yz &뙿Z;eCesc4 =>Z?fA-MKg5Y)?}yrӉkw:gitleaks-8.16.0/testdata/repos/small/dotGit/objects/f1/000077500000000000000000000000001437667101700226675ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/f1/b58b97808f8e744f6a23c693859df5b5968901000066400000000000000000000002601437667101700275760ustar00rootroot00000000000000xIj1s+1Z 7[eY!ϼ!b}c~CٖX)!cIBגn\αٶdNf!ۄXڸ Wcb(#F Kl-0zͻ"eeq`SNKKM58xh98_gn2 Ta'~MPdgitleaks-8.16.0/testdata/repos/small/dotGit/objects/pack/000077500000000000000000000000001437667101700232775ustar00rootroot00000000000000pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.idx000066400000000000000000000024541437667101700324310ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/packtOc cI&z &v^ԾGM$̔^\+m;.NYŇ6KI0;/ej H9]nUTLeUo%R\ɺΫUC (>Ag!IB.uﯻA`HA^ `-z;0ycuD%ǻ_. *.cwh#.Ϻ[E޶ B9n9տP 2U,)vGhЂu̍Ibآ􆃎Oץn,pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.pack000066400000000000000000000041041437667101700325550ustar00rootroot00000000000000gitleaks-8.16.0/testdata/repos/small/dotGit/objects/packPACK ,xuK0 W[0/i*NH!(Y뛶v.39DH2 +RI4#J!B3&VUg'!ARE͔Ak&L@4 pF$2HhIe]ېF;fZbjJOTB0V2vGQrS+b [Y>حv`|;:. \GLmm8X{FyFۋݫmµZzKiCl#'ܦno;D#7k}=8x\ÆC̣Ȭ򡿤~BI%nXH7sſlJ?Rw@02ʙ!+xuRˎ@s+H LB!i{m}d>f-HƼ$|$Q0T4]$DUE54橐 ^T!Lx>DXPEar4D^ٵnAH+iGc ާEg֬Ju -U ޠ!R˜1;g>U>~f9lYuy~C3mgޱ73b !MGhm,fG}&utz05qP//ghg1}THFTo' ?RgS9#g^m(;H-fbR(x]տYG(xuR]o@|W@^ *x[a)(.(z<$L2 gEl "O$D1$tʎFH(. ${LKl m~7"Y u@Bm)[^Vt󽤼e]xl-G r4-4C+\Te'6ZU+4qM< |X% ^\{YZOZ3Ըqf}ieF{*}`+ҕR*pRΧl+H=V,4qFzlҵdc^n%RY4yNq ײCwiƃ癱Pړ6:Z{HQXQ >n%S +oxfg=/G)XrXd'&]T𳙳{1?SNI~*t|x340031QrutuMa9M VpѸo瘾(713O/=G쎼B|RJw=W xSV(I-. ,VDԂ|"df^BzfINjbv1D͵xeϿ0O$?d@ 0PRt0Сw,Uw1ZFyȺRz0U,@8r ^S#cQ9*8