From 6ea64f5603a9073b6042499d75d16ab13c4850a2 Mon Sep 17 00:00:00 2001 From: goodgary Date: Sat, 8 Oct 2022 14:37:23 -0700 Subject: [PATCH] rebase (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(Dockerfile): Fix example of usage on Dockerfile (#545) * Closes #544 Co-authored-by: mercuriete * Pypi GitHub rules (#546) * adding pypi and basic azure rules * Adding new github format * splitting out github rules and retabbing * Update README.md * Update README.md * Docker-based pre-commit configuration example (#551) * Docker-based pre-commit configuration example * Docker-based pre-commit configuration example * Bug 553 global allowlist (#554) * add global file check * rm whitespace * Add pre-commit support (#552) * Add pre-commit support * Update README.md * Removed unnecessary backslashes * Include `offenderEntropy` in the JSON output (#549) * Pass the entropy data back to the Leak struct Do this to make it easier to tune entropy checks and make decisions in systems consuming the output. ~ B'ezrat Hashem ~ * Return negative number when entropy not checked That way you can tell the difference between not checking or an actual entropy level of 0 ~ B'ezrat Hashem ~ * Make sure to handle range checks properly Make sure to show when something had an entropy returned but was outside range, or didn't have a hit at all, etc... ~ B'zrat Hashem ~ * Add a few doc strings Follow the project's conventiona add a comment above the methods ~ B'ezrat Hashem ~ * Update tests and get them to pass ~ B'ezrat Hashem ~ * Remove checked in `.got` files ~ B'ezrat Hashem ~ * Add `*.got` to the `.gitignore` Make sure the test output files aren't checked-in ~ B'ezrat Hashem ~ * Bump version for pre-commit * Update README.md * SSH auth: Add custom username support (#536) * Add support for custom username when using SSH auth Previously, the user "git" was hard-coded This commit also adds support for ssh:// URLs * Add comment to explain username parsing * Fix example in leaky-repo.toml (#559) Signed-off-by: Norman Ziegner * Fix issue #523 (#561) * updating documentation regarding issue #523 * improving README.md file * Update README.md * Update README.md * Update type in config example (#597) * Remove --commit-from and --commit-to from docs (#605) * fix(git-symlink-commits): fix handling symbolic links in a git repository * Fix default twitter rules (#614) Regexps for default Twitter rules ("Twitter Secret Key" and "Twitter Client ID") have a small flaw that make the default configuration vulnerable to some false-positives. I believe these rules should detect the cases like (SOME_CLIENT_ID should be longer): ``` "twitter_client_id": "SOME_CLIENT_ID" ``` However, currently the twitter rules also detect the false positives for the cases like: ``` someObj := twitter.NewObjectWithALongName() config.Twitter.DomainAccessToken ``` I'm trying to address this issue the similar way it's done for facebook client ids and AWS secret keys, where the secret is expected to be quoted. * Updated RuleId in Sarif (#613) * fix(git-symlink-commits): fix handling symbolic links in a git repository (#612) * Update alpine, use gitleaks user instead of root (#615) * Updating alpine, use gitleaks user instead of root * remove comments * use embed pkg for default config, update deps (#616) * bump golang docker version * GitHub test (#617) * drop travis * remove travis * rename, use example * typo * different syntax * rename to test * split test and build into two jobs * add gosec job * drop gosec for now * Create maintenance.md * Fix premature exit for nogit scans, limit goroutines (#619) * fix premature exit on nogit scan, actually limit concurreny for nogit * removing files scanned log * fix(git-symlink-files): fix handling symbolic links in unstaged changes * Update README.md * No longer generate empty reports (#577) * return nil when no leaks found and lowercase report format option (#3) * lowercase format options for consistency * lowercase report format description Co-authored-by: eddie-northcutt-wfp0 * Update FUNDING.yml * update documentation * Create README.md * Fix README link Fix up readme link * Added a test for fixed Google and Square config * Simplify tests and continue on object not found errors (#633) * adding files * init better tests * add basic .git * more tests and test data * nogit, unstaged tests * removing unused testdata * adding empty testdata * rm gitmodules * fixing tests * remove with config * adding with_config * removing old test_data, updating config tests * removing hooks in testdata repos * Fixed typo in Readme.md Fixed description of main example rule * fix: fix the multiple scan executions from pre-commit hook (#649) Co-authored-by: dustin * Add clarification in README.md that Go 1.16+ required. (#651) * fix: fix the multiple scan executions from pre-commit hook * docs: add clarification note about Go version required\ Ref 646 Co-authored-by: dustin * updating documentation on how to build the docker image * Bump alpine to v3.14.2 This alpine release includes fixes for openssl CVE-2021-3711 and CVE-2021-3712 * update readme * build: add apple m1 support Signed-off-by: Rui Chen * Fixed bug in extractLine function which was returning incorrect line # when the line contains multiple vuln types * chore: lint code * Added EOL to sample file * Try to revert index file * Made changes to add support for cross-platform (os) testing as tests would pass on MacOS but no Windows * Had to re-add testdata/ folder to project in order to get scan tests passing on Windows * Fix for Windows OS * ADD_installation_from_bin ADD_installation_from_bin * fix: typo in readme * Update README.md * Update regex for AWS secret key * Fix tests with existing AWS secret keys * Adjust AWS secret key rule * fix possible typo in README.md * Introducing v8.0.0 changes (#701) * Introducing v8.0.0 changes * hardcode username to avoid redaction in action * actually use github.actor * remove git fetch tag from docker build process, already available * remove sorting tags * actually we gonna use git describe for docker build * override version in goreleaser * trying again * Update README.md * Update README.md * removing --simplify-merges and --show-pulls (#707) * remove --show-pulls from git log * adding logic to ignore gitleaks config during scans (#710) * Update sarif.go (#713) * Update sarif.go Provide correct version information for Sarif Reports * Update test Set version to correct Sarif version * Commit debug log (#716) * adding debug log for number of commits scanned * change debug text * readd commitsha * add global regex check (#717) * remove generic api key from default gitleaks config (#719) * Update README.md * use exit code 126 on 'unknown-flag' errors (#723) * Update README.md * lil hack to avoid scans 'finishing' when git errors are present (#726) * Update README.md * Update README.md * bump go-gitdiff (#731) * fix typo in config help * fix typo in readme * introducing secretGroup, the best group (#734) * working on deduping * my eyes... oh god my poor eyes * more readme * more readme * more readme * more readme and formatting * fix: format dates in log in a portable way (#735) The output of time.String() depends on the runtime environment and should only be used for debugging. This commit ensures that a well-defined UTC time is written to the report. * Update pre-commit step to run gitleaks checks (#729) * Fix pre-commit config. * Debug output * No debug and use redacted. * Typo * Add back staged. * Update .pre-commit-hooks.yaml * Update .pre-commit-hooks.yaml * ignore gitleaks.toml by default * fix deduplication issue caused by clobbered findings (#742) * fix deduplication issue caused by clobbered findings * fix index * remove indexing, slow is better than wrong * fix off by one line number for --no-git * remove writing default config, introduce GITLEAKS_CONFIG (#746) * remove writing default config, introduce GITLEAKS_CONFIG * setting report format default to json, update readme * add pre-commit instructions (#749) * do not fail on git rename warning (#750) * bump go-gitdiff * Update README.md * Update README.md * better asciinema * Update README.md * fix regexp for aws_key and slack_webhook (#754) * Adding Tines sponsorship to readme * fixing eof location bug (#756) * stricter ionic regex for less fps (#757) * write a report regardless if leaks are present (#758) * Adding Typeform to sponsorships * limit goroutines on file scanning to avoid pegging them cores (#759) * always write sarif results * limit number of goroutines for historic scanning as well (#761) * remove godoc text filtering (#763) * Fix typos in README.md (#780) comand ==> command awsome ==> awesome precendence ==> precedence * Sarif results with empty rules now represents as [] instead of null/nil (#786) * Fix vendor name casing, Flutterwave typo (#785) * Fix: Typo in LinkedIn id (#789) * fixing segfault when using a rule with only a path (#791) * fixing segfault when using a rule with only a path * DRYing * allow non-last-element secret groups (#792) * build: updates for go1.17 (#769) * build: remove `GO111MODULE` as it turned on by default Signed-off-by: Rui Chen * build: update for go1.17 * run test Signed-off-by: Rui Chen * lint: remove unused code * ignore k8s apiVersion in generic-api-key pattern (#760) * GitLab pats may contain underscores as well as dashes (#794) * gitlab pats may contain underscores as well as dashes * include testdata index binary Co-authored-by: Greg Johnson (codeEmitter) * adding go mod/sum to ignore (#797) * Escape - character in regex character groups (#802) * fix char escape * add test * fix verbosity in make test * Refactor `detect`, add `entropy` to all findings (#804) Refactor `detect`, add `entropy` to all findings * Stop words (#808) * use regex for stopwords * fix up regex * rm stopwords * Allow tag (#809) * gitleaks:allow signature * readd all tests * fixing tests * Update README.md * fixing a location off by one edge case for --no-git (#812) * detect: skip binary files with --no-git (#810) * remove stopwords from global allowlist * use official docker image as pre-commit hook (#818) * use official docker image as pre-commit hook * Update .pre-commit-hooks.yaml * Update .pre-commit-hooks.yaml * Update .pre-commit-hooks.yaml * Update .pre-commit-hooks.yaml * Update .pre-commit-hooks.yaml * skip content checks for path only rules * doc gitleaks-docker pre-commit hook (#819) relates to #818 * Keyword (#825) * wip keywords optimization * update readme * limit concurrency to 4 * update readme * normalize keyword check (#830) * fix ghcr.io typo in README.md (#835) * Standardize/alphabetize rules, add cmd/generate/config package (#840) * Update detect.go (#839) * optimize keywords (#841) * optimize keywords * use defaults for concurrency again * maybe fix out of bounds (#843) * Generate tps (#845) * WIP * simplify tp generation * unpin docker version in pre-commit hook (#832) eliminating inconsistency. e.g. for version 8.6.1, pre-commit hooks points to outdated version https://github.com/zricethezav/gitleaks/blob/c33ee3f25215635c0afbb210672779e7efb6f1d2/.pre-commit-hooks.yaml#L10 * fix EOL in secret suffix (#847) * fix EOL in secret suffix * allow quoted key value syntax * Update dockerfile (#848) * bump alpine and add default safe dir for git * comment out safe dir fix * update deps * adding stopwords (#849) * adding stopwords * format readme, update default config * adding a ton of stopwords to the generic rule only as that is the loudest rule (#851) * nasty little bug (#853) * Removing private keyword from private key rule (#858) * fix no-git bug (#859) * Update README.md * Adding JIT Security messages * Update README.md * Improve PlanetScale token detection (#874) This improves the PlanetScale token detection. It add some flexibility in length. There is no guarantee that the length is always 43 characters (in fact, it's very likely to change a bit soon). Additionally, it adds support for detecting oauth tokens as well. * feat: add algolia key support (#866) * feat: add algolia key support * feat: add algolia key to generator * chore: update algolia regex to match gen * updating generic regex and algoia regex (#875) * ignore end line when comparing generic rules (#879) * Fix generic-api-key detected erroneously (zricethezav#877) (#878) * add combo to stopwords, update cmd/generate * Limit newlines regex (#881) * improve regex to reduce fps with newlines * remove version from regex and rely on stopwords instead * add false positive for validation * fix git unsafe directory (#883) * fix git unsafe directory fixes https://github.com/zricethezav/gitleaks/issues/846 * Update Dockerfile Co-authored-by: x <> * add link to gitleaks.io * Create gitleaks.yml (#884) * Add gitleaks badge * Update README.md * user accounts don't need gitleaks license * Update README.md * Update gitleaks.yml * Update README.md * Fix duplicate TOML Rules and IDs (#889) * Remove duplicate rule * Fix duplicate rule IDs Co-authored-by: Craig Smith <5344211-craigmsmith@users.noreply.gitlab.com> * maintain parity with recent changes... need to create rule contributing guidelines (#891) * Update generate (#892) * maintain parity with recent changes... need to create rule contributing guidelines * missed on, ensure uniqueness in rule-id * Lint python commit script to satisfy PEP8 (#893) * contributing guidelines first draft (#895) * contributing guidelines first draft * update links, add readme note * Adding a bunch of new rules, update allowlist to include node_modules… (#896) * Adding a bunch of new rules, update allowlist to include node_modules and vendor folders, extend helper config functions * use func instead of function in stopwords * Remove ssn allowlist (#898) * Adding a bunch of new rules, update allowlist to include node_modules and vendor folders, extend helper config functions * remove ssns from allowlist since default config does not detect ssn * Fixes accidental type typos while translating rules from validation spreadsheet, adds bittrex rule * adding airtable and adafruit (#902) * Fix Plaid, add Plaid access token (#903) * adding airtable and adafruit * Fix plaid, add plaid-access-token * Adding okta, codecov, zendesk, and updating Atlassian's rule to include `jira` keyword (#904) * okta * adding codecov * add jira to atlassians keywords * adding zendesk * Fix id and description for twitter tokens (#905) Co-authored-by: Craig Smith <5344211-craigmsmith@users.noreply.gitlab.com> * adding travis ci * capitilze twitter description * update twitter rule generation description and id * Add multi platform build (#897) Signed-off-by: Romain Barissat * Fix proper names capitalization (#907) Co-authored-by: Craig Smith <5344211-craigmsmith@users.noreply.gitlab.com> * adding access to generic rule keywords and identifiers * Update README.md * Update README.md * Update README.md * Add fix for issue #915 (#916) Co-authored-by: André Breuer * Feature: Adding the ability to extend configuration files (#926) * init * working on default and path config extensions * adding trace log level, consolidating some code * cleaning things up, updating generate package * fix tests * formatting * adding tests for extend * extend not extends * formatting * only allow usedefault or path to be set * update readme * add note about allowlists * more readme, expand env var for path * actually dont support env var. ez attack * add url for config * update readme * Feature/add sidekiq rules (#933) * Add sidekiq rules * Added two new rules for sidekiq * Other: Add keywords to square rules per Zach's instructions * Validate now works, but test suite is failing * Tests are now passing * Add Sidekiq Rules: Ran go fmt * * After resolving conflicts, had to rerun the rule generator to add back the semicolon char * After running tests, had to fix one line in testdata/expected/report/sarif_simple.sarif * * Added keywords to simple.toml for sidekiq-sensitive-url so that the rule matches what is in gitleaks.toml Co-authored-by: Andrew Weiner * Add new rules for vault tokens (#919) * add new rules for vault tokens * Configure max length for vault rules * gitleaks allow docs (#941) * gitleaks allow docs * reorder * bump golang test version (#942) * add jwt rule (#943) * add jwt support * ignore sample secrets * Feat/ignore finding (#938) * add two test findings to gitleaksignore * Explicit fingerprint (#944) * Update README.md * safe file checking (#946) * Feat/add fingerprint no git (#952) * no-git support fingerprint support * updating gitleaksignore w/ no-git false positives * fix test * draft: bump gitdiff, add git.Err state, better log messages (#954) * bump gitdiff, add git.Err state, better log messages * remove cmd.Start * forgot to start... * add prefect and readme rules (#961) * Add grafana tokens rules (#959) * Add grafana tokens rules * Adding upper bound limits to Grafana tokens * ignore empty files (#965) * Update version in readme file (#972) * Pretty output (#973) pretty output * add fingerprint to output * update gitleaksignore * refactor: more precise rule for private keys (#930) * refactor: more precise rule for private keys The current regex didn't match PGP private keys anymore, since they start with `BEGIN PGP PRIVATE KEY BLOCK` and the `BLOCK` never matched for the existing regex. I've made that part optional so that all strings matching for the current regex will still match for the new regex. * refactor: more precise rule for private keys Co-authored-by: Fabian F Groß * Add pre-commit autoupdate command to README.md (#978) * Add baseline (#975) * Add baseline * Update doc, add error, move baseline to detect namespace, ignore findings instead of reactively filter them out * Update detect/detect.go Co-authored-by: Zachary Rice * Update IsNew function (no check on tags - omit finger print check) * Update README.md Co-authored-by: Zachary Rice * Update examples in readme to make it ensure it's clear that a baseline is indeed a gitleaks report * Fix test - updated tags doesn't make a finding new * Add missing err assignment * Allow scanner to continue without baseline if file is malformed * Fix typo in comment * Fix control flow err. (Real life testing) * Fix wording * Auto-ignore baseline path * add rule for microsoft teams webhooks (#970) * Issue #980: Add support for Telegram Bot API Token (#981) * Issue #980: Add support for Telegram Bot API Token * Replace test with random bot_id length by tests with fixed one. Add tests for the corner cases. Co-authored-by: Alex Goncharov * Adding quiet mode to silence banner (#852) * Adding quiet mode to silence banner * Changing flag description. Adding flag to README * Updating argument name * updating variable name to aline with argument * fixing readme spacing * Fixing variable name * Update README.md * Update .gitleaksignore * Update README.md * Minor cleanup to error handling and logging (#985) * silence warning about unchecked errors * go-fmt change to add newline * Zerolog requires you to always call .Msg() When logging with zerolog, you need to always end with .Msg(), even if you just pass an empty string. If you read the README on https://github.com/rs/zerolog, they write: > It is very important to note that when using the zerolog > chaining API, as shown above (log.Info().Msg("hello world"), the > chain must have either the Msg or Msgf method call. If you > forget to add either of these, the log will not occur and there > is no compile time error to alert you of this. * Create empty slice without literal * Fix variable / package name collision with literal instead of having a variable named "config", which collides with the package name "config", just pass a literal config.Config{} struct to the function * Replace call to deprecated ioutil.ReadAll() Use io.ReadAll() instead * Check error when closing jsonFile Make it a warning and log error * Upgrade go version to 1.19 (#987) * upgrade go version to 1.19 * upgrade go version to 1.19 in dockerfile and test.yml * Detect Slack Workflow Webhook URLs (#989) * Output number of commits at info-level. (#991) * Exclude dacpac refactorlogs (#990) Dacpac refactorlogs contains Key's that are false positives. This commit excludes those files. * Create USERS.md * Update USERS.md (#996) * docs: added goreleaser to user list (#997) Thanks for gitleaks, its amazing to have it in the pipeline so I can have some extra peace of mind! * docs: add Trendyol to users (#998) * Add detection rules for DigitalOcean tokens (#1002) * Add detection rules for DigitalOcean tokens * go fmt correction Signed-off-by: Norman Ziegner Signed-off-by: Rui Chen Signed-off-by: Romain Barissat Co-authored-by: mercuriete Co-authored-by: mercuriete Co-authored-by: Zachary Rice Co-authored-by: Pavel Shklovsky Co-authored-by: Pavel Shklovsky Co-authored-by: AmitHofree Co-authored-by: bplaxco Co-authored-by: Tomy Guichard Co-authored-by: Norman Ziegner Co-authored-by: Ramon Co-authored-by: Tomasz Wierzchowski Co-authored-by: Emma Sax Co-authored-by: Ido Markovitz Co-authored-by: Ivan Kalita <72927991+ivankalitaonefootball@users.noreply.github.com> Co-authored-by: rotem-cider <78903577+rotem-cider@users.noreply.github.com> Co-authored-by: Ido-DY <85484711+Ido-DY@users.noreply.github.com> Co-authored-by: Eddie Austin <84474478+eddie-austin@users.noreply.github.com> Co-authored-by: eddie-northcutt-wfp0 Co-authored-by: amith-legit Co-authored-by: Eli Schleifer <1265982+EliSchleifer@users.noreply.github.com> Co-authored-by: b-abderrahmane Co-authored-by: Dustin Shimono <5289+dustinsand@users.noreply.github.com> Co-authored-by: dustin Co-authored-by: Nick Russler Co-authored-by: Rui Chen Co-authored-by: Matthew E. Grahlman Co-authored-by: dani Co-authored-by: Lucas Alcântara Co-authored-by: Fabian Kirschner Co-authored-by: Dirk Pahl Co-authored-by: M.Hassan Yousaf Co-authored-by: Joost Voskuil Co-authored-by: Florian Greinacher Co-authored-by: Ben Randall Co-authored-by: Andrzej Amghar Co-authored-by: Zachary Rice Co-authored-by: Greg Myers Co-authored-by: Chris Wolf Co-authored-by: Ian Mckay Co-authored-by: Luca Regne Co-authored-by: Greg Johnson Co-authored-by: Greg Johnson (codeEmitter) Co-authored-by: jetexe Co-authored-by: Isaac Dawson <60455448+idawson-gl@users.noreply.github.com> Co-authored-by: Adam Shannon Co-authored-by: foolioo <28758375+foolioo@users.noreply.github.com> Co-authored-by: aeongdesu Co-authored-by: 0xn3va <47100179+0xn3va@users.noreply.github.com> Co-authored-by: Dirkjan Bussink Co-authored-by: SimonGurney Co-authored-by: Don C. Bigler <94854301+dcb-imvaria@users.noreply.github.com> Co-authored-by: Craig Smith Co-authored-by: Craig Smith <5344211-craigmsmith@users.noreply.gitlab.com> Co-authored-by: Alex <52292902+alexrudd2@users.noreply.github.com> Co-authored-by: Romain Barissat Co-authored-by: anotherbridge <46713015+anotherbridge@users.noreply.github.com> Co-authored-by: André Breuer Co-authored-by: Andrew Co-authored-by: Andrew Weiner Co-authored-by: Malte Morgenstern <65773564+maltemorgenstern@users.noreply.github.com> Co-authored-by: jmatosgrafana <100539023+jmatosgrafana@users.noreply.github.com> Co-authored-by: Akash Chandwani <3483277+akashchandwani@users.noreply.github.com> Co-authored-by: very-doge-wow <95224950+very-doge-wow@users.noreply.github.com> Co-authored-by: Fabian F Groß Co-authored-by: Gawan Schroeder <34353307+gawansch@users.noreply.github.com> Co-authored-by: Alex Goncharov <49787265+b4bay@users.noreply.github.com> Co-authored-by: Alex Goncharov Co-authored-by: Zane Durkin Co-authored-by: Michael Jarvis <5694899+mojotx@users.noreply.github.com> Co-authored-by: naoki kuroda <68233204+nnnkkk7@users.noreply.github.com> Co-authored-by: Becojo Co-authored-by: alexgit2k Co-authored-by: Carlos Alexandro Becker Co-authored-by: Furkan Türkal Co-authored-by: Michael Henriksen --- .github/FUNDING.yml | 1 - .github/ISSUE_TEMPLATE/maintenance.md | 16 + .github/workflows/gitleaks.yml | 13 + .github/workflows/release.yml | 57 + .github/workflows/test.yml | 26 + .gitignore | 7 + .gitleaksignore | 744 +++++ .goreleaser.yml | 29 + .pre-commit-hooks.yaml | 11 + .travis.yml | 8 - CONTRIBUTING.md | 103 + Dockerfile | 20 +- Makefile | 50 +- README.md | 432 ++- USERS.md | 25 + cmd/detect.go | 181 ++ cmd/generate/config/main.go | 192 ++ cmd/generate/config/rules/adafruit.go | 23 + cmd/generate/config/rules/adobe.go | 39 + cmd/generate/config/rules/age.go | 23 + cmd/generate/config/rules/airtable.go | 23 + cmd/generate/config/rules/algolia.go | 22 + cmd/generate/config/rules/alibaba.go | 41 + cmd/generate/config/rules/asana.go | 40 + cmd/generate/config/rules/atlassian.go | 25 + cmd/generate/config/rules/aws.go | 31 + cmd/generate/config/rules/beamer.go | 24 + cmd/generate/config/rules/bitbucket.go | 40 + cmd/generate/config/rules/bittrex.go | 40 + cmd/generate/config/rules/clojars.go | 24 + cmd/generate/config/rules/codecov.go | 25 + cmd/generate/config/rules/coinbase.go | 27 + cmd/generate/config/rules/config.tmpl | 60 + cmd/generate/config/rules/confluent.go | 44 + cmd/generate/config/rules/contentful.go | 24 + cmd/generate/config/rules/databricks.go | 22 + cmd/generate/config/rules/datadog.go | 26 + cmd/generate/config/rules/digitalocean.go | 51 + cmd/generate/config/rules/discord.go | 57 + cmd/generate/config/rules/doppler.go | 27 + cmd/generate/config/rules/droneci.go | 25 + cmd/generate/config/rules/dropbox.go | 49 + cmd/generate/config/rules/duffel.go | 24 + cmd/generate/config/rules/dynatrace.go | 24 + cmd/generate/config/rules/easypost.go | 40 + cmd/generate/config/rules/etsy.go | 25 + cmd/generate/config/rules/facebook.go | 23 + cmd/generate/config/rules/fastly.go | 23 + cmd/generate/config/rules/finicity.go | 40 + cmd/generate/config/rules/finnhub.go | 25 + cmd/generate/config/rules/flickr.go | 25 + cmd/generate/config/rules/flutterwave.go | 56 + cmd/generate/config/rules/frameio.go | 24 + cmd/generate/config/rules/freshbooks.go | 25 + cmd/generate/config/rules/gcp.go | 44 + cmd/generate/config/rules/generic.go | 55 + cmd/generate/config/rules/github.go | 73 + cmd/generate/config/rules/gitlab.go | 24 + cmd/generate/config/rules/gitter.go | 27 + cmd/generate/config/rules/gocardless.go | 26 + cmd/generate/config/rules/grafana.go | 65 + cmd/generate/config/rules/hashicorp.go | 24 + cmd/generate/config/rules/heroku.go | 22 + cmd/generate/config/rules/hubspot.go | 23 + cmd/generate/config/rules/intercom.go | 23 + cmd/generate/config/rules/jwt.go | 21 + cmd/generate/config/rules/kraken.go | 27 + cmd/generate/config/rules/kucoin.go | 44 + cmd/generate/config/rules/launchdarkly.go | 25 + cmd/generate/config/rules/linear.go | 41 + cmd/generate/config/rules/linkedin.go | 52 + cmd/generate/config/rules/lob.go | 47 + cmd/generate/config/rules/mailchimp.go | 25 + cmd/generate/config/rules/mailgun.go | 63 + cmd/generate/config/rules/mapbox.go | 23 + cmd/generate/config/rules/mattermost.go | 25 + cmd/generate/config/rules/messagebird.go | 58 + cmd/generate/config/rules/netlify.go | 26 + cmd/generate/config/rules/newrelic.go | 77 + cmd/generate/config/rules/npm.go | 25 + cmd/generate/config/rules/nytimes.go | 29 + cmd/generate/config/rules/okta.go | 26 + cmd/generate/config/rules/plaid.go | 66 + cmd/generate/config/rules/planetscale.go | 69 + cmd/generate/config/rules/postman.go | 25 + cmd/generate/config/rules/prefect.go | 25 + cmd/generate/config/rules/privatekey.go | 28 + cmd/generate/config/rules/pulumi.go | 25 + cmd/generate/config/rules/pypi.go | 26 + cmd/generate/config/rules/rapidapi.go | 27 + cmd/generate/config/rules/readme.go | 25 + cmd/generate/config/rules/rubygems.go | 25 + cmd/generate/config/rules/rule.go | 110 + cmd/generate/config/rules/sendbird.go | 44 + cmd/generate/config/rules/sendgrid.go | 25 + cmd/generate/config/rules/sendinblue.go | 25 + cmd/generate/config/rules/sentry.go | 25 + cmd/generate/config/rules/shippo.go | 26 + cmd/generate/config/rules/shopify.go | 64 + cmd/generate/config/rules/sidekiq.go | 60 + cmd/generate/config/rules/slack.go | 51 + cmd/generate/config/rules/square.go | 38 + cmd/generate/config/rules/squarespace.go | 25 + cmd/generate/config/rules/stopwords.go | 1489 +++++++++ cmd/generate/config/rules/stripe.go | 27 + cmd/generate/config/rules/sumologic.go | 46 + cmd/generate/config/rules/teams.go | 29 + cmd/generate/config/rules/telegram.go | 57 + cmd/generate/config/rules/travisci.go | 25 + cmd/generate/config/rules/trello.go | 25 + cmd/generate/config/rules/twilio.go | 24 + cmd/generate/config/rules/twitch.go | 25 + cmd/generate/config/rules/twitter.go | 91 + cmd/generate/config/rules/typeform.go | 26 + cmd/generate/config/rules/vault.go | 38 + cmd/generate/config/rules/yandex.go | 69 + cmd/generate/config/rules/zendesk.go | 25 + cmd/generate/secrets/regen.go | 15 + cmd/protect.go | 105 + cmd/root.go | 147 + cmd/version.go | 23 + config/allowlist.go | 60 + config/allowlist_test.go | 93 + config/config.go | 396 +-- config/config_test.go | 209 +- config/default.go | 139 - config/gitleaks.toml | 2758 +++++++++++++++++ config/rule.go | 43 + config/utils.go | 24 + detect/baseline.go | 65 + detect/baseline_test.go | 137 + detect/detect.go | 511 +++ detect/detect_test.go | 578 ++++ detect/git/git.go | 121 + detect/git/git_test.go | 158 + detect/location.go | 69 + detect/location_test.go | 60 + detect/utils.go | 158 + examples/leaky-repo.toml | 195 -- examples/pre-commit.example | 19 - examples/regex_and_entropy_config.toml | 17 - .../simple_regex_and_allowlist_config.toml | 13 - examples/simple_regex_config.toml | 6 - go.mod | 57 +- go.sum | 676 +++- hosts/github.go | 190 -- hosts/gitlab.go | 112 - hosts/host.go | 53 - hosts/hosts_test.go | 116 - main.go | 99 +- manager/manager.go | 274 -- manager/manager_test.go | 106 - manager/report.go | 78 - manager/sarif.go | 153 - options/options.go | 257 -- options/options_test.go | 1 - report/constants.go | 4 + report/csv.go | 57 + report/csv_test.go | 85 + report/finding.go | 50 + report/finding_test.go | 27 + report/json.go | 15 + report/json_test.go | 88 + report/report.go | 32 + report/report_test.go | 111 + report/sarif.go | 209 ++ report/sarif_test.go | 111 + scan/repo.go | 304 -- scan/rule.go | 395 --- scan/scan.go | 493 --- scan/scan_test.go | 628 ---- scripts/pre-commit.py | 27 + test_data/test_configs/allowlist_commit.toml | 13 - test_data/test_configs/aws_key.toml | 9 - .../test_configs/aws_key_allowlist_files.toml | 8 - .../aws_key_allowlist_python_files.toml | 7 - .../test_configs/aws_key_aws_allowlisted.toml | 7 - .../test_configs/aws_key_file_regex.toml | 14 - .../aws_key_global_allowlist_file.toml | 10 - .../aws_key_global_allowlist_path.toml | 10 - .../aws_key_local_owner_allowlist_repo.toml | 9 - test_data/test_configs/bad_aws_key.toml | 9 - .../test_configs/bad_aws_key_file_regex.toml | 13 - test_data/test_configs/bad_entropy_1.toml | 8 - test_data/test_configs/bad_entropy_2.toml | 8 - test_data/test_configs/bad_entropy_3.toml | 8 - test_data/test_configs/bad_entropy_4.toml | 9 - test_data/test_configs/bad_entropy_5.toml | 9 - test_data/test_configs/bad_entropy_6.toml | 9 - test_data/test_configs/bad_entropy_7.toml | 9 - test_data/test_configs/bad_regex_aws_key.toml | 9 - test_data/test_configs/entropy.toml | 11 - test_data/test_configs/generic.toml | 4 - test_data/test_configs/large.toml | 148 - .../large_with_global_allowlist_regex.toml | 151 - test_data/test_configs/regex_entropy.toml | 14 - test_data/test_configs/regex_filename.toml | 6 - test_data/test_configs/regex_filepath.toml | 6 - .../test_configs/regex_filepath_filename.toml | 7 - test_data/test_entropy.json | 15 - test_data/test_local_owner_aws_leak.json | 197 -- ...t_local_owner_aws_leak_allowlist_repo.json | 197 -- .../test_local_owner_aws_leak_depth_2.json | 107 - test_data/test_local_repo_eight.json | 47 - ...test_local_repo_five_at_latest_commit.json | 17 - test_data/test_local_repo_five_commit.json | 17 - .../test_local_repo_five_files_at_commit.json | 32 - ...ocal_repo_five_files_at_latest_commit.json | 32 - ...st_local_repo_four_alt_config_entropy.json | 32 - ...ocal_repo_four_leaks_commit_timerange.json | 32 - test_data/test_local_repo_nine_aws_leak.json | 17 - test_data/test_local_repo_one_aws_leak.json | 17 - ...local_repo_one_aws_leak_and_file_leak.json | 17 - .../test_local_repo_one_aws_leak_commit.json | 17 - ...t_local_repo_one_aws_leak_uncommitted.json | 17 - ...local_repo_seven_aws_leak_uncommitted.json | 17 - test_data/test_local_repo_six.json | 44 - test_data/test_local_repo_six_filename.json | 32 - test_data/test_local_repo_six_filepath.json | 17 - ...test_local_repo_six_filepath_filename.json | 17 - .../test_local_repo_six_leaks_since_date.json | 17 - .../test_local_repo_six_leaks_until_date.json | 17 - ...al_repo_six_path_globally_allowlisted.json | 17 - test_data/test_local_repo_three_leaks.json | 62 - ...test_local_repo_two_allowlist_commits.json | 17 - test_data/test_local_repo_two_leaks.json | 47 - ...test_local_repo_two_leaks_commit_from.json | 32 - ...est_local_repo_two_leaks_commit_range.json | 32 - .../test_local_repo_two_leaks_commit_to.json | 17 - ...t_local_repo_two_leaks_commit_to_from.json | 17 - .../test_local_repo_two_leaks_deletion.json | 92 - ...ocal_repo_two_leaks_file_commit_range.json | 32 - .../test_options/test_local_repo_commits.txt | 5 - test_data/test_regex_entropy.json | 17 - .../test_repo_1/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_1/dotGit/HEAD | 1 - .../test_repos/test_repo_1/dotGit/config | 7 - test_data/test_repos/test_repo_1/dotGit/index | Bin 126 -> 0 bytes .../test_repos/test_repo_1/dotGit/logs/HEAD | 2 - .../test_repo_1/dotGit/logs/refs/heads/master | 2 - .../10/fa14c5ab0134436e2ae435138bf921eb477c60 | Bin 784 -> 0 bytes .../3a/76f3781306faf5612017bf18a4b4bdb9f927bf | Bin 138 -> 0 bytes .../41/42082bcb939bbc17985a69ba748491ac6b62a5 | Bin 281 -> 0 bytes .../49/8b267a8c7812490d6479839c5577eaaec79d62 | Bin 77 -> 0 bytes .../60/c9e47f150a6b713e247e6105b77f1b961f844f | Bin 23 -> 0 bytes .../61/87dbf4390fc6e28445dd3d988aefb9d1111988 | Bin 708 -> 0 bytes .../65/57c92612d3b35979bd426d429255b3bf9fab74 | Bin 133 -> 0 bytes .../6a/756416384c210ada2631f17862f5c01fffa478 | Bin 946 -> 0 bytes .../6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 | Bin 114 -> 0 bytes .../6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 | Bin 2176 -> 0 bytes .../80/8b12c5ca4b142367932e7045d555a639fc148c | Bin 209 -> 0 bytes .../80/ba94135cc378364af9d3cb2450df48e51faf2c | Bin 1247 -> 0 bytes .../9e/523225b31add24e72f2feb0b2645cfb36542dc | 3 - .../a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 | 3 - .../a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d | Bin 57 -> 0 bytes .../a5/196d1be8fb59edf8062bef36d3a602e0812139 | 1 - .../a5/d7b84a673458d14d9aab082183a1968c2c7492 | Bin 299 -> 0 bytes .../b5/8d1184a9d43a39c0d95f32453efc78581877d6 | Bin 529 -> 0 bytes .../c9/8e6c52cbd1f50de572ff12a3441271fccff705 | Bin 158 -> 0 bytes .../cb/089cd89a7d7686d284d8761201649346b5aa1c | Bin 37 -> 0 bytes .../cb/19a50e8cdeb7011eccdb13f3b739f00d775bab | 2 - .../d2/74003914c707212cbe84e3e466a00013ccb639 | Bin 154 -> 0 bytes .../e6/73bb3980f3c286291809e05f80873852bc3e9c | Bin 1646 -> 0 bytes .../e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 | Bin 59 -> 0 bytes .../ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e | 2 - .../fe/f3190e94723e78847ab9f0daaa15add4ffd4ef | Bin 58 -> 0 bytes .../test_repo_1/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_1/server.test.py | 9 - .../test_repo_2/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_2/dotGit/HEAD | 1 - .../test_repos/test_repo_2/dotGit/config | 7 - .../test_repos/test_repo_2/dotGit/description | 1 - test_data/test_repos/test_repo_2/dotGit/index | Bin 225 -> 0 bytes .../test_repo_2/dotGit/info/exclude | 6 - .../test_repos/test_repo_2/dotGit/logs/HEAD | 8 - .../test_repo_2/dotGit/logs/refs/heads/master | 8 - .../0b/c3a0c9536cc7273b74f48edcc6adead16333f7 | Bin 55 -> 0 bytes .../0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc | Bin 115 -> 0 bytes .../15/40f193bc25b494cde092597a79af04013807ec | Bin 3391 -> 0 bytes .../17/471a5fda722a9e423f1a0d3f0d267ea009d41c | Bin 181 -> 0 bytes .../20/ef26716304570775cb395f37cb2d626bbd0a82 | Bin 83 -> 0 bytes .../24/3d535d84ed97fbc20d09c9d2c2f417507fe461 | Bin 59 -> 0 bytes .../3d/dab16668fe919638b76dd48c96bedf0e2276ca | Bin 94 -> 0 bytes .../51/f6dcf6b89b93f4075ba92c400b075631a6cc93 | 3 - .../5d/5c8724e8787e69cebcc9ea4bceb47d9941656e | Bin 83 -> 0 bytes .../5d/630e1163864c8b5616199962390a36a8a53b69 | Bin 53 -> 0 bytes .../5e/a982157d053ce35a9b79394973c7c8901f317c | Bin 83 -> 0 bytes .../69/b7669aa8e125ef0e14abce31911e84dd09e25e | Bin 83 -> 0 bytes .../85/699e429f33e75541530998a5b5d457a12e6285 | Bin 124 -> 0 bytes .../8c/b18882408aad0b2abf556bf1f2c5478ef328f5 | Bin 68 -> 0 bytes .../96/c1c0a3632af796efd3942cc1d81d7af48ead3e | Bin 133 -> 0 bytes .../99/6865bb912f3bc45898a370a13aadb315014b55 | 3 - .../a6/214eec6a6290fec81fe250e5b73b86d634a981 | Bin 67 -> 0 bytes .../b1/0b3e2cb320a8c211fda94c4567299d37de7776 | Bin 164 -> 0 bytes .../b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba | Bin 162 -> 0 bytes .../c0/23aab082c73abd327675ad485fe78bb427ae21 | Bin 84 -> 0 bytes .../c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 | Bin 95 -> 0 bytes .../d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a | 1 - .../e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 | Bin 54 -> 0 bytes .../f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 | 2 - .../test_repo_2/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_2/no_secrets.md | 1 - test_data/test_repos/test_repo_2/secrets.md | 3 - .../test_repo_3/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_3/dotGit/HEAD | 1 - .../test_repos/test_repo_3/dotGit/config | 7 - .../test_repos/test_repo_3/dotGit/description | 1 - test_data/test_repos/test_repo_3/dotGit/index | Bin 225 -> 0 bytes .../test_repo_3/dotGit/info/exclude | 6 - .../test_repos/test_repo_3/dotGit/logs/HEAD | 14 - .../test_repo_3/dotGit/logs/refs/heads/dev | 3 - .../test_repo_3/dotGit/logs/refs/heads/master | 10 - .../0b/c3a0c9536cc7273b74f48edcc6adead16333f7 | Bin 55 -> 0 bytes .../0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc | Bin 115 -> 0 bytes .../15/40f193bc25b494cde092597a79af04013807ec | Bin 3391 -> 0 bytes .../17/471a5fda722a9e423f1a0d3f0d267ea009d41c | Bin 181 -> 0 bytes .../18/5715c36f82be353f34845811270a4d0ae4b24e | Bin 83 -> 0 bytes .../20/ef26716304570775cb395f37cb2d626bbd0a82 | Bin 83 -> 0 bytes .../24/3d535d84ed97fbc20d09c9d2c2f417507fe461 | Bin 59 -> 0 bytes .../3d/dab16668fe919638b76dd48c96bedf0e2276ca | Bin 94 -> 0 bytes .../4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb | Bin 125 -> 0 bytes .../4b/a23978297d33c8d7744f059cc5bca2385e262d | Bin 83 -> 0 bytes .../51/f6dcf6b89b93f4075ba92c400b075631a6cc93 | 3 - .../5d/5c8724e8787e69cebcc9ea4bceb47d9941656e | Bin 83 -> 0 bytes .../5d/630e1163864c8b5616199962390a36a8a53b69 | Bin 53 -> 0 bytes .../5e/a982157d053ce35a9b79394973c7c8901f317c | Bin 83 -> 0 bytes .../64/cfcee9aad1c84581631636bfc54f2050718d1a | Bin 156 -> 0 bytes .../68/b020592645020c9afb7462e17842a1cc723071 | Bin 83 -> 0 bytes .../69/b7669aa8e125ef0e14abce31911e84dd09e25e | Bin 83 -> 0 bytes .../82/4b8a2b468fcfa244e096bd54b83508b85ef488 | Bin 115 -> 0 bytes .../83/c50b16ff4b3149142517a2adc8662f04b5b323 | Bin 54 -> 0 bytes .../84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 | 3 - .../85/699e429f33e75541530998a5b5d457a12e6285 | Bin 124 -> 0 bytes .../8c/b18882408aad0b2abf556bf1f2c5478ef328f5 | Bin 68 -> 0 bytes .../96/c1c0a3632af796efd3942cc1d81d7af48ead3e | Bin 133 -> 0 bytes .../99/6865bb912f3bc45898a370a13aadb315014b55 | 3 - .../a6/214eec6a6290fec81fe250e5b73b86d634a981 | Bin 67 -> 0 bytes .../b1/07a0d7a337f04413efa73d337461f548aef336 | Bin 83 -> 0 bytes .../b1/0b3e2cb320a8c211fda94c4567299d37de7776 | Bin 164 -> 0 bytes .../b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba | Bin 162 -> 0 bytes .../b8/a52870f2b093699e0d98cb896387c87e0c98a6 | Bin 66 -> 0 bytes .../c0/23aab082c73abd327675ad485fe78bb427ae21 | Bin 84 -> 0 bytes .../c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 | Bin 95 -> 0 bytes .../cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 | 3 - .../d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a | 1 - .../de/ea550dd6c7acaf0e59432600593533984a2125 | Bin 158 -> 0 bytes .../e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 | Bin 54 -> 0 bytes .../f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 | 2 - .../test_repo_3/dotGit/refs/heads/dev | 1 - .../test_repo_3/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_3/no_secrets.md | 1 - test_data/test_repos/test_repo_3/secrets.md | 2 - .../test_repo_4/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_4/dotGit/HEAD | 1 - .../test_repos/test_repo_4/dotGit/config | 7 - .../test_repos/test_repo_4/dotGit/description | 1 - test_data/test_repos/test_repo_4/dotGit/index | Bin 305 -> 0 bytes .../test_repo_4/dotGit/info/exclude | 6 - .../test_repos/test_repo_4/dotGit/logs/HEAD | 18 - .../test_repo_4/dotGit/logs/refs/heads/dev | 3 - .../test_repo_4/dotGit/logs/refs/heads/master | 14 - .../0b/c3a0c9536cc7273b74f48edcc6adead16333f7 | Bin 55 -> 0 bytes .../0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc | Bin 115 -> 0 bytes .../15/40f193bc25b494cde092597a79af04013807ec | Bin 3391 -> 0 bytes .../17/471a5fda722a9e423f1a0d3f0d267ea009d41c | Bin 181 -> 0 bytes .../18/51114bbb7484cccd61f18c71649699d73ede6c | Bin 121 -> 0 bytes .../18/5715c36f82be353f34845811270a4d0ae4b24e | Bin 83 -> 0 bytes .../20/ef26716304570775cb395f37cb2d626bbd0a82 | Bin 83 -> 0 bytes .../24/3d535d84ed97fbc20d09c9d2c2f417507fe461 | Bin 59 -> 0 bytes .../29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 | Bin 425 -> 0 bytes .../3d/dab16668fe919638b76dd48c96bedf0e2276ca | Bin 94 -> 0 bytes .../4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb | Bin 125 -> 0 bytes .../4b/a23978297d33c8d7744f059cc5bca2385e262d | Bin 83 -> 0 bytes .../4b/c47c2d3aaa25385e3354ea34136456c2260a12 | Bin 121 -> 0 bytes .../51/f6dcf6b89b93f4075ba92c400b075631a6cc93 | 3 - .../5a/ccbc40c35906d99f073881fb8746c314f9d59f | 1 - .../5d/5c8724e8787e69cebcc9ea4bceb47d9941656e | Bin 83 -> 0 bytes .../5d/630e1163864c8b5616199962390a36a8a53b69 | Bin 53 -> 0 bytes .../5e/a982157d053ce35a9b79394973c7c8901f317c | Bin 83 -> 0 bytes .../64/99d414147df9f56cbecd26ca710c39e4834024 | Bin 97 -> 0 bytes .../64/cfcee9aad1c84581631636bfc54f2050718d1a | Bin 156 -> 0 bytes .../67/c45b6048e42a2bd5512662ca6cd2bfc74c7842 | 5 - .../68/b020592645020c9afb7462e17842a1cc723071 | Bin 83 -> 0 bytes .../69/b7669aa8e125ef0e14abce31911e84dd09e25e | Bin 83 -> 0 bytes .../7b/2eba252004b7c867413def2a0984d545daab8b | Bin 160 -> 0 bytes .../82/4b8a2b468fcfa244e096bd54b83508b85ef488 | Bin 115 -> 0 bytes .../82/8595723b76e4a35b5253d9f2ccb4f897f1845a | Bin 163 -> 0 bytes .../83/c50b16ff4b3149142517a2adc8662f04b5b323 | Bin 54 -> 0 bytes .../84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 | 3 - .../85/699e429f33e75541530998a5b5d457a12e6285 | Bin 124 -> 0 bytes .../8c/b18882408aad0b2abf556bf1f2c5478ef328f5 | Bin 68 -> 0 bytes .../96/c1c0a3632af796efd3942cc1d81d7af48ead3e | Bin 133 -> 0 bytes .../99/6865bb912f3bc45898a370a13aadb315014b55 | 3 - .../a6/214eec6a6290fec81fe250e5b73b86d634a981 | Bin 67 -> 0 bytes .../b1/07a0d7a337f04413efa73d337461f548aef336 | Bin 83 -> 0 bytes .../b1/0b3e2cb320a8c211fda94c4567299d37de7776 | Bin 164 -> 0 bytes .../b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba | Bin 162 -> 0 bytes .../b4/70f07d2aaf2b537808b285cab667259b4e0ca7 | Bin 121 -> 0 bytes .../b8/a52870f2b093699e0d98cb896387c87e0c98a6 | Bin 66 -> 0 bytes .../c0/23aab082c73abd327675ad485fe78bb427ae21 | Bin 84 -> 0 bytes .../c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 | Bin 95 -> 0 bytes .../cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 | 3 - .../ce/835da266b3f8c34e4b7f398693ed068f67cb30 | 1 - .../d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a | 1 - .../de/ea550dd6c7acaf0e59432600593533984a2125 | Bin 158 -> 0 bytes .../e0/894b9037d76464dbb8d25768c9a036987d6ace | Bin 121 -> 0 bytes .../e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 | Bin 54 -> 0 bytes .../ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 | Bin 99 -> 0 bytes .../f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 | 2 - .../test_repo_4/dotGit/refs/heads/dev | 1 - .../test_repo_4/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_4/gitleaks.toml | 8 - .../test_repos/test_repo_4/no_secrets.md | 1 - test_data/test_repos/test_repo_4/secrets.md | 21 - .../test_repo_5/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_5/dotGit/HEAD | 1 - .../test_repos/test_repo_5/dotGit/config | 7 - .../test_repos/test_repo_5/dotGit/description | 1 - test_data/test_repos/test_repo_5/dotGit/index | Bin 217 -> 0 bytes .../test_repo_5/dotGit/info/exclude | 6 - .../test_repos/test_repo_5/dotGit/logs/HEAD | 4 - .../test_repo_5/dotGit/logs/refs/heads/master | 4 - .../00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 | Bin 123 -> 0 bytes .../1f/2a4abc47dabf991e6af6f9770867ce0ac1f360 | 2 - .../2b/8f95ef90b07889acd0607a91a22bee87ac4a46 | Bin 67 -> 0 bytes .../54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec | 4 - .../5d/bb39e8aa13063310c7cd4787a62d3119674be0 | Bin 87 -> 0 bytes .../81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb | Bin 87 -> 0 bytes .../97/2ea8fcf4f3d9a216644c8eb11df1382b6e02ab | Bin 20 -> 0 bytes .../a4/c9fb737d5552fd96fce5cc7eedb23353ba9ed0 | 2 - .../ca/71fcdeda15f25f0cc661d90e8785c255925c27 | 1 - .../cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 | Bin 53 -> 0 bytes .../f6/878b4d8b01947b3bd9bf23de8446cb6cae335e | Bin 77 -> 0 bytes .../fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 | Bin 87 -> 0 bytes .../test_repo_5/dotGit/refs/heads/master | 1 - test_data/test_repos/test_repo_5/notes.md | 1 - test_data/test_repos/test_repo_5/secrets.py | 9 - .../test_repos/test_repo_6/application.yaml | 3 - .../test_repo_6/config/application.properties | 3 - .../test_repo_6/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_6/dotGit/HEAD | 1 - .../test_repos/test_repo_6/dotGit/config | 7 - .../test_repos/test_repo_6/dotGit/description | 1 - test_data/test_repos/test_repo_6/dotGit/index | Bin 333 -> 0 bytes .../test_repo_6/dotGit/info/exclude | 6 - .../test_repos/test_repo_6/dotGit/logs/HEAD | 4 - .../test_repo_6/dotGit/logs/refs/heads/master | 3 - .../10/fa14c5ab0134436e2ae435138bf921eb477c60 | Bin 784 -> 0 bytes .../3a/76f3781306faf5612017bf18a4b4bdb9f927bf | Bin 138 -> 0 bytes .../41/42082bcb939bbc17985a69ba748491ac6b62a5 | Bin 281 -> 0 bytes .../49/8b267a8c7812490d6479839c5577eaaec79d62 | Bin 77 -> 0 bytes .../5c/b000d0f4965e9b0c080814478dbf4e87c114c7 | Bin 111 -> 0 bytes .../60/c9e47f150a6b713e247e6105b77f1b961f844f | Bin 23 -> 0 bytes .../61/87dbf4390fc6e28445dd3d988aefb9d1111988 | Bin 708 -> 0 bytes .../65/57c92612d3b35979bd426d429255b3bf9fab74 | Bin 133 -> 0 bytes .../69/465772e5c3a14379da6c369cdb46edbaa6d097 | Bin 133 -> 0 bytes .../6a/756416384c210ada2631f17862f5c01fffa478 | Bin 946 -> 0 bytes .../6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 | Bin 114 -> 0 bytes .../6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 | Bin 2176 -> 0 bytes .../80/8b12c5ca4b142367932e7045d555a639fc148c | Bin 209 -> 0 bytes .../80/ba94135cc378364af9d3cb2450df48e51faf2c | Bin 1247 -> 0 bytes .../98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 | Bin 176 -> 0 bytes .../9e/523225b31add24e72f2feb0b2645cfb36542dc | 3 - .../a1/ddd32febf3bde66331218f877ff637c85c5f92 | Bin 208 -> 0 bytes .../a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 | 3 - .../a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d | Bin 57 -> 0 bytes .../a5/196d1be8fb59edf8062bef36d3a602e0812139 | 1 - .../a5/d7b84a673458d14d9aab082183a1968c2c7492 | Bin 299 -> 0 bytes .../b5/8d1184a9d43a39c0d95f32453efc78581877d6 | Bin 529 -> 0 bytes .../bc/379e22c22a97ca5ffc871c1449af854f6f26c4 | Bin 195 -> 0 bytes .../c9/8e6c52cbd1f50de572ff12a3441271fccff705 | Bin 158 -> 0 bytes .../cb/089cd89a7d7686d284d8761201649346b5aa1c | Bin 37 -> 0 bytes .../cb/19a50e8cdeb7011eccdb13f3b739f00d775bab | 2 - .../d2/74003914c707212cbe84e3e466a00013ccb639 | Bin 154 -> 0 bytes .../db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 | Bin 67 -> 0 bytes .../dd/6e8207f130e113c97f5ed15238e7901290ee42 | Bin 106 -> 0 bytes .../dd/cd9ac6904950dcc48e4c04ba043707e9e0117f | Bin 132 -> 0 bytes .../e6/73bb3980f3c286291809e05f80873852bc3e9c | Bin 1646 -> 0 bytes .../e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 | Bin 59 -> 0 bytes .../ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e | 2 - .../fe/f3190e94723e78847ab9f0daaa15add4ffd4ef | Bin 58 -> 0 bytes .../test_repo_6/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_6/server.test.py | 10 - test_data/test_repos/test_repo_7/dotGit/HEAD | 1 - .../test_repos/test_repo_7/dotGit/config | 7 - .../test_repos/test_repo_7/dotGit/description | 1 - .../test_repo_7/dotGit/info/exclude | 6 - test_data/test_repos/test_repo_7/file | 6 - test_data/test_repos/test_repo_8/README.md | 2 - test_data/test_repos/test_repo_8/dotGit/HEAD | 1 - .../test_repos/test_repo_8/dotGit/description | 1 - test_data/test_repos/test_repo_8/dotGit/index | Bin 297 -> 0 bytes .../test_repo_8/dotGit/info/exclude | 6 - .../test_repos/test_repo_8/dotGit/logs/HEAD | 1 - .../test_repo_8/dotGit/logs/refs/heads/master | 1 - .../dotGit/logs/refs/remotes/origin/HEAD | 1 - .../0b/aadf22eda42ba55c4fec3e14973edc6cec783a | 4 - .../0c/4994567bb2c77bebe47868d3bf1dd287d20452 | Bin 131 -> 0 bytes .../0c/79fa4384c973e9a6fe794491492da04ea289aa | Bin 131 -> 0 bytes .../16/f577ee2b9f9e185ae792092d779dc7e9a5d90f | Bin 514 -> 0 bytes .../17/f5d7f87925bdad6793b0fc7e338378ffb93166 | Bin 131 -> 0 bytes .../23/efedf4961168dc048e896f68eda78bcfb8e51f | Bin 131 -> 0 bytes .../2a/5fecc2737429b02047e5a99d9c0ac6e76a3ac2 | Bin 554 -> 0 bytes .../36/09cadde7b3c8323d95943d6edfcf9c7a58dbdf | Bin 566 -> 0 bytes .../3c/cb6c2b338c176bbb7de1154cd7b61d0f6155ce | 4 - .../46/7192699b9e6aaf85401389e1db50ce9685ab56 | Bin 87 -> 0 bytes .../54/759376585b8a4e0318b1ecc0e770f69a6c4230 | Bin 120 -> 0 bytes .../61/4a498fb4c38af5f5909718481e8b371f118901 | Bin 54 -> 0 bytes .../64/b4391ddf2b399fb5218ee44cf90111d3f7ca9a | Bin 565 -> 0 bytes .../64/dbb271509f9b9647106da59914a6f5320de7c4 | Bin 131 -> 0 bytes .../74/8f11eaf2c38c3cf0ac6a22e44208777e79fa6f | 5 - .../75/ead74004eb27c7e9e1ddf391f089ea0441f242 | Bin 386 -> 0 bytes .../84/5ebbfaf21dd869057da0e2a3494f2b8dea8cde | Bin 382 -> 0 bytes .../92/67bc86ec1497471cbc6f3308f3527f7ef34b9d | Bin 554 -> 0 bytes .../b0/e4c4f24e7787b8ae08521f56b5dd9a76f90011 | Bin 43 -> 0 bytes .../b2/6121273b1bf2eb385ae14ad0a0f186e3a47f4b | Bin 393 -> 0 bytes .../b3/aeb0f5be4a83bbeaee1d6ae5b755502020819e | Bin 102 -> 0 bytes .../b3/bec734a41357c480b7856e0298de649a5fef14 | Bin 566 -> 0 bytes .../b9/01f643b1eeeaeb7ff12931213bd0d9a47254d1 | Bin 131 -> 0 bytes .../ce/6e0398cd8a40085cad12a8f4c96e580c2200c1 | Bin 611 -> 0 bytes .../ce/7e8177bbf8a172c06b6a1e370a374d5c19f660 | Bin 554 -> 0 bytes .../fc/8b31a54e5975bc41e901965e0c7dee18ed202f | Bin 74 -> 0 bytes .../test_repos/test_repo_8/dotGit/packed-refs | 4 - .../test_repo_8/dotGit/refs/heads/master | 1 - .../dotGit/refs/remotes/origin/HEAD | 1 - test_data/test_repos/test_repo_8/dummy.txt | 8 - .../test_repo_8/ufos_might_be_real.txt | 19 - .../test_repo_9/dotGit/COMMIT_EDITMSG | 1 - test_data/test_repos/test_repo_9/dotGit/HEAD | 1 - .../test_repos/test_repo_9/dotGit/config | 7 - .../test_repos/test_repo_9/dotGit/description | 1 - test_data/test_repos/test_repo_9/dotGit/index | Bin 145 -> 0 bytes .../test_repo_9/dotGit/info/exclude | 6 - .../test_repos/test_repo_9/dotGit/logs/HEAD | 3 - .../test_repo_9/dotGit/logs/refs/heads/master | 3 - .../10/fa14c5ab0134436e2ae435138bf921eb477c60 | Bin 784 -> 0 bytes .../3a/76f3781306faf5612017bf18a4b4bdb9f927bf | Bin 138 -> 0 bytes .../41/42082bcb939bbc17985a69ba748491ac6b62a5 | Bin 281 -> 0 bytes .../49/8b267a8c7812490d6479839c5577eaaec79d62 | Bin 77 -> 0 bytes .../60/c9e47f150a6b713e247e6105b77f1b961f844f | Bin 23 -> 0 bytes .../61/87dbf4390fc6e28445dd3d988aefb9d1111988 | Bin 708 -> 0 bytes .../65/57c92612d3b35979bd426d429255b3bf9fab74 | Bin 133 -> 0 bytes .../6a/756416384c210ada2631f17862f5c01fffa478 | Bin 946 -> 0 bytes .../6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 | Bin 114 -> 0 bytes .../6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 | Bin 2176 -> 0 bytes .../80/8b12c5ca4b142367932e7045d555a639fc148c | Bin 209 -> 0 bytes .../80/ba94135cc378364af9d3cb2450df48e51faf2c | Bin 1247 -> 0 bytes .../8d/1fb60d2d80f0590f191ed5ace1e45ef780909a | 2 - .../9e/523225b31add24e72f2feb0b2645cfb36542dc | 3 - .../a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 | 3 - .../a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d | Bin 57 -> 0 bytes .../a5/196d1be8fb59edf8062bef36d3a602e0812139 | 1 - .../a5/d7b84a673458d14d9aab082183a1968c2c7492 | Bin 299 -> 0 bytes .../b5/8d1184a9d43a39c0d95f32453efc78581877d6 | Bin 529 -> 0 bytes .../c1/f3c6341548a65be1eded56b4f7cacec7fe9090 | Bin 59 -> 0 bytes .../c9/8e6c52cbd1f50de572ff12a3441271fccff705 | Bin 158 -> 0 bytes .../cb/089cd89a7d7686d284d8761201649346b5aa1c | Bin 37 -> 0 bytes .../cb/19a50e8cdeb7011eccdb13f3b739f00d775bab | 2 - .../d2/74003914c707212cbe84e3e466a00013ccb639 | Bin 154 -> 0 bytes .../e6/73bb3980f3c286291809e05f80873852bc3e9c | Bin 1646 -> 0 bytes .../e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 | Bin 59 -> 0 bytes .../ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e | 2 - .../f9/f2f36962fa38ca4525b99ef702fba03e3a79a7 | Bin 220 -> 0 bytes .../fe/f3190e94723e78847ab9f0daaa15add4ffd4ef | Bin 58 -> 0 bytes .../test_repo_9/dotGit/refs/heads/master | 1 - .../test_repos/test_repo_9/server.test.py | 9 - testdata/baseline/baseline.csv | 2 + testdata/baseline/baseline.json | 40 + testdata/baseline/baseline.sarif | 6 + testdata/config/allow_aws_re.toml | 9 + testdata/config/allow_commit.toml | 9 + .../config/allow_global_aws_re.toml | 6 +- testdata/config/allow_path.toml | 9 + testdata/config/bad_entropy_group.toml | 8 + testdata/config/base.toml | 10 + testdata/config/entropy_group.toml | 8 + testdata/config/escaped_character_group.toml | 8 + testdata/config/extend_1.toml | 10 + testdata/config/extend_2.toml | 10 + testdata/config/extend_3.toml | 9 + testdata/config/generic.toml | 8 + testdata/config/generic_with_py_path.toml | 36 + testdata/config/path_only.toml | 6 + testdata/config/simple.toml | 222 ++ testdata/expected/git/small-branch-foo.txt | 17 + testdata/expected/git/small.txt | 67 + testdata/expected/report/csv_simple.csv | 2 + testdata/expected/report/empty.json | 1 + testdata/expected/report/json_simple.json | 21 + testdata/expected/report/sarif_simple.sarif | 301 ++ testdata/repos/nogit/main.go | 24 + testdata/repos/small/README.md | 2 + testdata/repos/small/api/api.go | 7 + testdata/repos/small/dotGit/COMMIT_EDITMSG | 1 + testdata/repos/small/dotGit/FETCH_HEAD | 1 + testdata/repos/small/dotGit/HEAD | 1 + testdata/repos/small/dotGit/ORIG_HEAD | 1 + .../repos/small}/dotGit/config | 6 +- .../repos/small}/dotGit/description | 0 testdata/repos/small/dotGit/index | Bin 0 -> 317 bytes .../repos/small}/dotGit/info/exclude | 0 testdata/repos/small/dotGit/logs/HEAD | 13 + .../small/dotGit/logs/refs/heads/api-pkg | 1 + .../repos/small/dotGit/logs/refs/heads/foo | 3 + .../repos/small/dotGit/logs/refs/heads/main | 2 + .../dotGit/logs/refs/heads/remove-secrets | 3 + .../dotGit/logs/refs/remotes/origin/HEAD | 1 + .../dotGit/logs/refs/remotes/origin/api-pkg | 1 + .../small/dotGit/logs/refs/remotes/origin/foo | 1 + .../dotGit/logs/refs/remotes/origin/main | 1 + .../02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 | 1 + .../15/2888a42422b2ff5868b8d003d626120a9cb738 | Bin 0 -> 86 bytes .../2e/1db472eeba53f06c4026ae4566ea022e36598e | Bin 0 -> 618 bytes .../49/1504d5a31946ce75e22554cc34203d8e5ff3ca | Bin 0 -> 175 bytes .../5c/547e4215d9594c3935bdfefdf4f500016a4112 | Bin 0 -> 51 bytes .../78/9ba677976d5db481de55c799d67acbf8e3f16a | Bin 0 -> 51 bytes .../90/6335481df9a4b48906c90318b4fac76b67fe73 | 3 + .../9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad | Bin 0 -> 196 bytes .../a1/22b33c6bad3ee54724f52f2caad385ab1982ab | Bin 0 -> 163 bytes .../a5/caae6d742e49a33982f1fdc608ce861ea59be5 | Bin 0 -> 134 bytes .../a9/aa0c942dcef669a94f207a77426106b25efd1a | Bin 0 -> 143 bytes .../bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886 | Bin 0 -> 116 bytes .../d8/32479114dc6be7207edc7c37ce91dd11b93161 | Bin 0 -> 80 bytes .../da/2622b4d97e32c5801511244b809144b6b3ea78 | Bin 0 -> 51 bytes .../e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb | Bin 0 -> 143 bytes .../f1/b58b97808f8e744f6a23c693859df5b5968901 | Bin 0 -> 176 bytes ...dc2976b84768d0829c75cc8d8fc4d849be62cd.idx | Bin 0 -> 1324 bytes ...c2976b84768d0829c75cc8d8fc4d849be62cd.pack | Bin 0 -> 2116 bytes testdata/repos/small/dotGit/packed-refs | 2 + .../repos/small/dotGit/refs/heads/api-pkg | 1 + testdata/repos/small/dotGit/refs/heads/foo | 1 + testdata/repos/small/dotGit/refs/heads/main | 1 + .../small/dotGit/refs/heads/remove-secrets | 1 + .../small/dotGit/refs/remotes/origin/HEAD | 1 + .../small/dotGit/refs/remotes/origin/api-pkg | 1 + .../small/dotGit/refs/remotes/origin/foo | 1 + .../small/dotGit/refs/remotes/origin/main | 1 + testdata/repos/small/main.go | 27 + testdata/tmp/note.txt | 1 + version/version.go | 6 - 640 files changed, 14715 insertions(+), 6476 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/maintenance.md create mode 100644 .github/workflows/gitleaks.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitleaksignore create mode 100644 .goreleaser.yml create mode 100644 .pre-commit-hooks.yaml delete mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md create mode 100644 USERS.md create mode 100644 cmd/detect.go create mode 100644 cmd/generate/config/main.go create mode 100644 cmd/generate/config/rules/adafruit.go create mode 100644 cmd/generate/config/rules/adobe.go create mode 100644 cmd/generate/config/rules/age.go create mode 100644 cmd/generate/config/rules/airtable.go create mode 100644 cmd/generate/config/rules/algolia.go create mode 100644 cmd/generate/config/rules/alibaba.go create mode 100644 cmd/generate/config/rules/asana.go create mode 100644 cmd/generate/config/rules/atlassian.go create mode 100644 cmd/generate/config/rules/aws.go create mode 100644 cmd/generate/config/rules/beamer.go create mode 100644 cmd/generate/config/rules/bitbucket.go create mode 100644 cmd/generate/config/rules/bittrex.go create mode 100644 cmd/generate/config/rules/clojars.go create mode 100644 cmd/generate/config/rules/codecov.go create mode 100644 cmd/generate/config/rules/coinbase.go create mode 100644 cmd/generate/config/rules/config.tmpl create mode 100644 cmd/generate/config/rules/confluent.go create mode 100644 cmd/generate/config/rules/contentful.go create mode 100644 cmd/generate/config/rules/databricks.go create mode 100644 cmd/generate/config/rules/datadog.go create mode 100644 cmd/generate/config/rules/digitalocean.go create mode 100644 cmd/generate/config/rules/discord.go create mode 100644 cmd/generate/config/rules/doppler.go create mode 100644 cmd/generate/config/rules/droneci.go create mode 100644 cmd/generate/config/rules/dropbox.go create mode 100644 cmd/generate/config/rules/duffel.go create mode 100644 cmd/generate/config/rules/dynatrace.go create mode 100644 cmd/generate/config/rules/easypost.go create mode 100644 cmd/generate/config/rules/etsy.go create mode 100644 cmd/generate/config/rules/facebook.go create mode 100644 cmd/generate/config/rules/fastly.go create mode 100644 cmd/generate/config/rules/finicity.go create mode 100644 cmd/generate/config/rules/finnhub.go create mode 100644 cmd/generate/config/rules/flickr.go create mode 100644 cmd/generate/config/rules/flutterwave.go create mode 100644 cmd/generate/config/rules/frameio.go create mode 100644 cmd/generate/config/rules/freshbooks.go create mode 100644 cmd/generate/config/rules/gcp.go create mode 100644 cmd/generate/config/rules/generic.go create mode 100644 cmd/generate/config/rules/github.go create mode 100644 cmd/generate/config/rules/gitlab.go create mode 100644 cmd/generate/config/rules/gitter.go create mode 100644 cmd/generate/config/rules/gocardless.go create mode 100644 cmd/generate/config/rules/grafana.go create mode 100644 cmd/generate/config/rules/hashicorp.go create mode 100644 cmd/generate/config/rules/heroku.go create mode 100644 cmd/generate/config/rules/hubspot.go create mode 100644 cmd/generate/config/rules/intercom.go create mode 100644 cmd/generate/config/rules/jwt.go create mode 100644 cmd/generate/config/rules/kraken.go create mode 100644 cmd/generate/config/rules/kucoin.go create mode 100644 cmd/generate/config/rules/launchdarkly.go create mode 100644 cmd/generate/config/rules/linear.go create mode 100644 cmd/generate/config/rules/linkedin.go create mode 100644 cmd/generate/config/rules/lob.go create mode 100644 cmd/generate/config/rules/mailchimp.go create mode 100644 cmd/generate/config/rules/mailgun.go create mode 100644 cmd/generate/config/rules/mapbox.go create mode 100644 cmd/generate/config/rules/mattermost.go create mode 100644 cmd/generate/config/rules/messagebird.go create mode 100644 cmd/generate/config/rules/netlify.go create mode 100644 cmd/generate/config/rules/newrelic.go create mode 100644 cmd/generate/config/rules/npm.go create mode 100644 cmd/generate/config/rules/nytimes.go create mode 100644 cmd/generate/config/rules/okta.go create mode 100644 cmd/generate/config/rules/plaid.go create mode 100644 cmd/generate/config/rules/planetscale.go create mode 100644 cmd/generate/config/rules/postman.go create mode 100644 cmd/generate/config/rules/prefect.go create mode 100644 cmd/generate/config/rules/privatekey.go create mode 100644 cmd/generate/config/rules/pulumi.go create mode 100644 cmd/generate/config/rules/pypi.go create mode 100644 cmd/generate/config/rules/rapidapi.go create mode 100644 cmd/generate/config/rules/readme.go create mode 100644 cmd/generate/config/rules/rubygems.go create mode 100644 cmd/generate/config/rules/rule.go create mode 100644 cmd/generate/config/rules/sendbird.go create mode 100644 cmd/generate/config/rules/sendgrid.go create mode 100644 cmd/generate/config/rules/sendinblue.go create mode 100644 cmd/generate/config/rules/sentry.go create mode 100644 cmd/generate/config/rules/shippo.go create mode 100644 cmd/generate/config/rules/shopify.go create mode 100644 cmd/generate/config/rules/sidekiq.go create mode 100644 cmd/generate/config/rules/slack.go create mode 100644 cmd/generate/config/rules/square.go create mode 100644 cmd/generate/config/rules/squarespace.go create mode 100644 cmd/generate/config/rules/stopwords.go create mode 100644 cmd/generate/config/rules/stripe.go create mode 100644 cmd/generate/config/rules/sumologic.go create mode 100644 cmd/generate/config/rules/teams.go create mode 100644 cmd/generate/config/rules/telegram.go create mode 100644 cmd/generate/config/rules/travisci.go create mode 100644 cmd/generate/config/rules/trello.go create mode 100644 cmd/generate/config/rules/twilio.go create mode 100644 cmd/generate/config/rules/twitch.go create mode 100644 cmd/generate/config/rules/twitter.go create mode 100644 cmd/generate/config/rules/typeform.go create mode 100644 cmd/generate/config/rules/vault.go create mode 100644 cmd/generate/config/rules/yandex.go create mode 100644 cmd/generate/config/rules/zendesk.go create mode 100644 cmd/generate/secrets/regen.go create mode 100644 cmd/protect.go create mode 100644 cmd/root.go create mode 100644 cmd/version.go create mode 100644 config/allowlist.go create mode 100644 config/allowlist_test.go delete mode 100644 config/default.go create mode 100644 config/gitleaks.toml create mode 100644 config/rule.go create mode 100644 config/utils.go create mode 100644 detect/baseline.go create mode 100644 detect/baseline_test.go create mode 100644 detect/detect.go create mode 100644 detect/detect_test.go create mode 100644 detect/git/git.go create mode 100644 detect/git/git_test.go create mode 100644 detect/location.go create mode 100644 detect/location_test.go create mode 100644 detect/utils.go delete mode 100644 examples/leaky-repo.toml delete mode 100644 examples/pre-commit.example delete mode 100644 examples/regex_and_entropy_config.toml delete mode 100644 examples/simple_regex_and_allowlist_config.toml delete mode 100644 examples/simple_regex_config.toml delete mode 100644 hosts/github.go delete mode 100644 hosts/gitlab.go delete mode 100644 hosts/host.go delete mode 100644 hosts/hosts_test.go delete mode 100644 manager/manager.go delete mode 100644 manager/manager_test.go delete mode 100644 manager/report.go delete mode 100644 manager/sarif.go delete mode 100644 options/options.go delete mode 100644 options/options_test.go create mode 100644 report/constants.go create mode 100644 report/csv.go create mode 100644 report/csv_test.go create mode 100644 report/finding.go create mode 100644 report/finding_test.go create mode 100644 report/json.go create mode 100644 report/json_test.go create mode 100644 report/report.go create mode 100644 report/report_test.go create mode 100644 report/sarif.go create mode 100644 report/sarif_test.go delete mode 100644 scan/repo.go delete mode 100644 scan/rule.go delete mode 100644 scan/scan.go delete mode 100644 scan/scan_test.go create mode 100644 scripts/pre-commit.py delete mode 100644 test_data/test_configs/allowlist_commit.toml delete mode 100644 test_data/test_configs/aws_key.toml delete mode 100644 test_data/test_configs/aws_key_allowlist_files.toml delete mode 100644 test_data/test_configs/aws_key_allowlist_python_files.toml delete mode 100644 test_data/test_configs/aws_key_aws_allowlisted.toml delete mode 100644 test_data/test_configs/aws_key_file_regex.toml delete mode 100644 test_data/test_configs/aws_key_global_allowlist_file.toml delete mode 100644 test_data/test_configs/aws_key_global_allowlist_path.toml delete mode 100644 test_data/test_configs/aws_key_local_owner_allowlist_repo.toml delete mode 100644 test_data/test_configs/bad_aws_key.toml delete mode 100644 test_data/test_configs/bad_aws_key_file_regex.toml delete mode 100644 test_data/test_configs/bad_entropy_1.toml delete mode 100644 test_data/test_configs/bad_entropy_2.toml delete mode 100644 test_data/test_configs/bad_entropy_3.toml delete mode 100644 test_data/test_configs/bad_entropy_4.toml delete mode 100644 test_data/test_configs/bad_entropy_5.toml delete mode 100644 test_data/test_configs/bad_entropy_6.toml delete mode 100644 test_data/test_configs/bad_entropy_7.toml delete mode 100644 test_data/test_configs/bad_regex_aws_key.toml delete mode 100644 test_data/test_configs/entropy.toml delete mode 100644 test_data/test_configs/generic.toml delete mode 100644 test_data/test_configs/large.toml delete mode 100644 test_data/test_configs/large_with_global_allowlist_regex.toml delete mode 100644 test_data/test_configs/regex_entropy.toml delete mode 100644 test_data/test_configs/regex_filename.toml delete mode 100644 test_data/test_configs/regex_filepath.toml delete mode 100644 test_data/test_configs/regex_filepath_filename.toml delete mode 100644 test_data/test_entropy.json delete mode 100644 test_data/test_local_owner_aws_leak.json delete mode 100644 test_data/test_local_owner_aws_leak_allowlist_repo.json delete mode 100644 test_data/test_local_owner_aws_leak_depth_2.json delete mode 100644 test_data/test_local_repo_eight.json delete mode 100644 test_data/test_local_repo_five_at_latest_commit.json delete mode 100644 test_data/test_local_repo_five_commit.json delete mode 100644 test_data/test_local_repo_five_files_at_commit.json delete mode 100644 test_data/test_local_repo_five_files_at_latest_commit.json delete mode 100644 test_data/test_local_repo_four_alt_config_entropy.json delete mode 100644 test_data/test_local_repo_four_leaks_commit_timerange.json delete mode 100644 test_data/test_local_repo_nine_aws_leak.json delete mode 100644 test_data/test_local_repo_one_aws_leak.json delete mode 100644 test_data/test_local_repo_one_aws_leak_and_file_leak.json delete mode 100644 test_data/test_local_repo_one_aws_leak_commit.json delete mode 100644 test_data/test_local_repo_one_aws_leak_uncommitted.json delete mode 100644 test_data/test_local_repo_seven_aws_leak_uncommitted.json delete mode 100644 test_data/test_local_repo_six.json delete mode 100644 test_data/test_local_repo_six_filename.json delete mode 100644 test_data/test_local_repo_six_filepath.json delete mode 100644 test_data/test_local_repo_six_filepath_filename.json delete mode 100644 test_data/test_local_repo_six_leaks_since_date.json delete mode 100644 test_data/test_local_repo_six_leaks_until_date.json delete mode 100644 test_data/test_local_repo_six_path_globally_allowlisted.json delete mode 100644 test_data/test_local_repo_three_leaks.json delete mode 100644 test_data/test_local_repo_two_allowlist_commits.json delete mode 100644 test_data/test_local_repo_two_leaks.json delete mode 100644 test_data/test_local_repo_two_leaks_commit_from.json delete mode 100644 test_data/test_local_repo_two_leaks_commit_range.json delete mode 100644 test_data/test_local_repo_two_leaks_commit_to.json delete mode 100644 test_data/test_local_repo_two_leaks_commit_to_from.json delete mode 100644 test_data/test_local_repo_two_leaks_deletion.json delete mode 100644 test_data/test_local_repo_two_leaks_file_commit_range.json delete mode 100644 test_data/test_options/test_local_repo_commits.txt delete mode 100644 test_data/test_regex_entropy.json delete mode 100644 test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_1/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_1/dotGit/config delete mode 100644 test_data/test_repos/test_repo_1/dotGit/index delete mode 100644 test_data/test_repos/test_repo_1/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e delete mode 100644 test_data/test_repos/test_repo_1/dotGit/objects/fe/f3190e94723e78847ab9f0daaa15add4ffd4ef delete mode 100644 test_data/test_repos/test_repo_1/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_1/server.test.py delete mode 100644 test_data/test_repos/test_repo_2/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_2/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_2/dotGit/config delete mode 100644 test_data/test_repos/test_repo_2/dotGit/description delete mode 100644 test_data/test_repos/test_repo_2/dotGit/index delete mode 100644 test_data/test_repos/test_repo_2/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_2/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 delete mode 100644 test_data/test_repos/test_repo_2/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_2/no_secrets.md delete mode 100644 test_data/test_repos/test_repo_2/secrets.md delete mode 100644 test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_3/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_3/dotGit/config delete mode 100644 test_data/test_repos/test_repo_3/dotGit/description delete mode 100644 test_data/test_repos/test_repo_3/dotGit/index delete mode 100644 test_data/test_repos/test_repo_3/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_3/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev delete mode 100644 test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/82/4b8a2b468fcfa244e096bd54b83508b85ef488 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 delete mode 100644 test_data/test_repos/test_repo_3/dotGit/refs/heads/dev delete mode 100644 test_data/test_repos/test_repo_3/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_3/no_secrets.md delete mode 100644 test_data/test_repos/test_repo_3/secrets.md delete mode 100644 test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_4/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_4/dotGit/config delete mode 100644 test_data/test_repos/test_repo_4/dotGit/description delete mode 100644 test_data/test_repos/test_repo_4/dotGit/index delete mode 100644 test_data/test_repos/test_repo_4/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_4/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev delete mode 100644 test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/0e/cd6aeaa0b76f5cad8077ae5be8420457403bfc delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/17/471a5fda722a9e423f1a0d3f0d267ea009d41c delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/4b/c47c2d3aaa25385e3354ea34136456c2260a12 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/64/99d414147df9f56cbecd26ca710c39e4834024 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/67/c45b6048e42a2bd5512662ca6cd2bfc74c7842 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/7b/2eba252004b7c867413def2a0984d545daab8b delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/82/4b8a2b468fcfa244e096bd54b83508b85ef488 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/82/8595723b76e4a35b5253d9f2ccb4f897f1845a delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/96/c1c0a3632af796efd3942cc1d81d7af48ead3e delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/b2/eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/b4/70f07d2aaf2b537808b285cab667259b4e0ca7 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/c1/bfab622827026dbd2eba4e2d75a8c523e55dc2 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 delete mode 100644 test_data/test_repos/test_repo_4/dotGit/refs/heads/dev delete mode 100644 test_data/test_repos/test_repo_4/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_4/gitleaks.toml delete mode 100644 test_data/test_repos/test_repo_4/no_secrets.md delete mode 100644 test_data/test_repos/test_repo_4/secrets.md delete mode 100644 test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_5/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_5/dotGit/config delete mode 100644 test_data/test_repos/test_repo_5/dotGit/description delete mode 100644 test_data/test_repos/test_repo_5/dotGit/index delete mode 100644 test_data/test_repos/test_repo_5/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_5/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/1f/2a4abc47dabf991e6af6f9770867ce0ac1f360 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/97/2ea8fcf4f3d9a216644c8eb11df1382b6e02ab delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/a4/c9fb737d5552fd96fce5cc7eedb23353ba9ed0 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/ca/71fcdeda15f25f0cc661d90e8785c255925c27 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e delete mode 100644 test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 delete mode 100644 test_data/test_repos/test_repo_5/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_5/notes.md delete mode 100644 test_data/test_repos/test_repo_5/secrets.py delete mode 100644 test_data/test_repos/test_repo_6/application.yaml delete mode 100644 test_data/test_repos/test_repo_6/config/application.properties delete mode 100644 test_data/test_repos/test_repo_6/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_6/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_6/dotGit/config delete mode 100644 test_data/test_repos/test_repo_6/dotGit/description delete mode 100644 test_data/test_repos/test_repo_6/dotGit/index delete mode 100644 test_data/test_repos/test_repo_6/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_6/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/dd/cd9ac6904950dcc48e4c04ba043707e9e0117f delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e delete mode 100644 test_data/test_repos/test_repo_6/dotGit/objects/fe/f3190e94723e78847ab9f0daaa15add4ffd4ef delete mode 100644 test_data/test_repos/test_repo_6/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_6/server.test.py delete mode 100644 test_data/test_repos/test_repo_7/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_7/dotGit/config delete mode 100644 test_data/test_repos/test_repo_7/dotGit/description delete mode 100644 test_data/test_repos/test_repo_7/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_7/file delete mode 100644 test_data/test_repos/test_repo_8/README.md delete mode 100644 test_data/test_repos/test_repo_8/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_8/dotGit/description delete mode 100644 test_data/test_repos/test_repo_8/dotGit/index delete mode 100644 test_data/test_repos/test_repo_8/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_8/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/0c/4994567bb2c77bebe47868d3bf1dd287d20452 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/0c/79fa4384c973e9a6fe794491492da04ea289aa delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/16/f577ee2b9f9e185ae792092d779dc7e9a5d90f delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/17/f5d7f87925bdad6793b0fc7e338378ffb93166 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/23/efedf4961168dc048e896f68eda78bcfb8e51f delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/2a/5fecc2737429b02047e5a99d9c0ac6e76a3ac2 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/36/09cadde7b3c8323d95943d6edfcf9c7a58dbdf delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/3c/cb6c2b338c176bbb7de1154cd7b61d0f6155ce delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/46/7192699b9e6aaf85401389e1db50ce9685ab56 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/54/759376585b8a4e0318b1ecc0e770f69a6c4230 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/61/4a498fb4c38af5f5909718481e8b371f118901 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/64/b4391ddf2b399fb5218ee44cf90111d3f7ca9a delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/64/dbb271509f9b9647106da59914a6f5320de7c4 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/74/8f11eaf2c38c3cf0ac6a22e44208777e79fa6f delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/75/ead74004eb27c7e9e1ddf391f089ea0441f242 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/84/5ebbfaf21dd869057da0e2a3494f2b8dea8cde delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/92/67bc86ec1497471cbc6f3308f3527f7ef34b9d delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/b0/e4c4f24e7787b8ae08521f56b5dd9a76f90011 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/b2/6121273b1bf2eb385ae14ad0a0f186e3a47f4b delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/b3/aeb0f5be4a83bbeaee1d6ae5b755502020819e delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/b3/bec734a41357c480b7856e0298de649a5fef14 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/b9/01f643b1eeeaeb7ff12931213bd0d9a47254d1 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/ce/6e0398cd8a40085cad12a8f4c96e580c2200c1 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/ce/7e8177bbf8a172c06b6a1e370a374d5c19f660 delete mode 100644 test_data/test_repos/test_repo_8/dotGit/objects/fc/8b31a54e5975bc41e901965e0c7dee18ed202f delete mode 100644 test_data/test_repos/test_repo_8/dotGit/packed-refs delete mode 100644 test_data/test_repos/test_repo_8/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_8/dotGit/refs/remotes/origin/HEAD delete mode 100644 test_data/test_repos/test_repo_8/dummy.txt delete mode 100644 test_data/test_repos/test_repo_8/ufos_might_be_real.txt delete mode 100644 test_data/test_repos/test_repo_9/dotGit/COMMIT_EDITMSG delete mode 100644 test_data/test_repos/test_repo_9/dotGit/HEAD delete mode 100644 test_data/test_repos/test_repo_9/dotGit/config delete mode 100644 test_data/test_repos/test_repo_9/dotGit/description delete mode 100644 test_data/test_repos/test_repo_9/dotGit/index delete mode 100644 test_data/test_repos/test_repo_9/dotGit/info/exclude delete mode 100644 test_data/test_repos/test_repo_9/dotGit/logs/HEAD delete mode 100644 test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/61/87dbf4390fc6e28445dd3d988aefb9d1111988 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/6c/9406b7d9320db083eca69b3f8bee9a6c7b50d4 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/80/ba94135cc378364af9d3cb2450df48e51faf2c delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/a5/196d1be8fb59edf8062bef36d3a602e0812139 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/a5/d7b84a673458d14d9aab082183a1968c2c7492 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/cb/19a50e8cdeb7011eccdb13f3b739f00d775bab delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/d2/74003914c707212cbe84e3e466a00013ccb639 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/f9/f2f36962fa38ca4525b99ef702fba03e3a79a7 delete mode 100644 test_data/test_repos/test_repo_9/dotGit/objects/fe/f3190e94723e78847ab9f0daaa15add4ffd4ef delete mode 100644 test_data/test_repos/test_repo_9/dotGit/refs/heads/master delete mode 100644 test_data/test_repos/test_repo_9/server.test.py create mode 100644 testdata/baseline/baseline.csv create mode 100644 testdata/baseline/baseline.json create mode 100644 testdata/baseline/baseline.sarif create mode 100644 testdata/config/allow_aws_re.toml create mode 100644 testdata/config/allow_commit.toml rename test_data/test_configs/bad_aws_key_global_allowlist_file.toml => testdata/config/allow_global_aws_re.toml (56%) create mode 100644 testdata/config/allow_path.toml create mode 100755 testdata/config/bad_entropy_group.toml create mode 100644 testdata/config/base.toml create mode 100755 testdata/config/entropy_group.toml create mode 100644 testdata/config/escaped_character_group.toml create mode 100644 testdata/config/extend_1.toml create mode 100644 testdata/config/extend_2.toml create mode 100644 testdata/config/extend_3.toml create mode 100644 testdata/config/generic.toml create mode 100644 testdata/config/generic_with_py_path.toml create mode 100644 testdata/config/path_only.toml create mode 100644 testdata/config/simple.toml create mode 100644 testdata/expected/git/small-branch-foo.txt create mode 100644 testdata/expected/git/small.txt create mode 100644 testdata/expected/report/csv_simple.csv create mode 100644 testdata/expected/report/empty.json create mode 100644 testdata/expected/report/json_simple.json create mode 100644 testdata/expected/report/sarif_simple.sarif create mode 100644 testdata/repos/nogit/main.go create mode 100644 testdata/repos/small/README.md create mode 100644 testdata/repos/small/api/api.go create mode 100644 testdata/repos/small/dotGit/COMMIT_EDITMSG create mode 100644 testdata/repos/small/dotGit/FETCH_HEAD create mode 100644 testdata/repos/small/dotGit/HEAD create mode 100644 testdata/repos/small/dotGit/ORIG_HEAD rename {test_data/test_repos/test_repo_8 => testdata/repos/small}/dotGit/config (68%) rename {test_data/test_repos/test_repo_1 => testdata/repos/small}/dotGit/description (100%) create mode 100644 testdata/repos/small/dotGit/index rename {test_data/test_repos/test_repo_1 => testdata/repos/small}/dotGit/info/exclude (100%) create mode 100644 testdata/repos/small/dotGit/logs/HEAD create mode 100644 testdata/repos/small/dotGit/logs/refs/heads/api-pkg create mode 100644 testdata/repos/small/dotGit/logs/refs/heads/foo create mode 100644 testdata/repos/small/dotGit/logs/refs/heads/main create mode 100644 testdata/repos/small/dotGit/logs/refs/heads/remove-secrets create mode 100644 testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD create mode 100644 testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg create mode 100644 testdata/repos/small/dotGit/logs/refs/remotes/origin/foo create mode 100644 testdata/repos/small/dotGit/logs/refs/remotes/origin/main create mode 100644 testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 create mode 100644 testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 create mode 100644 testdata/repos/small/dotGit/objects/2e/1db472eeba53f06c4026ae4566ea022e36598e create mode 100644 testdata/repos/small/dotGit/objects/49/1504d5a31946ce75e22554cc34203d8e5ff3ca create mode 100644 testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 create mode 100644 testdata/repos/small/dotGit/objects/78/9ba677976d5db481de55c799d67acbf8e3f16a create mode 100644 testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 create mode 100644 testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad create mode 100644 testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab create mode 100644 testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 create mode 100644 testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a create mode 100644 testdata/repos/small/dotGit/objects/bc/f47ef84f29bb7ed6e653d61fccd30d0ecce886 create mode 100644 testdata/repos/small/dotGit/objects/d8/32479114dc6be7207edc7c37ce91dd11b93161 create mode 100644 testdata/repos/small/dotGit/objects/da/2622b4d97e32c5801511244b809144b6b3ea78 create mode 100644 testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb create mode 100644 testdata/repos/small/dotGit/objects/f1/b58b97808f8e744f6a23c693859df5b5968901 create mode 100644 testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.idx create mode 100644 testdata/repos/small/dotGit/objects/pack/pack-2cdc2976b84768d0829c75cc8d8fc4d849be62cd.pack create mode 100644 testdata/repos/small/dotGit/packed-refs create mode 100644 testdata/repos/small/dotGit/refs/heads/api-pkg create mode 100644 testdata/repos/small/dotGit/refs/heads/foo create mode 100644 testdata/repos/small/dotGit/refs/heads/main create mode 100644 testdata/repos/small/dotGit/refs/heads/remove-secrets create mode 100644 testdata/repos/small/dotGit/refs/remotes/origin/HEAD create mode 100644 testdata/repos/small/dotGit/refs/remotes/origin/api-pkg create mode 100644 testdata/repos/small/dotGit/refs/remotes/origin/foo create mode 100644 testdata/repos/small/dotGit/refs/remotes/origin/main create mode 100644 testdata/repos/small/main.go create mode 100644 testdata/tmp/note.txt delete mode 100644 version/version.go diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5de42d831..c9e8d9176 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,3 @@ # These are supported funding model platforms github: [zricethezav] -custom: ["https://www.paypal.me/zricethezav"] diff --git a/.github/ISSUE_TEMPLATE/maintenance.md b/.github/ISSUE_TEMPLATE/maintenance.md new file mode 100644 index 000000000..7f42bb96d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/maintenance.md @@ -0,0 +1,16 @@ +--- +name: Maintenance request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Additional context** +Add any other context or screenshots about the feature request here. + +cc @zricethezav diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml new file mode 100644 index 000000000..baca755c6 --- /dev/null +++ b/.github/workflows/gitleaks.yml @@ -0,0 +1,13 @@ +name: gitleaks +on: [pull_request, push, workflow_dispatch] +jobs: + scan: + name: gitleaks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..432c070b1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Create and publish a Docker image + +on: + release: + types: [published] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@8b122486cedac8393e77aa9734c3528886e4a1a8 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@dc7b9719a96d48369863986a06765841d7ea23f6 + + - name: Log in to Docker Hub + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + username: ${{ github.actor }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to the Container registry + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: | + zricethezav/gitleaks + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@e551b19e49efd4e98792db7592c17c09b89db8d8 + with: + platforms: linux/amd64,linux/arm64 + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..23043bf67 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Test + +on: + pull_request: + branches: + - "*" + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.19 + + - name: Build + run: go build -v ./... + + - name: Test + run: make test + + - name: Validate Config + run: cd cmd/generate/config && go run main.go diff --git a/.gitignore b/.gitignore index ddf01fd2a..49abd80e2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,15 @@ *.dylib *.DS_STORE *.idea +*.got gitleaks build +# configs +.gitleaks.toml +cmd/generate/config/gitleaks.toml + # Test binary *.out + +dist/ diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 000000000..f763c3af3 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,744 @@ +418edf165dbb63d6f46993ae8f8818ffd87ea582:cmd/generate/config/rules/jwt.go:jwt:17 +418edf165dbb63d6f46993ae8f8818ffd87ea582:cmd/generate/config/rules/jwt.go:jwt:19 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:46 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:48 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:50 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:52 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:54 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:55 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:56 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:57 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:22 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:24 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:28 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:29 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-sensitive-url:164 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-sensitive-url:170 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:120 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:126 +525d9792b1e3670b4630b8fcc385ca22e8544f9b:detect/detect_test.go:sidekiq-secret:142 +31650f01e76858ce7a0490943426e84a0824bbc8:config/config_test.go:aws-access-token:31 +5ed010c944ccc715cb9245abafd4e97d98d75e9f:config/config_test.go:aws-access-token:31 +ad7509e3b47331ce9586743ace635422843b695b:cmd/generate/config/rules/privatekey.go:private-key:22 +717cf1b10be1625875199eca8cdf48883348985f:README.md:aws-access-token:23 +3474c58c9e25fe2b1cee855a35bd1bf8a8c0fae8:cmd/generate/config/rules/generic.go:clojars-api-token:38 +a42b32bdf11b6f4ea5c32ec76a1731b4b0c5e52a:cmd/generate/config/rules/generic.go:generic-api-key:40 +a42b32bdf11b6f4ea5c32ec76a1731b4b0c5e52a:cmd/generate/config/rules/generic.go:generic-api-key:41 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:50 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:60 +3e5e63956ea770be734dcb7642cf515910154fb5:detect/detect_test.go:aws-access-token:61 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:pypi-upload-token:29 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:51 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:73 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:81 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:89 +33082a996774ba4c8ad4ba26fd219d77497eb960:README.md:sidekiq-secret:43 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:98 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:235 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:236 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:253 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:254 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:278 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:279 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:343 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:344 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:362 +57d2d345b6b6ea220be9d99792b21a75359555c0:detect/detect_test.go:aws-access-token:363 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:pypi-upload-token:27 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:49 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:71 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:79 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:87 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:120 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:96 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:128 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:118 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:150 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:126 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:discord-api-token:166 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:175 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:183 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:238 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:239 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:256 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:257 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:281 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:282 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:356 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:357 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:375 +6e72472b6019d29eaa4b76b39700cd2418741f0c:detect/detect_test.go:aws-access-token:376 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:148 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:27 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:32 +17b5540fb16bd9816d2a3a83f65cedf5918eaf70:detect/detect_test.go:pypi-upload-token:33 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:discord-api-token:164 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:173 +c9bc6b46087e700a42eb3492cf2053b7da4a6d9e:detect/detect_test.go:aws-access-token:181 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:43 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:60 +ce42947cae32cda8d5d8813c1a8ce82eb06f018e:detect/git_test.go:aws-access-token:85 +b8141713e89f5acec500c7a62415f0f1cb7234dc:README.md:discord-client-secret:273 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:aws-access-token:130 +b8141713e89f5acec500c7a62415f0f1cb7234dc:README.md:discord-client-secret:289 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:discord-client-secret:251 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:README.md:discord-client-secret:267 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/detect_test.go:aws-access-token:33 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/files_test.go:aws-access-token:32 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:detect/files_test.go:aws-access-token:50 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:config/config_test.go:generic-api-key:133 +80d29764a0bc0f269607d3eb7b2774a0f31e5da3:detect/detect_test.go:aws-access-token:123 +80d29764a0bc0f269607d3eb7b2774a0f31e5da3:testdata/config/allow_global_aws_re.toml:aws-access-token:8 +4acd7a3c8d20b7116a32f9bbade6a3cf15f741e4:detect/detect_test.go:aws-access-token:117 +f0b8d26c9988af725132c100dda5051586a3026e:README.md:discord-client-secret:225 +98d5648f6e54ea84ca915c73fff88ad3bc5809e0:config/config_test.go:generic-api-key:144 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:121 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:122 +93f292c3dfa2649ef91f8925b623e79546fa992e:README.md:aws-access-token:157 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:aws-access-token:31 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:32 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:33 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:50 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/files_test.go:aws-access-token:51 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:42 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:44 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:58 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:60 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:82 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/git_test.go:aws-access-token:83 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:generic-api-key:133 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/config/allow_aws_re.toml:aws-access-token:9 +93f292c3dfa2649ef91f8925b623e79546fa992e:config/config_test.go:generic-api-key:144 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small-branch-foo.txt:aws-access-token:15 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/repos/nogit/main.go:aws-access-token:20 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small.txt:aws-access-token:15 +93f292c3dfa2649ef91f8925b623e79546fa992e:testdata/expected/git/small.txt:aws-access-token:44 +3a3e13c3b5f85b0116cf2a0cd92529baf22d0ac9:testdata/repos/with_square_and_google/env:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:scan/unstaged_test.go:aws-access-token:38 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_ae8db4a2_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_ae8db4a2_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_depth_1.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_depth_1.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_files_at_208ae46.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:5 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:26 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:31 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:40 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:46 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:aws-access-token:52 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:59 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:74 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:80 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:95 +93f292c3dfa2649ef91f8925b623e79546fa992e:detect/detect_test.go:discord-api-token:109 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_no_git.json:aws-access-token:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/basic/results_unstaged.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:generic-api-key:6 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:aws-access-token:9 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/basic/secrets.py:aws-access-token:13 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:54 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:aws-access-token:56 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results.json:generic-api-key:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:aws-access-token:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_e7c0aff3.json:aws-access-token:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:aws-access-token:37 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:aws-access-token:39 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:3 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:20 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/expect/with_config/results_ae8db4a_e7c0aff.json:generic-api-key:22 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:generic-api-key:5 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:generic-api-key:6 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:aws-access-token:9 +6adc045580c3911a7a936be7b977979a5519aa29:testdata/repos/with_config/secrets.py:aws-access-token:13 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_repos/test_dir_2/env:generic-api-key:1 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_repos/test_dir_2/env:generic-api-key:3 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_dir_one_google_leak_and_square_leak.json:generic-api-key:3 +45c898c5ea56ee503a048c1bac1404cf63855edc:test_data/test_dir_one_google_leak_and_square_leak.json:generic-api-key:20 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:35 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:37 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:259 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:261 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:339 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:51 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:83 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:85 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:131 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:133 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:147 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:149 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:179 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:227 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:229 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:323 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:355 +65f42020afcc65de3b7dfe5a797b9f6396345250:test_data/test_local_owner_aws_leak.json:aws-access-token:357 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_file1_aws_leak.json:aws-access-token:3 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_file1_aws_leak.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:3 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:17 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_dir1_aws_leak.json:aws-access-token:19 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_repos/test_dir_1/server.test.py:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_repos/test_dir_1/server.test2.py:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:99 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:101 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:115 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:117 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:131 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:133 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:147 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:149 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:163 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:165 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:179 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:181 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:195 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:197 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:213 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:83 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:85 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:99 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:101 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:115 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:117 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:131 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:133 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:147 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:149 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:163 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:165 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:179 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:259 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:261 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:181 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:195 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:197 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:339 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak.json:aws-access-token:341 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:3 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:5 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:18 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:20 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:33 +2acc34dfdfb0e7f1141eadd940ea933c645e0f86:test_data/test_local_repo_three_leaks_with_report_groups.json:aws-access-token:35 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:259 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:261 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_to_from.json:aws-access-token:3 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_to_from.json:aws-access-token:5 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:323 +c50906373cc38206f3d41c57e2c413ce400e61e7:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:325 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:18 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:20 +fae366a404357fa6c6611756a11e61546ebec4e0:examples/simple_regex_and_allowlist_config.toml:aws-access-token:12 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:3 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:5 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:18 +ad505754fc6283523ef8dfa88ecb6559e0268ec3:test_data/test_local_repo_two_leaks_file_commit_range.json:aws-access-token:20 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_configs/aws_key_aws_allowlisted.toml:aws-access-token:7 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:185 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_repo_nine_aws_leak.json:aws-access-token:3 +fae366a404357fa6c6611756a11e61546ebec4e0:test_data/test_local_repo_nine_aws_leak.json:aws-access-token:5 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:78 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:80 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:138 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:140 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:153 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:155 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:168 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak.json:aws-access-token:170 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:138 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:140 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:153 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:155 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:168 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_owner_aws_leak_allowlist_repo.json:aws-access-token:170 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:3 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:5 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:18 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:20 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:33 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_local_repo_eight.json:aws-access-token:35 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_repos/test_repo_8/dummy.txt:aws-access-token:2 +eabc7b5c12cb89b4a828b7aaef00fdfa694a7e0a:test_data/test_repos/test_repo_8/dummy.txt:aws-access-token:6 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:33 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak.json:aws-access-token:93 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:78 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:18 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_three_leaks.json:aws-access-token:48 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:78 +6ca7a11d8846af2a3d26f71c4a9083eb0b3deeee:test_data/test_local_repo_two_leaks.json:aws-access-token:33 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:3 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:4 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:16 +bdc688dd5351adf1cf5cbf734dfd104ea6bab92b:test_data/test_local_repo_two_whitelist_commits.json:aws-access-token:17 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_since_date.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_since_date.json:aws-access-token:4 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_until_date.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_six_leaks_until_date.json:aws-access-token:4 +0d7c18cb39c60efb62a6c7b351f95d46ebe1f63e:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:172 +0d7c18cb39c60efb62a6c7b351f95d46ebe1f63e:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:173 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:3 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:4 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:16 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:17 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:29 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:30 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:42 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:43 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:55 +e0f6399d5ccadd44544cdfe5f630de57fced1473:test_data/test_local_repo_four_leaks_commit_timerange.json:aws-access-token:56 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:3 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:4 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:16 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:17 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:29 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:30 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:42 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:43 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:55 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:56 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:68 +cfbb600fcb286e1323e2e4d24144eeca163ad396:test_data/test_local_repo_two_leaks_deletion.json:aws-access-token:69 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_local_repo_seven_aws_leak_uncommitted.json:aws-access-token:3 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_local_repo_seven_aws_leak_uncommitted.json:aws-access-token:4 +212232f80a22c4c698dd2864006f398ea1f15107:test_data/test_repos/test_repo_7/file:aws-access-token:5 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:134 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:160 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:133 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:134 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:172 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:173 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:3 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:4 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:16 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:17 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:29 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:30 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:42 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:43 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:55 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:56 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:68 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:69 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:81 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:82 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:94 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:95 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:107 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:108 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:120 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:121 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:133 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:134 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:146 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:147 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:159 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:160 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:172 +473d0d55a71097894c5c6b9a2968ad478d2e6edf:test_data/test_local_owner_aws_leak_whitelist_repo.json:aws-access-token:173 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:186 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:29 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:30 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:42 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:224 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:225 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:212 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:263 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:264 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:237 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:238 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:276 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:277 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:316 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:342 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:95 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:121 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:3 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:4 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:29 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:30 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:42 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_five_files_at_latest_commit.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:43 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:146 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:147 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:380 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:381 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:406 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:407 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:445 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_owner_aws_leak.json:aws-access-token:446 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:16 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:17 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:68 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:69 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:55 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:56 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:172 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks.json:aws-access-token:173 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:68 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:69 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:95 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_owner_aws_leak.json:aws-access-token:120 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_owner_aws_leak.json:aws-access-token:121 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks.json:aws-access-token:107 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks.json:aws-access-token:108 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:94 +c6f15b768e19613228b232a712f53a39cc5120a3:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:95 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_three_leaks.json:aws-access-token:81 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_three_leaks.json:aws-access-token:82 +c4b07f5113bf39019374579a64d83959236295e4:audit/util.go:aws-access-token:66 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:55 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:56 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:55 +94cae90d1eb208410073669de54a21fb65f23742:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:56 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak.json:aws-access-token:276 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak.json:aws-access-token:277 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:16 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:17 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:146 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:147 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six.json:aws-access-token:31 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six.json:aws-access-token:33 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_filepath.json:aws-access-token:3 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_filepath.json:aws-access-token:4 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_path_globally_whitelisted.json:aws-access-token:3 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_local_repo_six_path_globally_whitelisted.json:aws-access-token:4 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_repos/test_repo_6/server.test.py:aws-access-token:5 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:55 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:56 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:68 +10745be661121f2e6577170419cf8ce3308ae311:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:69 +c4b07f5113bf39019374579a64d83959236295e4:test_data/test_repos/test_repo_6/config/application.properties:aws-access-token:3 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:133 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:134 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:250 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:251 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:263 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_owner_aws_leak.json:aws-access-token:264 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:3 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:4 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:16 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_local_repo_five_files_at_commit.json:aws-access-token:17 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:3 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:4 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:16 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:17 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:42 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:43 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:68 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:69 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:94 +2474c39311296b4d48c284b1ce82e0c270854bde:test_data/test_local_owner_aws_leak_depth_2.json:aws-access-token:95 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_repos/test_repo_5/secrets.py:aws-access-token:1 +d13e0fdfde8f5c6261c9e893461f32861e21e8f5:test_data/test_repos/test_repo_5/secrets.py:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:16 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:17 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:42 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_range.json:aws-access-token:43 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_to.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:3 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:4 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:16 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:17 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:29 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:30 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:42 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:43 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:55 +a0f72a4e3595ddb382a77804d2674d54b2b0e880:test_data/test_local_repo_two_leaks_commit_from.json:aws-access-token:56 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:68 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:69 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:81 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:82 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:107 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:108 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:94 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_repo_two_leaks.json:aws-access-token:95 +6e1c41b536a514e1d17768eb42ebf5d87e61247d:examples/simple_regex_and_whitelist_config.toml:aws-access-token:4 +6e1c41b536a514e1d17768eb42ebf5d87e61247d:examples/simple_regex_and_whitelist_config.toml:aws-access-token:12 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:211 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:212 +275232f8c8f3ae4936667602a06a46caa156580b:audit/util.go:aws-access-token:90 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:237 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:238 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_configs/aws_key_aws_whitelisted.toml:aws-access-token:6 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_regex_whitelist.json.got:aws-access-token:3 +275232f8c8f3ae4936667602a06a46caa156580b:test_data/test_regex_whitelist.json.got:aws-access-token:4 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:315 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:316 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:341 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:342 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:445 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:446 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:471 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:472 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:549 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:550 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:575 +4d04ea079fc4e7f46c9f751fccde8f18c33b9e13:test_data/test_local_owner_aws_leak.json:aws-access-token:576 +e446ba073804cf714316c5dc00d0ac41917b31f7:test_data/test_regex_entropy.json:aws-access-token:3 +e446ba073804cf714316c5dc00d0ac41917b31f7:test_data/test_regex_entropy.json:aws-access-token:4 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:241 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:242 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:255 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:256 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:269 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:270 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:283 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:284 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:297 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:298 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:311 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:312 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:325 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:326 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:339 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:340 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:353 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:354 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:367 +2ccd40677db07877be4a5919a16f6a180fc2a7e4:test_data/test_local_owner_aws_leak.json:aws-access-token:368 +b55d88dc151f7022901cda41a03d43e0e508f2b7:audit/audit_test.go:aws-access-token:207 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_entropy.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_and_file_leak.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_commit.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_one_aws_leak_uncommitted.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:87 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:88 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:101 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_three_leaks.json:aws-access-token:102 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_repos/test_repo_1/server.test.py:aws-access-token:5 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_repo_two_leaks.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:3 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:4 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:17 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:18 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:31 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:32 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:45 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:46 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:59 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:60 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:73 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:74 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:87 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:88 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:101 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:102 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:115 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:116 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:129 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:130 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:143 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:144 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:157 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:158 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:171 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:172 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:185 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:186 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:199 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:200 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:213 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:214 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:227 +b55d88dc151f7022901cda41a03d43e0e508f2b7:test_data/test_local_owner_aws_leak.json:aws-access-token:228 +7bd55e33b504f76fc2aec27f4f479a5fb2606480:src/constants.go:private-key:32 +e79ffc6ae8f66931d687407e07bc0632fb262091:src/constants.go:private-key:23 +2b995fda446e03b7660c327fec41265f03199c71:config.go:private-key:28 +1f80d14f3f069118a2e578d83bbc8440495fc906:main.go:private-key:118 +fe977ea8577b739c34a0071ba34e98cf6b6fad38:checks_test.go:aws-access-token:52 +4b4fa00b69a9a2e5f7619b1ff1dd6d160f588aec:README.md:aws-access-token:25 +4b4fa00b69a9a2e5f7619b1ff1dd6d160f588aec:README.md:aws-access-token:27 +2186f2299990290e4e19cf3b28906e2ec369d01e:main.go:private-key:44 +9f694531b203663588c68c82dbbfb34d4f71863f:main.go:private-key:44 +1e250f1a14eab6f457d61f5d7650b47c6ff43334:checks_test.go:aws-access-token:19 +1e250f1a14eab6f457d61f5d7650b47c6ff43334:config.yml:private-key:2 +bc26e979c5911cf647c1bede0b3700ebaaa454c8:checks_test.go:aws-access-token:36 +8f352bd840f028b481dc725b77d2f4904b77913b:checks_test.go:aws-access-token:34 +ec2fc9d6cb0954fb3b57201cf6133c48d8ca0d29:checks_test.go:aws-access-token:37 +06c9e824d5985c8e8789321ae70de7ace3b093dc:main.go:aws-access-token:15 + +README.md:aws-access-token:204 +README.md:aws-access-token:205 +README.md:aws-access-token:244 +cmd/generate/config/rules/privatekey.go:private-key:19 +cmd/generate/config/rules/generic.go:clojars-api-token:43 +cmd/generate/config/rules/generic.go:generic-api-key:45 +cmd/generate/config/rules/generic.go:generic-api-key:46 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:22 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:24 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:28 +cmd/generate/config/rules/sidekiq.go:sidekiq-secret:29 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:46 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:48 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:50 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:52 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:54 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:55 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:56 +cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:57 +config/config_test.go:aws-access-token:31 +detect/detect_test.go:sidekiq-secret:120 +detect/detect_test.go:sidekiq-secret:126 +detect/detect_test.go:sidekiq-secret:142 +detect/detect_test.go:aws-access-token:50 +detect/detect_test.go:aws-access-token:60 +detect/detect_test.go:aws-access-token:61 +detect/detect_test.go:aws-access-token:98 +detect/detect_test.go:aws-access-token:104 +detect/detect_test.go:aws-access-token:105 +detect/detect_test.go:aws-access-token:186 +detect/detect_test.go:aws-access-token:194 +detect/detect_test.go:aws-access-token:202 +detect/detect_test.go:aws-access-token:288 +detect/detect_test.go:aws-access-token:296 +detect/detect_test.go:aws-access-token:359 +detect/detect_test.go:aws-access-token:360 +detect/detect_test.go:aws-access-token:378 +detect/detect_test.go:aws-access-token:379 +detect/detect_test.go:aws-access-token:404 +detect/detect_test.go:aws-access-token:405 +detect/detect_test.go:aws-access-token:480 +detect/detect_test.go:aws-access-token:481 +detect/detect_test.go:aws-access-token:499 +detect/detect_test.go:aws-access-token:500 +detect/detect_test.go:sidekiq-sensitive-url:164 +detect/detect_test.go:sidekiq-sensitive-url:170 +detect/detect_test.go:pypi-upload-token:76 +detect/detect_test.go:pypi-upload-token:82 +detect/detect_test.go:pypi-upload-token:83 +detect/detect_test.go:discord-api-token:211 +detect/detect_test.go:discord-api-token:233 +detect/detect_test.go:discord-api-token:241 +detect/detect_test.go:discord-api-token:263 +detect/detect_test.go:discord-api-token:279 +testdata/config/allow_aws_re.toml:aws-access-token:9 +testdata/config/allow_global_aws_re.toml:aws-access-token:8 +testdata/expected/git/small-branch-foo.txt:aws-access-token:15 +testdata/expected/git/small.txt:aws-access-token:15 +testdata/expected/git/small.txt:aws-access-token:44 +testdata/repos/nogit/main.go:aws-access-token:20 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:513 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:492 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:414 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:388 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:366 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:discord-api-token:255 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:discord-api-token:224 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-sensitive-url:177 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-secret:154 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:sidekiq-secret:130 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:107 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:pypi-upload-token:84 +3df8c3deb7bc1e34210bdbce114f1c6165bc6ac8:detect/detect_test.go:aws-access-token:62 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:62 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:pypi-upload-token:84 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:107 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-secret:130 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-secret:154 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:sidekiq-sensitive-url:177 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:discord-api-token:224 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:discord-api-token:255 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:366 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:388 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:414 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:492 +96eed6aa0f507fe0c21bb46bec32637dc4cb1a9f:detect/detect_test.go:aws-access-token:513 +bfbc39eb185a217ead81a7174026f1c55f963660:cmd/generate/config/rules/jwt.go:jwt:17 +bfbc39eb185a217ead81a7174026f1c55f963660:cmd/generate/config/rules/jwt.go:jwt:19 diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..94ad5762c --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,29 @@ +project_name: gitleaks + +builds: + - main: main.go + binary: gitleaks + goos: + - darwin + - linux + - windows + goarch: + - amd64 + - "386" + - arm + - arm64 + goarm: + - "6" + - "7" + ldflags: + - -s -w -X=github.com/zricethezav/gitleaks/v8/cmd.Version={{.Version}} +archives: + - builds: [gitleaks] + format_overrides: + - goos: windows + format: zip + replacements: + amd64: x64 + 386: x32 +release: + prerelease: true diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 000000000..c8aba5b73 --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,11 @@ +- id: gitleaks + name: Detect hardcoded secrets + description: Detect hardcoded secrets using Gitleaks + entry: gitleaks protect --verbose --redact --staged + language: golang + pass_filenames: false +- id: gitleaks-docker + name: Detect hardcoded secrets + description: Detect hardcoded secrets using Gitleaks + entry: zricethezav/gitleaks protect --verbose --redact --staged + language: docker_image diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 97a1b6f42..000000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: -- 1.14.x -services: -- docker -script: -- make test -- make security-scan diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..6d2ce277b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,103 @@ +# Contribution guidelines + +## General + +### Issues + +If you have a feature or bug fix you would like to contribute please check if +there are any open issues describing your proposed addition. If there are open +issues, make a comment stating you are working on fixing or implementing said +issue. If not, then please open an issue describing your addition. Make sure to +link your PR to an issue. + +### Pull Requests + +Fill out the template as best you can. Make sure your tests pass. If you see a +PR that isn't one you opened and want it introduced in the next release, +give it a :thumbsup: on the PR description. + +## Adding new Gitleaks rules + +If you want to add a new rule to the [default Gitleaks configuration](https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml) then follow these steps. + +1. Create a `cmd/generate/config/rules/{provider}.go` file. + This file is used to generate a new Gitleaks rule. + Let's look at `beamer.go` for example. Comments have been added for context. + + ```golang + func Beamer() *config.Rule { + // Define Rule + r := config.Rule{ + // Human redable description of the rule + Description: "Beamer API token", + + // Unique ID for the rule + RuleID: "beamer-api-token", + + // Regex capture group for the actual secret + SecretGroup: 1, + + + // Regex used for detecting secrets. See regex section below for more details + Regex: generateSemiGenericRegex([]string{"beamer"}, `b_[a-z0-9=_\-]{44}`), + + // Keywords used for string matching on fragments (think of this as a prefilter) + Keywords: []string{"beamer"}, + } + + // validate + tps := []string{ + generateSampleSecret("beamer", "b_"+secrets.NewSecret(alphaNumericExtended("44"))), + } + return validate(r, tps, nil) + } + ``` + + Feel free to use this example as a template when writing new rules. + This file should be fairly self-explanatory except for a few items; + regex and secret generation. To help with maintence, _most_ rules should + be uniform. The functions, + [`generateSemiGenericRegex`](https://github.com/zricethezav/gitleaks/blob/master/cmd/generate/config/rules/rule.go#L31) and [`generateUniqueTokenRegex`](https://github.com/zricethezav/gitleaks/blob/master/cmd/generate/config/rules/rule.go#L44) will generate rules + that follow defined patterns. + + The function signatures look like this: + + ```golang + func generateSemiGenericRegex(identifiers []string, secretRegex string) *regexp.Regexp + + func generateUniqueTokenRegex(secretRegex string) *regexp.Regexp + ``` + + `generateSemiGenericRegex` accepts a list of identifiers and a regex. + The list of identifiers _should_ match the list of `Keywords` in the rule + definition above. Both `identifiers` in the `generateSemiGenericRegex` + function _and_ `Keywords` act as filters for Gitleaks telling the program + "_at least one of these strings must be present to be considered a leak_" + + `generateUniqueToken` just accepts a regex. If you are writing a rule for a + token that is unique enough not to require an identifier then you can use + this function. For example, Pulumi's API Token has the prefix `pul-` which is + unique enough to use `generateUniqueToken`. But something like Beamer's API + token that has a `b_` prefix is not unqiue enough to use `generateUniqueToken`, + so instead we use `generateSemiGenericRegex` and require a `beamer` + identifier is part of the rule. + If a token's prefix has more than `3` characters then you could + probably get away with using `generateUniqueToken`. + + Last thing you'll want to hit before we move on from this file is the + validation part. You can use `generateSampleSecret` to create a secret for the + true positives (`tps` in the example above) used in `validate`. + +1. Update `cmd/generate/config/main.go`. Add a line like + `configRules = append(configRules, rules.Beamer())` in `main()`. Try and keep + this alphabetically pretty please. + +1. Change directories into `cmd/generate/config` and run `go run main.go` + + ``` + cd cmd/generate/config && go run main.go + ``` + +1. Check out your new rules in `config/gitleaks.toml` and see if everything looks good. + +1. Open a PR diff --git a/Dockerfile b/Dockerfile index 3227f579b..cbee1ad32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,15 @@ -FROM golang:1.14.1 AS build +FROM golang:1.19 AS build WORKDIR /go/src/github.com/zricethezav/gitleaks -ARG ldflags COPY . . -RUN GO111MODULE=on CGO_ENABLED=0 go build -o bin/gitleaks -ldflags "-X="${ldflags} *.go +RUN VERSION=$(git describe --tags --abbrev=0) && \ +CGO_ENABLED=0 go build -o bin/gitleaks -ldflags "-X="github.com/zricethezav/gitleaks/v8/cmd.Version=${VERSION} -FROM alpine:3.11 -RUN apk add --no-cache bash git openssh +FROM alpine:3.16 +RUN adduser -D gitleaks && \ + apk add --no-cache bash git openssh-client COPY --from=build /go/src/github.com/zricethezav/gitleaks/bin/* /usr/bin/ -ENTRYPOINT ["gitleaks"] - -# How to use me : +USER gitleaks -# docker build -t gitleaks . -# docker run --rm --name=gitleaks gitleaks --repo=https://github.com/zricethezav/gitleaks +RUN git config --global --add safe.directory '*' -# This will check for secrets in https://github.com/zricethezav/gitleaks +ENTRYPOINT ["gitleaks"] diff --git a/Makefile b/Makefile index a6f6ec81a..f53e37964 100644 --- a/Makefile +++ b/Makefile @@ -1,52 +1,26 @@ -.PHONY: test test-cover build release-builds +.PHONY: test test-cover -VERSION := `git fetch --tags && git tag | sort -V | tail -1` PKG=github.com/zricethezav/gitleaks -LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks/v6/version.Version=$(VERSION)" -_LDFLAGS="github.com/zricethezav/gitleaks/v6/version.Version=$(VERSION)" +VERSION := `git fetch --tags && git tag | sort -V | tail -1` +LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks/v8/cmd.Version=$(VERSION)" COVER=--cover --coverprofile=cover.out test-cover: - go test ./... --race $(COVER) $(PKG) -v + go test -v ./... --race $(COVER) $(PKG) go tool cover -html=cover.out -test: - go get golang.org/x/lint/golint +format: go fmt ./... - go vet ./... - golint ./... - go test ./... --race $(PKG) -v -test-integration: - go test github.com/zricethezav/gitleaks/hosts -v -integration +test: format + go vet ./... + go test -v ./... --race $(PKG) -build: - go fmt ./... - golint ./... +build: format go vet ./... go mod tidy go build $(LDFLAGS) -security-scan: - go get github.com/securego/gosec/cmd/gosec - gosec -no-fail ./... - -release-builds: - rm -rf build - mkdir build - env GOOS="windows" GOARCH="amd64" go build -o "build/gitleaks-windows-amd64.exe" $(LDFLAGS) - env GOOS="windows" GOARCH="386" go build -o "build/gitleaks-windows-386.exe" $(LDFLAGS) - env GOOS="linux" GOARCH="amd64" go build -o "build/gitleaks-linux-amd64" $(LDFLAGS) - env GOOS="linux" GOARCH="arm" go build -o "build/gitleaks-linux-arm" $(LDFLAGS) - env GOOS="linux" GOARCH="mips" go build -o "build/gitleaks-linux-mips" $(LDFLAGS) - env GOOS="linux" GOARCH="mips" go build -o "build/gitleaks-linux-mips" $(LDFLAGS) - env GOOS="darwin" GOARCH="amd64" go build -o "build/gitleaks-darwin-amd64" $(LDFLAGS) - -deploy: - @echo "$(DOCKER_PASSWORD)" | docker login -u "$(DOCKER_USERNAME)" --password-stdin - docker build --build-arg ldflags=$(_LDFLAGS) -f Dockerfile -t zricethezav/gitleaks:latest -t zricethezav/gitleaks:$(VERSION) . - echo "Pushing zricethezav/gitleaks:$(VERSION) and zricethezav/gitleaks:latest" - docker push zricethezav/gitleaks - -dockerbuild: - docker build --build-arg ldflags=$(_LDFLAGS) -f Dockerfile -t zricethezav/gitleaks:latest -t zricethezav/gitleaks:$(VERSION) . +clean: + find . -type f -name '*.got.*' -delete + find . -type f -name '*.out' -delete diff --git a/README.md b/README.md index 672036af0..ad6ad1d52 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,415 @@ -

- gitleaks -

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

+

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

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

+ + Tines Sponsorship + +

-#### Individual Sponsors -These users are [sponsors](https://github.com/sponsors/zricethezav) of gitleaks: +## Exit Codes -[![Adam Shannon](https://github.com/adamdecaf.png?size=50)](https://github.com/adamdecaf) | ----| ----- -#### Logo Attribution -The Gitleaks logo uses the Git Logo created Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License. +You can always set the exit code when leaks are encountered with the --exit-code flag. Default exit codes below: +``` +0 - no leaks present +1 - leaks or error encountered +126 - unknown flag +``` diff --git a/USERS.md b/USERS.md new file mode 100644 index 000000000..2235c163b --- /dev/null +++ b/USERS.md @@ -0,0 +1,25 @@ +## Who uses Gitleaks? + +As the Gitleaks Community grows, we'd like to keep a list of our users. + +Here's a running list of some organizations using Gitleaks[^1]: + +1. [Gitleaks](https://gitleaks.io) +1. [GoReleaser](https://goreleaser.com) +2. [Trendyol](https://trendyol.com) + +Feel free to [add yours](https://github.com/zricethezav/gitleaks/edit/master/USERS.md)! + + + +[^1]: Entries were either added by the companies themselves or by the maintainers after seeing it in the wild. + You can see all public repositories using Gitleaks or Gitleaks-Action by [searching on GitHub](https://github.com/search?q=gitleaks). + + diff --git a/cmd/detect.go b/cmd/detect.go new file mode 100644 index 000000000..40124bdfc --- /dev/null +++ b/cmd/detect.go @@ -0,0 +1,181 @@ +package cmd + +import ( + "os" + "path/filepath" + "time" + + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" + "github.com/zricethezav/gitleaks/v8/report" +) + +func init() { + rootCmd.AddCommand(detectCmd) + detectCmd.Flags().String("log-opts", "", "git log options") + detectCmd.Flags().Bool("no-git", false, "treat git repo as a regular directory and scan those files, --log-opts has no effect on the scan when --no-git is set") +} + +var detectCmd = &cobra.Command{ + Use: "detect", + Short: "detect secrets in code", + Run: runDetect, +} + +func runDetect(cmd *cobra.Command, args []string) { + initConfig() + var ( + vc config.ViperConfig + findings []report.Finding + err error + ) + + // Load config + if err = viper.Unmarshal(&vc); err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg, err := vc.Translate() + if err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg.Path, _ = cmd.Flags().GetString("config") + + // start timer + start := time.Now() + + // Setup detector + detector := detect.NewDetector(cfg) + detector.Config.Path, err = cmd.Flags().GetString("config") + if err != nil { + log.Fatal().Err(err).Msg("") + } + source, err := cmd.Flags().GetString("source") + if err != nil { + log.Fatal().Err(err).Msg("") + } + // if config path is not set, then use the {source}/.gitleaks.toml path. + // note that there may not be a `{source}/.gitleaks.toml` file, this is ok. + if detector.Config.Path == "" { + detector.Config.Path = filepath.Join(source, ".gitleaks.toml") + } + // set verbose flag + if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil { + log.Fatal().Err(err).Msg("") + } + // set redact flag + if detector.Redact, err = cmd.Flags().GetBool("redact"); err != nil { + log.Fatal().Err(err).Msg("") + } + + if fileExists(filepath.Join(source, ".gitleaksignore")) { + if err = detector.AddGitleaksIgnore(filepath.Join(source, ".gitleaksignore")); err != nil { + log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore") + } + } + + // ignore findings from the baseline (an existing report in json format generated earlier) + baselinePath, _ := cmd.Flags().GetString("baseline-path") + if baselinePath != "" { + err = detector.AddBaseline(baselinePath) + if err != nil { + log.Error().Msgf("Could not load baseline. The path must point of a gitleaks report generated using the default format: %s", err) + } + } + + // set exit code + exitCode, err := cmd.Flags().GetInt("exit-code") + if err != nil { + log.Fatal().Err(err).Msg("could not get exit code") + } + + // determine what type of scan: + // - git: scan the history of the repo + // - no-git: scan files by treating the repo as a plain directory + noGit, err := cmd.Flags().GetBool("no-git") + if err != nil { + log.Fatal().Err(err).Msg("could not call GetBool() for no-git") + } + + // start the detector scan + if noGit { + findings, err = detector.DetectFiles(source) + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + + } else { + var logOpts string + logOpts, err = cmd.Flags().GetString("log-opts") + if err != nil { + log.Fatal().Err(err).Msg("") + } + findings, err = detector.DetectGit(source, logOpts, detect.DetectType) + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + } + + // log info about the scan + if err == nil { + log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("leaks found: %d", len(findings)) + } else { + log.Info().Msg("no leaks found") + } + } else { + log.Warn().Msgf("partial scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("%d leaks found in partial scan", len(findings)) + } else { + log.Warn().Msg("no leaks found in partial scan") + } + } + + // write report if desired + reportPath, _ := cmd.Flags().GetString("report-path") + ext, _ := cmd.Flags().GetString("report-format") + if reportPath != "" { + if err := report.Write(findings, cfg, ext, reportPath); err != nil { + log.Fatal().Err(err).Msg("could not write") + } + } + + if err != nil { + os.Exit(1) + } + + if len(findings) != 0 { + os.Exit(exitCode) + } +} + +func fileExists(fileName string) bool { + // check for a .gitleaksignore file + info, err := os.Stat(fileName) + if err != nil && !os.IsNotExist(err) { + return false + } + + if info != nil && err == nil { + if !info.IsDir() { + return true + } + } + return false +} + +func FormatDuration(d time.Duration) string { + scale := 100 * time.Second + // look for the max scale that is smaller than d + for scale > d { + scale = scale / 10 + } + return d.Round(scale / 100).String() +} diff --git a/cmd/generate/config/main.go b/cmd/generate/config/main.go new file mode 100644 index 000000000..7ad7755cd --- /dev/null +++ b/cmd/generate/config/main.go @@ -0,0 +1,192 @@ +package main + +import ( + "os" + "text/template" + + "github.com/rs/zerolog/log" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/config/rules" + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + templatePath = "rules/config.tmpl" +) + +func main() { + var configRules []*config.Rule + configRules = append(configRules, rules.AdafruitAPIKey()) + configRules = append(configRules, rules.AdobeClientID()) + configRules = append(configRules, rules.AdobeClientSecret()) + configRules = append(configRules, rules.AgeSecretKey()) + configRules = append(configRules, rules.Airtable()) + configRules = append(configRules, rules.AlgoliaApiKey()) + configRules = append(configRules, rules.AlibabaAccessKey()) + configRules = append(configRules, rules.AlibabaSecretKey()) + configRules = append(configRules, rules.AsanaClientID()) + configRules = append(configRules, rules.AsanaClientSecret()) + configRules = append(configRules, rules.Atlassian()) + configRules = append(configRules, rules.AWS()) + configRules = append(configRules, rules.BitBucketClientID()) + configRules = append(configRules, rules.BitBucketClientSecret()) + configRules = append(configRules, rules.BittrexAccessKey()) + configRules = append(configRules, rules.BittrexSecretKey()) + configRules = append(configRules, rules.Beamer()) + configRules = append(configRules, rules.CodecovAccessToken()) + configRules = append(configRules, rules.CoinbaseAccessToken()) + configRules = append(configRules, rules.Clojars()) + configRules = append(configRules, rules.ConfluentAccessToken()) + configRules = append(configRules, rules.ConfluentSecretKey()) + configRules = append(configRules, rules.Contentful()) + configRules = append(configRules, rules.Databricks()) + configRules = append(configRules, rules.DatadogtokenAccessToken()) + configRules = append(configRules, rules.DigitalOceanPAT()) + configRules = append(configRules, rules.DigitalOceanOAuthToken()) + configRules = append(configRules, rules.DigitalOceanRefreshToken()) + configRules = append(configRules, rules.DiscordAPIToken()) + configRules = append(configRules, rules.DiscordClientID()) + configRules = append(configRules, rules.DiscordClientSecret()) + configRules = append(configRules, rules.Doppler()) + configRules = append(configRules, rules.DropBoxAPISecret()) + configRules = append(configRules, rules.DropBoxLongLivedAPIToken()) + configRules = append(configRules, rules.DropBoxShortLivedAPIToken()) + configRules = append(configRules, rules.DroneciAccessToken()) + configRules = append(configRules, rules.Duffel()) + configRules = append(configRules, rules.Dynatrace()) + configRules = append(configRules, rules.EasyPost()) + configRules = append(configRules, rules.EasyPostTestAPI()) + configRules = append(configRules, rules.EtsyAccessToken()) + configRules = append(configRules, rules.Facebook()) + configRules = append(configRules, rules.FastlyAPIToken()) + configRules = append(configRules, rules.FinicityClientSecret()) + configRules = append(configRules, rules.FinicityAPIToken()) + configRules = append(configRules, rules.FlickrAccessToken()) + configRules = append(configRules, rules.FinnhubAccessToken()) + configRules = append(configRules, rules.FlutterwavePublicKey()) + configRules = append(configRules, rules.FlutterwaveSecretKey()) + configRules = append(configRules, rules.FlutterwaveEncKey()) + configRules = append(configRules, rules.FrameIO()) + configRules = append(configRules, rules.FreshbooksAccessToken()) + configRules = append(configRules, rules.GoCardless()) + // TODO figure out what makes sense for GCP + // configRules = append(configRules, rules.GCPServiceAccount()) + configRules = append(configRules, rules.GCPAPIKey()) + configRules = append(configRules, rules.GitHubPat()) + configRules = append(configRules, rules.GitHubOauth()) + configRules = append(configRules, rules.GitHubApp()) + configRules = append(configRules, rules.GitHubRefresh()) + configRules = append(configRules, rules.Gitlab()) + configRules = append(configRules, rules.GitterAccessToken()) + configRules = append(configRules, rules.GrafanaApiKey()) + configRules = append(configRules, rules.GrafanaCloudApiToken()) + configRules = append(configRules, rules.GrafanaServiceAccountToken()) + configRules = append(configRules, rules.Hashicorp()) + configRules = append(configRules, rules.Heroku()) + configRules = append(configRules, rules.HubSpot()) + configRules = append(configRules, rules.Intercom()) + configRules = append(configRules, rules.JWT()) + configRules = append(configRules, rules.KrakenAccessToken()) + configRules = append(configRules, rules.KucoinAccessToken()) + configRules = append(configRules, rules.KucoinSecretKey()) + configRules = append(configRules, rules.LaunchDarklyAccessToken()) + configRules = append(configRules, rules.LinearAPIToken()) + configRules = append(configRules, rules.LinearClientSecret()) + configRules = append(configRules, rules.LinkedinClientID()) + configRules = append(configRules, rules.LinkedinClientSecret()) + configRules = append(configRules, rules.LobAPIToken()) + configRules = append(configRules, rules.LobPubAPIToken()) + configRules = append(configRules, rules.MailChimp()) + configRules = append(configRules, rules.MailGunPubAPIToken()) + configRules = append(configRules, rules.MailGunPrivateAPIToken()) + configRules = append(configRules, rules.MailGunSigningKey()) + configRules = append(configRules, rules.MapBox()) + configRules = append(configRules, rules.MattermostAccessToken()) + configRules = append(configRules, rules.MessageBirdAPIToken()) + configRules = append(configRules, rules.MessageBirdClientID()) + configRules = append(configRules, rules.NetlifyAccessToken()) + configRules = append(configRules, rules.NewRelicUserID()) + configRules = append(configRules, rules.NewRelicUserKey()) + configRules = append(configRules, rules.NewRelicBrowserAPIKey()) + configRules = append(configRules, rules.NPM()) + configRules = append(configRules, rules.NytimesAccessToken()) + configRules = append(configRules, rules.OktaAccessToken()) + configRules = append(configRules, rules.PlaidAccessID()) + configRules = append(configRules, rules.PlaidSecretKey()) + configRules = append(configRules, rules.PlaidAccessToken()) + configRules = append(configRules, rules.PlanetScalePassword()) + configRules = append(configRules, rules.PlanetScaleAPIToken()) + configRules = append(configRules, rules.PlanetScaleOAuthToken()) + configRules = append(configRules, rules.PostManAPI()) + configRules = append(configRules, rules.Prefect()) + configRules = append(configRules, rules.PrivateKey()) + configRules = append(configRules, rules.PulumiAPIToken()) + configRules = append(configRules, rules.PyPiUploadToken()) + configRules = append(configRules, rules.RapidAPIAccessToken()) + configRules = append(configRules, rules.ReadMe()) + configRules = append(configRules, rules.RubyGemsAPIToken()) + configRules = append(configRules, rules.SendbirdAccessID()) + configRules = append(configRules, rules.SendbirdAccessToken()) + configRules = append(configRules, rules.SendGridAPIToken()) + configRules = append(configRules, rules.SendInBlueAPIToken()) + configRules = append(configRules, rules.SentryAccessToken()) + configRules = append(configRules, rules.ShippoAPIToken()) + configRules = append(configRules, rules.ShopifyAccessToken()) + configRules = append(configRules, rules.ShopifyCustomAccessToken()) + configRules = append(configRules, rules.ShopifyPrivateAppAccessToken()) + configRules = append(configRules, rules.ShopifySharedSecret()) + configRules = append(configRules, rules.SidekiqSecret()) + configRules = append(configRules, rules.SidekiqSensitiveUrl()) + configRules = append(configRules, rules.SlackAccessToken()) + configRules = append(configRules, rules.SlackWebHook()) + configRules = append(configRules, rules.StripeAccessToken()) + configRules = append(configRules, rules.SquareAccessToken()) + configRules = append(configRules, rules.SquareSpaceAccessToken()) + configRules = append(configRules, rules.SumoLogicAccessID()) + configRules = append(configRules, rules.SumoLogicAccessToken()) + configRules = append(configRules, rules.TeamsWebhook()) + configRules = append(configRules, rules.TelegramBotToken()) + configRules = append(configRules, rules.TravisCIAccessToken()) + configRules = append(configRules, rules.Twilio()) + configRules = append(configRules, rules.TwitchAPIToken()) + configRules = append(configRules, rules.TwitterAPIKey()) + configRules = append(configRules, rules.TwitterAPISecret()) + configRules = append(configRules, rules.TwitterAccessToken()) + configRules = append(configRules, rules.TwitterAccessSecret()) + configRules = append(configRules, rules.TwitterBearerToken()) + configRules = append(configRules, rules.Typeform()) + configRules = append(configRules, rules.VaultBatchToken()) + configRules = append(configRules, rules.VaultServiceToken()) + configRules = append(configRules, rules.YandexAPIKey()) + configRules = append(configRules, rules.YandexAWSAccessToken()) + configRules = append(configRules, rules.YandexAccessToken()) + configRules = append(configRules, rules.ZendeskSecretKey()) + configRules = append(configRules, rules.GenericCredential()) + + // ensure rules have unique ids + ruleLookUp := make(map[string]config.Rule) + for _, rule := range configRules { + // check if rule is in ruleLookUp + if _, ok := ruleLookUp[rule.RuleID]; ok { + log.Fatal().Msgf("rule id %s is not unique", rule.RuleID) + } + // TODO: eventually change all the signatures to get ride of this + // nasty dereferencing. + ruleLookUp[rule.RuleID] = *rule + } + + tmpl, err := template.ParseFiles(templatePath) + if err != nil { + log.Fatal().Err(err).Msg("Failed to parse template") + } + + f, err := os.Create("../../../config/gitleaks.toml") + if err != nil { + log.Fatal().Err(err).Msg("Failed to create rules.toml") + } + + if err = tmpl.Execute(f, config.Config{Rules: ruleLookUp}); err != nil { + log.Fatal().Err(err).Msg("could not execute template") + } + +} diff --git a/cmd/generate/config/rules/adafruit.go b/cmd/generate/config/rules/adafruit.go new file mode 100644 index 000000000..3889e6c62 --- /dev/null +++ b/cmd/generate/config/rules/adafruit.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AdafruitAPIKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adafruit API Key", + RuleID: "adafruit-api-key", + Regex: generateSemiGenericRegex([]string{"adafruit"}, alphaNumericExtendedShort("32")), + SecretGroup: 1, + Keywords: []string{"adafruit"}, + } + + // validate + tps := []string{ + generateSampleSecret("adafruit", secrets.NewSecret(alphaNumericExtendedShort("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/adobe.go b/cmd/generate/config/rules/adobe.go new file mode 100644 index 000000000..c0e9999f1 --- /dev/null +++ b/cmd/generate/config/rules/adobe.go @@ -0,0 +1,39 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AdobeClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adobe Client ID (OAuth Web)", + RuleID: "adobe-client-id", + Regex: generateSemiGenericRegex([]string{"adobe"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"adobe"}, + } + + // validate + tps := []string{ + generateSampleSecret("adobe", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func AdobeClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Adobe Client Secret", + RuleID: "adobe-client-secret", + Regex: generateUniqueTokenRegex(`(p8e-)(?i)[a-z0-9]{32}`), + Keywords: []string{"p8e-"}, + } + + // validate + tps := []string{ + "adobeClient := \"p8e-" + secrets.NewSecret(hex("32")) + "\"", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/age.go b/cmd/generate/config/rules/age.go new file mode 100644 index 000000000..ccc0ca2e8 --- /dev/null +++ b/cmd/generate/config/rules/age.go @@ -0,0 +1,23 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func AgeSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Age secret key", + RuleID: "age secret key", + Regex: regexp.MustCompile(`AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}`), + Keywords: []string{"AGE-SECRET-KEY-1"}, + } + + // validate + tps := []string{ + `apiKey := "AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/airtable.go b/cmd/generate/config/rules/airtable.go new file mode 100644 index 000000000..ab31f88d7 --- /dev/null +++ b/cmd/generate/config/rules/airtable.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Airtable() *config.Rule { + // define rule + r := config.Rule{ + Description: "Airtable API Key", + RuleID: "airtable-api-key", + Regex: generateSemiGenericRegex([]string{"airtable"}, alphaNumeric("17")), + SecretGroup: 1, + Keywords: []string{"airtable"}, + } + + // validate + tps := []string{ + generateSampleSecret("airtable", secrets.NewSecret(alphaNumeric("17"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/algolia.go b/cmd/generate/config/rules/algolia.go new file mode 100644 index 000000000..4e3e30aff --- /dev/null +++ b/cmd/generate/config/rules/algolia.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AlgoliaApiKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Algolia API Key", + RuleID: "algolia-api-key", + Regex: generateSemiGenericRegex([]string{"algolia"}, `[a-z0-9]{32}`), + Keywords: []string{"algolia"}, + } + + // validate + tps := []string{ + "algolia_key := " + secrets.NewSecret(hex("32")), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/alibaba.go b/cmd/generate/config/rules/alibaba.go new file mode 100644 index 000000000..6f7085b59 --- /dev/null +++ b/cmd/generate/config/rules/alibaba.go @@ -0,0 +1,41 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AlibabaAccessKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Alibaba AccessKey ID", + RuleID: "alibaba-access-key-id", + Regex: generateUniqueTokenRegex(`(LTAI)(?i)[a-z0-9]{20}`), + Keywords: []string{"LTAI"}, + } + + // validate + tps := []string{ + "alibabaKey := \"LTAI" + secrets.NewSecret(hex("20")) + "\"", + } + return validate(r, tps, nil) +} + +// TODO +func AlibabaSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Alibaba Secret Key", + RuleID: "alibaba-secret-key", + Regex: generateSemiGenericRegex([]string{"alibaba"}, + alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{"alibaba"}, + } + + // validate + tps := []string{ + generateSampleSecret("alibaba", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/asana.go b/cmd/generate/config/rules/asana.go new file mode 100644 index 000000000..888bc6574 --- /dev/null +++ b/cmd/generate/config/rules/asana.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func AsanaClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Asana Client ID", + RuleID: "asana-client-id", + Regex: generateSemiGenericRegex([]string{"asana"}, numeric("16")), + SecretGroup: 1, + Keywords: []string{"asana"}, + } + + // validate + tps := []string{ + generateSampleSecret("asana", secrets.NewSecret(numeric("16"))), + } + return validate(r, tps, nil) +} + +func AsanaClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Asana Client Secret", + RuleID: "asana-client-secret", + Regex: generateSemiGenericRegex([]string{"asana"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"asana"}, + } + + // validate + tps := []string{ + generateSampleSecret("asana", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/atlassian.go b/cmd/generate/config/rules/atlassian.go new file mode 100644 index 000000000..2da4f08df --- /dev/null +++ b/cmd/generate/config/rules/atlassian.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Atlassian() *config.Rule { + // define rule + r := config.Rule{ + Description: "Atlassian API token", + RuleID: "atlassian-api-token", + Regex: generateSemiGenericRegex([]string{ + "atlassian", "confluence", "jira"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{"atlassian", "confluence", "jira"}, + } + + // validate + tps := []string{ + generateSampleSecret("atlassian", secrets.NewSecret(alphaNumeric("24"))), + generateSampleSecret("confluence", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/aws.go b/cmd/generate/config/rules/aws.go new file mode 100644 index 000000000..a0339b741 --- /dev/null +++ b/cmd/generate/config/rules/aws.go @@ -0,0 +1,31 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func AWS() *config.Rule { + // define rule + r := config.Rule{ + Description: "AWS", + RuleID: "aws-access-token", + Regex: regexp.MustCompile( + "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Keywords: []string{ + "AKIA", + "AGPA", + "AIDA", + "AROA", + "AIPA", + "ANPA", + "ANVA", + "ASIA", + }, + } + + // validate + tps := []string{generateSampleSecret("AWS", "AKIALALEMEL33243OLIB")} // gitleaks:allow + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/beamer.go b/cmd/generate/config/rules/beamer.go new file mode 100644 index 000000000..a44239419 --- /dev/null +++ b/cmd/generate/config/rules/beamer.go @@ -0,0 +1,24 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Beamer() *config.Rule { + // define rule + r := config.Rule{ + Description: "Beamer API token", + RuleID: "beamer-api-token", + SecretGroup: 1, + Regex: generateSemiGenericRegex([]string{"beamer"}, + `b_[a-z0-9=_\-]{44}`), + Keywords: []string{"beamer"}, + } + + // validate + tps := []string{ + generateSampleSecret("beamer", "b_"+secrets.NewSecret(alphaNumericExtended("44"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/bitbucket.go b/cmd/generate/config/rules/bitbucket.go new file mode 100644 index 000000000..fe3a05298 --- /dev/null +++ b/cmd/generate/config/rules/bitbucket.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func BitBucketClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bitbucket Client ID", + RuleID: "bitbucket-client-id", + Regex: generateSemiGenericRegex([]string{"bitbucket"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bitbucket"}, + } + + // validate + tps := []string{ + generateSampleSecret("bitbucket", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func BitBucketClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bitbucket Client Secret", + RuleID: "bitbucket-client-secret", + Regex: generateSemiGenericRegex([]string{"bitbucket"}, alphaNumericExtended("64")), + SecretGroup: 1, + Keywords: []string{"bitbucket"}, + } + + // validate + tps := []string{ + generateSampleSecret("bitbucket", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/bittrex.go b/cmd/generate/config/rules/bittrex.go new file mode 100644 index 000000000..ccb9705ff --- /dev/null +++ b/cmd/generate/config/rules/bittrex.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func BittrexAccessKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bittrex Access Key", + RuleID: "bittrex-access-key", + Regex: generateSemiGenericRegex([]string{"bittrex"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bittrex"}, + } + + // validate + tps := []string{ + generateSampleSecret("bittrex", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func BittrexSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Bittrex Secret Key", + RuleID: "bittrex-secret-key", + Regex: generateSemiGenericRegex([]string{"bittrex"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{"bittrex"}, + } + + // validate + tps := []string{ + generateSampleSecret("bittrex", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/clojars.go b/cmd/generate/config/rules/clojars.go new file mode 100644 index 000000000..b7309c64b --- /dev/null +++ b/cmd/generate/config/rules/clojars.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Clojars() *config.Rule { + // define rule + r := config.Rule{ + Description: "Clojars API token", + RuleID: "clojars-api-token", + Regex: regexp.MustCompile(`(?i)(CLOJARS_)[a-z0-9]{60}`), + Keywords: []string{"clojars"}, + } + + // validate + tps := []string{ + generateSampleSecret("clojars", "CLOJARS_"+secrets.NewSecret(alphaNumeric("60"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/codecov.go b/cmd/generate/config/rules/codecov.go new file mode 100644 index 000000000..6b1b886b4 --- /dev/null +++ b/cmd/generate/config/rules/codecov.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func CodecovAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "codecov-access-token", + Description: "Codecov Access Token", + Regex: generateSemiGenericRegex([]string{"codecov"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "codecov", + }, + } + + // validate + tps := []string{ + generateSampleSecret("codecov", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/coinbase.go b/cmd/generate/config/rules/coinbase.go new file mode 100644 index 000000000..c5598c2ad --- /dev/null +++ b/cmd/generate/config/rules/coinbase.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func CoinbaseAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "coinbase-access-token", + Description: "Coinbase Access Token", + Regex: generateSemiGenericRegex([]string{"coinbase"}, + alphaNumericExtendedShort("64")), + SecretGroup: 1, + Keywords: []string{ + "coinbase", + }, + } + + // validate + tps := []string{ + generateSampleSecret("coinbase", + secrets.NewSecret(alphaNumericExtendedShort("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/config.tmpl b/cmd/generate/config/rules/config.tmpl new file mode 100644 index 000000000..25c2ce66e --- /dev/null +++ b/cmd/generate/config/rules/config.tmpl @@ -0,0 +1,60 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md + +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''', + '''node_modules''', + '''vendor''', +] + +{{ range $i, $rule := .Rules }}[[rules]] +{{ if and $rule.SecretGroup $rule.Entropy $rule.Allowlist.StopWords }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +entropy = {{ $rule.Entropy}} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] +[rules.allowlist] +stopwords= [{{ range $j, $stopword := $rule.Allowlist.StopWords }} + "{{$stopword}}",{{end}} +] +{{ else if and $rule.SecretGroup $rule.Entropy }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +entropy = {{ $rule.Entropy}} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{ else if $rule.SecretGroup }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +secretGroup = {{ $rule.SecretGroup }} +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{ else }}description = "{{$rule.Description}}" +id = "{{$rule.RuleID}}" +regex = '''{{$rule.Regex}}''' +keywords = [ + {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}} +] + +{{end}}{{end}} \ No newline at end of file diff --git a/cmd/generate/config/rules/confluent.go b/cmd/generate/config/rules/confluent.go new file mode 100644 index 000000000..a6d0c99a6 --- /dev/null +++ b/cmd/generate/config/rules/confluent.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ConfluentSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "confluent-secret-key", + Description: "Confluent Secret Key", + Regex: generateSemiGenericRegex([]string{"confluent"}, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "confluent", + }, + } + + // validate + tps := []string{ + generateSampleSecret("confluent", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} + +func ConfluentAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "confluent-access-token", + Description: "Confluent Access Token", + Regex: generateSemiGenericRegex([]string{"confluent"}, alphaNumeric("16")), + SecretGroup: 1, + Keywords: []string{ + "confluent", + }, + } + + // validate + tps := []string{ + generateSampleSecret("confluent", secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/contentful.go b/cmd/generate/config/rules/contentful.go new file mode 100644 index 000000000..fbf44cd15 --- /dev/null +++ b/cmd/generate/config/rules/contentful.go @@ -0,0 +1,24 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Contentful() *config.Rule { + // define rule + r := config.Rule{ + Description: "Contentful delivery API token", + RuleID: "contentful-delivery-api-token", + Regex: generateSemiGenericRegex([]string{"contentful"}, + alphaNumericExtended("43")), + SecretGroup: 1, + Keywords: []string{"contentful"}, + } + + // validate + tps := []string{ + generateSampleSecret("contentful", secrets.NewSecret(alphaNumeric("43"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/databricks.go b/cmd/generate/config/rules/databricks.go new file mode 100644 index 000000000..d7cd19d5b --- /dev/null +++ b/cmd/generate/config/rules/databricks.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Databricks() *config.Rule { + // define rule + r := config.Rule{ + Description: "Databricks API token", + RuleID: "databricks-api-token", + Regex: generateUniqueTokenRegex(`dapi[a-h0-9]{32}`), + Keywords: []string{"dapi"}, + } + + // validate + tps := []string{ + generateSampleSecret("databricks", "dapi"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/datadog.go b/cmd/generate/config/rules/datadog.go new file mode 100644 index 000000000..a39b918f2 --- /dev/null +++ b/cmd/generate/config/rules/datadog.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DatadogtokenAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "datadog-access-token", + Description: "Datadog Access Token", + Regex: generateSemiGenericRegex([]string{"datadog"}, + alphaNumeric("40")), + SecretGroup: 1, + Keywords: []string{ + "datadog", + }, + } + + // validate + tps := []string{ + generateSampleSecret("datadog", secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/digitalocean.go b/cmd/generate/config/rules/digitalocean.go new file mode 100644 index 000000000..623dcff87 --- /dev/null +++ b/cmd/generate/config/rules/digitalocean.go @@ -0,0 +1,51 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DigitalOceanPAT() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean Personal Access Token", + RuleID: "digitalocean-pat", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`dop_v1_[a-f0-9]{64}`), + Keywords: []string{"dop_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "dop_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DigitalOceanOAuthToken() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean OAuth Access Token", + RuleID: "digitalocean-access-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`doo_v1_[a-f0-9]{64}`), + Keywords: []string{"doo_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "doo_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DigitalOceanRefreshToken() *config.Rule { + r := config.Rule{ + Description: "DigitalOcean OAuth Refresh Token", + RuleID: "digitalocean-refresh-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`dor_v1_[a-f0-9]{64}`), + Keywords: []string{"dor_v1_"}, + } + + tps := []string{ + generateSampleSecret("do", "dor_v1_"+secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/discord.go b/cmd/generate/config/rules/discord.go new file mode 100644 index 000000000..4d1f13602 --- /dev/null +++ b/cmd/generate/config/rules/discord.go @@ -0,0 +1,57 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DiscordAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord API key", + RuleID: "discord-api-token", + Regex: generateSemiGenericRegex([]string{"discord"}, hex("64")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} + +func DiscordClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord client ID", + RuleID: "discord-client-id", + Regex: generateSemiGenericRegex([]string{"discord"}, numeric("18")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(numeric("18"))), + } + return validate(r, tps, nil) +} + +func DiscordClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Discord client secret", + RuleID: "discord-client-secret", + Regex: generateSemiGenericRegex([]string{"discord"}, alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{"discord"}, + } + + // validate + tps := []string{ + generateSampleSecret("discord", secrets.NewSecret(numeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/doppler.go b/cmd/generate/config/rules/doppler.go new file mode 100644 index 000000000..b94f2e86c --- /dev/null +++ b/cmd/generate/config/rules/doppler.go @@ -0,0 +1,27 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Doppler() *config.Rule { + // define rule + r := config.Rule{ + Description: "Doppler API token", + RuleID: "doppler-api-token", + Regex: regexp.MustCompile(`(dp\.pt\.)(?i)[a-z0-9]{43}`), + Keywords: []string{"doppler"}, + } + + // validate + tps := []string{ + generateSampleSecret("doppler", "dp.pt."+secrets.NewSecret(alphaNumeric("43"))), + } + return validate(r, tps, nil) +} + +// TODO add additional doppler formats: +// https://docs.doppler.com/reference/auth-token-formats diff --git a/cmd/generate/config/rules/droneci.go b/cmd/generate/config/rules/droneci.go new file mode 100644 index 000000000..03888d523 --- /dev/null +++ b/cmd/generate/config/rules/droneci.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DroneciAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "droneci-access-token", + Description: "Droneci Access Token", + Regex: generateSemiGenericRegex([]string{"droneci"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "droneci", + }, + } + + // validate + tps := []string{ + generateSampleSecret("droneci", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/dropbox.go b/cmd/generate/config/rules/dropbox.go new file mode 100644 index 000000000..375cc2fb6 --- /dev/null +++ b/cmd/generate/config/rules/dropbox.go @@ -0,0 +1,49 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func DropBoxAPISecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Dropbox API secret", + RuleID: "dropbox-api-token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, alphaNumeric("15")), + SecretGroup: 1, + Keywords: []string{"dropbox"}, + } + + // validate + tps := []string{ + generateSampleSecret("dropbox", secrets.NewSecret(alphaNumeric("15"))), + } + return validate(r, tps, nil) +} + +func DropBoxShortLivedAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "dropbox-short-lived-api-token", + Description: "Dropbox short lived API token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, `sl\.[a-z0-9\-=_]{135}`), + Keywords: []string{"dropbox"}, + } + + // validate TODO + return &r +} + +func DropBoxLongLivedAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "dropbox-long-lived-api-token", + Description: "Dropbox long lived API token", + Regex: generateSemiGenericRegex([]string{"dropbox"}, `[a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43}`), + Keywords: []string{"dropbox"}, + } + + // validate TODO + return &r +} diff --git a/cmd/generate/config/rules/duffel.go b/cmd/generate/config/rules/duffel.go new file mode 100644 index 000000000..5d5b428d2 --- /dev/null +++ b/cmd/generate/config/rules/duffel.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Duffel() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "duffel-api-token", + Description: "Duffel API token", + Regex: regexp.MustCompile(`duffel_(test|live)_(?i)[a-z0-9_\-=]{43}`), + Keywords: []string{"duffel"}, + } + + // validate + tps := []string{ + generateSampleSecret("duffel", "duffel_test_"+secrets.NewSecret(alphaNumericExtended("43"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/dynatrace.go b/cmd/generate/config/rules/dynatrace.go new file mode 100644 index 000000000..95b985152 --- /dev/null +++ b/cmd/generate/config/rules/dynatrace.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Dynatrace() *config.Rule { + // define rule + r := config.Rule{ + Description: "Dynatrace API token", + RuleID: "dynatrace-api-token", + Regex: regexp.MustCompile(`dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}`), + Keywords: []string{"dynatrace"}, + } + + // validate + tps := []string{ + generateSampleSecret("dynatrace", "dt0c01."+secrets.NewSecret(alphaNumeric("24"))+"."+secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/easypost.go b/cmd/generate/config/rules/easypost.go new file mode 100644 index 000000000..b2a3ace0f --- /dev/null +++ b/cmd/generate/config/rules/easypost.go @@ -0,0 +1,40 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func EasyPost() *config.Rule { + // define rule + r := config.Rule{ + Description: "EasyPost API token", + RuleID: "easypost-api-token", + Regex: regexp.MustCompile(`EZAK(?i)[a-z0-9]{54}`), + Keywords: []string{"EZAK"}, + } + + // validate + tps := []string{ + generateSampleSecret("EZAK", "EZAK"+secrets.NewSecret(alphaNumeric("54"))), + } + return validate(r, tps, nil) +} + +func EasyPostTestAPI() *config.Rule { + // define rule + r := config.Rule{ + Description: "EasyPost test API token", + RuleID: "easypost-test-api-token", + Regex: regexp.MustCompile(`EZTK(?i)[a-z0-9]{54}`), + Keywords: []string{"EZTK"}, + } + + // validate + tps := []string{ + generateSampleSecret("EZTK", "EZTK"+secrets.NewSecret(alphaNumeric("54"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/etsy.go b/cmd/generate/config/rules/etsy.go new file mode 100644 index 000000000..926308f5a --- /dev/null +++ b/cmd/generate/config/rules/etsy.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func EtsyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "etsy-access-token", + Description: "Etsy Access Token", + Regex: generateSemiGenericRegex([]string{"etsy"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{ + "etsy", + }, + } + + // validate + tps := []string{ + generateSampleSecret("etsy", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/facebook.go b/cmd/generate/config/rules/facebook.go new file mode 100644 index 000000000..d614e8e61 --- /dev/null +++ b/cmd/generate/config/rules/facebook.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Facebook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Facebook", + RuleID: "facebook", + Regex: generateSemiGenericRegex([]string{"facebook"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"facebook"}, + } + + // validate + tps := []string{ + generateSampleSecret("facebook", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/fastly.go b/cmd/generate/config/rules/fastly.go new file mode 100644 index 000000000..58a8db4ed --- /dev/null +++ b/cmd/generate/config/rules/fastly.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FastlyAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Fastly API key", + RuleID: "fastly-api-token", + Regex: generateSemiGenericRegex([]string{"fastly"}, alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{"fastly"}, + } + + // validate + tps := []string{ + generateSampleSecret("fastly", secrets.NewSecret(alphaNumericExtended("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/finicity.go b/cmd/generate/config/rules/finicity.go new file mode 100644 index 000000000..f85404875 --- /dev/null +++ b/cmd/generate/config/rules/finicity.go @@ -0,0 +1,40 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FinicityClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity Client Secret", + RuleID: "finicity-client-secret", + Regex: generateSemiGenericRegex([]string{"finicity"}, alphaNumeric("20")), + SecretGroup: 1, + Keywords: []string{"finicity"}, + } + + // validate + tps := []string{ + generateSampleSecret("finicity", secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} + +func FinicityAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity API token", + RuleID: "finicity-api-token", + Regex: generateSemiGenericRegex([]string{"finicity"}, hex("32")), + SecretGroup: 1, + Keywords: []string{"finicity"}, + } + + // validate + tps := []string{ + generateSampleSecret("finicity", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/finnhub.go b/cmd/generate/config/rules/finnhub.go new file mode 100644 index 000000000..61bf9129c --- /dev/null +++ b/cmd/generate/config/rules/finnhub.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FinnhubAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "finnhub-access-token", + Description: "Finnhub Access Token", + Regex: generateSemiGenericRegex([]string{"finnhub"}, alphaNumeric("20")), + SecretGroup: 1, + Keywords: []string{ + "finnhub", + }, + } + + // validate + tps := []string{ + generateSampleSecret("finnhub", secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/flickr.go b/cmd/generate/config/rules/flickr.go new file mode 100644 index 000000000..8d478e492 --- /dev/null +++ b/cmd/generate/config/rules/flickr.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FlickrAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "flickr-access-token", + Description: "Flickr Access Token", + Regex: generateSemiGenericRegex([]string{"flickr"}, alphaNumeric("32")), + SecretGroup: 1, + Keywords: []string{ + "flickr", + }, + } + + // validate + tps := []string{ + generateSampleSecret("flickr", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/flutterwave.go b/cmd/generate/config/rules/flutterwave.go new file mode 100644 index 000000000..98b9cffb1 --- /dev/null +++ b/cmd/generate/config/rules/flutterwave.go @@ -0,0 +1,56 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FlutterwavePublicKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Finicity Public Key", + RuleID: "flutterwave-public-key", + Regex: regexp.MustCompile(`FLWPUBK_TEST-(?i)[a-h0-9]{32}-X`), + Keywords: []string{"FLWPUBK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWPUBK_TEST-"+secrets.NewSecret(hex("32"))+"-X"), + } + return validate(r, tps, nil) +} + +func FlutterwaveSecretKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Flutterwave Secret Key", + RuleID: "flutterwave-secret-key", + Regex: regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{32}-X`), + Keywords: []string{"FLWSECK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+secrets.NewSecret(hex("32"))+"-X"), + } + return validate(r, tps, nil) +} + +func FlutterwaveEncKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Flutterwave Encryption Key", + RuleID: "flutterwave-encryption-key", + Regex: regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{12}`), + Keywords: []string{"FLWSECK_TEST"}, + } + + // validate + tps := []string{ + generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+secrets.NewSecret(hex("12"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/frameio.go b/cmd/generate/config/rules/frameio.go new file mode 100644 index 000000000..ecfa3673f --- /dev/null +++ b/cmd/generate/config/rules/frameio.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FrameIO() *config.Rule { + // define rule + r := config.Rule{ + Description: "Frame.io API token", + RuleID: "frameio-api-token", + Regex: regexp.MustCompile(`fio-u-(?i)[a-z0-9\-_=]{64}`), + Keywords: []string{"fio-u-"}, + } + + // validate + tps := []string{ + generateSampleSecret("frameio", "fio-u-"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/freshbooks.go b/cmd/generate/config/rules/freshbooks.go new file mode 100644 index 000000000..9cb36225f --- /dev/null +++ b/cmd/generate/config/rules/freshbooks.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func FreshbooksAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "freshbooks-access-token", + Description: "Freshbooks Access Token", + Regex: generateSemiGenericRegex([]string{"freshbooks"}, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "freshbooks", + }, + } + + // validate + tps := []string{ + generateSampleSecret("freshbooks", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gcp.go b/cmd/generate/config/rules/gcp.go new file mode 100644 index 000000000..cedd5e896 --- /dev/null +++ b/cmd/generate/config/rules/gcp.go @@ -0,0 +1,44 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +// TODO this one could probably use some work +func GCPServiceAccount() *config.Rule { + // define rule + r := config.Rule{ + Description: "Google (GCP) Service-account", + RuleID: "gcp-service-account", + Regex: regexp.MustCompile(`\"type\": \"service_account\"`), + Keywords: []string{`\"type\": \"service_account\"`}, + } + + // validate + tps := []string{ + `"type": "service_account"`, + } + return validate(r, tps, nil) +} + +func GCPAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gcp-api-key", + Description: "GCP API key", + Regex: generateUniqueTokenRegex(`AIza[0-9A-Za-z\\-_]{35}`), + SecretGroup: 1, + Keywords: []string{ + "AIza", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gcp", secrets.NewSecret(`AIza[0-9A-Za-z\\-_]{35}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/generic.go b/cmd/generate/config/rules/generic.go new file mode 100644 index 000000000..9cf8e7ad7 --- /dev/null +++ b/cmd/generate/config/rules/generic.go @@ -0,0 +1,55 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func GenericCredential() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "generic-api-key", + Description: "Generic API Key", + Regex: generateSemiGenericRegex([]string{ + "key", + "api", + "token", + "secret", + "client", + "passwd", + "password", + "auth", + "access", + }, `[0-9a-z\-_.=]{10,150}`), + SecretGroup: 1, + Keywords: []string{ + "key", + "api", + "token", + "secret", + "client", + "passwd", + "password", + "auth", + "access", + }, + Entropy: 3.5, + Allowlist: config.Allowlist{ + StopWords: DefaultStopWords, + }, + } + + // validate + tps := []string{ + generateSampleSecret("generic", "CLOJARS_34bf0e88955ff5a1c328d6a7491acc4f48e865a7b8dd4d70a70749037443"), + generateSampleSecret("generic", "Zf3D0LXCM3EIMbgJpUNnkRtOfOueHznB"), + `"client_id" : "0afae57f3ccfd9d7f5767067bc48b30f719e271ba470488056e37ab35d4b6506"`, + `"client_secret" : "6da89121079f83b2eb6acccf8219ea982c3d79bccc3e9c6a85856480661f8fde",`, + } + fps := []string{ + `client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.client-vpn-endpoint.id`, + `password combination. + +R5: Regulatory--21`, + } + return validate(r, tps, fps) +} diff --git a/cmd/generate/config/rules/github.go b/cmd/generate/config/rules/github.go new file mode 100644 index 000000000..5cc404359 --- /dev/null +++ b/cmd/generate/config/rules/github.go @@ -0,0 +1,73 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GitHubPat() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub Personal Access Token", + RuleID: "github-pat", + Regex: regexp.MustCompile(`ghp_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghp_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghp_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubOauth() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub OAuth Access Token", + RuleID: "github-oauth", + Regex: regexp.MustCompile(`gho_[0-9a-zA-Z]{36}`), + Keywords: []string{"gho_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "gho_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubApp() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub App Token", + RuleID: "github-app-token", + Regex: regexp.MustCompile(`(ghu|ghs)_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghu_", "ghs_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghu_"+secrets.NewSecret(alphaNumeric("36"))), + generateSampleSecret("github", "ghs_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} + +func GitHubRefresh() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitHub Refresh Token", + RuleID: "github-refresh-token", + Regex: regexp.MustCompile(`ghr_[0-9a-zA-Z]{36}`), + Keywords: []string{"ghr_"}, + } + + // validate + tps := []string{ + generateSampleSecret("github", "ghr_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gitlab.go b/cmd/generate/config/rules/gitlab.go new file mode 100644 index 000000000..623b48192 --- /dev/null +++ b/cmd/generate/config/rules/gitlab.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Gitlab() *config.Rule { + // define rule + r := config.Rule{ + Description: "GitLab Personal Access Token", + RuleID: "gitlab-pat", + Regex: regexp.MustCompile(`glpat-[0-9a-zA-Z\-\_]{20}`), + Keywords: []string{"glpat-"}, + } + + // validate + tps := []string{ + generateSampleSecret("gitlab", "glpat-"+secrets.NewSecret(alphaNumeric("20"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gitter.go b/cmd/generate/config/rules/gitter.go new file mode 100644 index 000000000..072a8d713 --- /dev/null +++ b/cmd/generate/config/rules/gitter.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GitterAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gitter-access-token", + Description: "Gitter Access Token", + Regex: generateSemiGenericRegex([]string{"gitter"}, + alphaNumericExtendedShort("40")), + SecretGroup: 1, + Keywords: []string{ + "gitter", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gitter", + secrets.NewSecret(alphaNumericExtendedShort("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/gocardless.go b/cmd/generate/config/rules/gocardless.go new file mode 100644 index 000000000..7e1203e79 --- /dev/null +++ b/cmd/generate/config/rules/gocardless.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GoCardless() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "gocardless-api-token", + Description: "GoCardless API token", + Regex: generateSemiGenericRegex([]string{"gocardless"}, `live_(?i)[a-z0-9\-_=]{40}`), + SecretGroup: 1, + Keywords: []string{ + "live_", + "gocardless", + }, + } + + // validate + tps := []string{ + generateSampleSecret("gocardless", "live_"+secrets.NewSecret(alphaNumericExtended("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/grafana.go b/cmd/generate/config/rules/grafana.go new file mode 100644 index 000000000..302847e6c --- /dev/null +++ b/cmd/generate/config/rules/grafana.go @@ -0,0 +1,65 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func GrafanaApiKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana api key (or Grafana cloud api key)", + RuleID: "grafana-api-key", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`eyJrIjoi[A-Za-z0-9]{70,400}={0,2}`), + Keywords: []string{"eyJrIjoi"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-api-key", + "eyJrIjoi"+ + secrets.NewSecret(alphaNumeric("70"))), + } + return validate(r, tps, nil) +} + +func GrafanaCloudApiToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana cloud api token", + RuleID: "grafana-cloud-api-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`glc_[A-Za-z0-9+/]{32,400}={0,2}`), + Keywords: []string{"glc_"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-cloud-api-token", + "glc_"+ + secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} + +func GrafanaServiceAccountToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Grafana service account token", + RuleID: "grafana-service-account-token", + SecretGroup: 1, + Regex: generateUniqueTokenRegex(`glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8}`), + Keywords: []string{"glsa_"}, + } + + // validate + tps := []string{ + generateSampleSecret("grafana-service-account-token", + "glsa_"+ + secrets.NewSecret(alphaNumeric("32"))+ + "_"+ + secrets.NewSecret((hex("8")))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/hashicorp.go b/cmd/generate/config/rules/hashicorp.go new file mode 100644 index 000000000..ce883b4ac --- /dev/null +++ b/cmd/generate/config/rules/hashicorp.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Hashicorp() *config.Rule { + // define rule + r := config.Rule{ + Description: "HashiCorp Terraform user/org API token", + RuleID: "hashicorp-tf-api-token", + Regex: regexp.MustCompile(`(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}`), + Keywords: []string{"atlasv1"}, + } + + // validate + tps := []string{ + generateSampleSecret("hashicorpToken", secrets.NewSecret(hex("14"))+".atlasv1."+secrets.NewSecret(alphaNumericExtended("60,70"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/heroku.go b/cmd/generate/config/rules/heroku.go new file mode 100644 index 000000000..599a04c52 --- /dev/null +++ b/cmd/generate/config/rules/heroku.go @@ -0,0 +1,22 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func Heroku() *config.Rule { + // define rule + r := config.Rule{ + Description: "Heroku API Key", + RuleID: "heroku-api-key", + Regex: generateSemiGenericRegex([]string{"heroku"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{"heroku"}, + } + + // validate + tps := []string{ + `const HEROKU_KEY = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/hubspot.go b/cmd/generate/config/rules/hubspot.go new file mode 100644 index 000000000..746284c21 --- /dev/null +++ b/cmd/generate/config/rules/hubspot.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func HubSpot() *config.Rule { + // define rule + r := config.Rule{ + Description: "HubSpot API Token", + RuleID: "hubspot-api-key", + Regex: generateSemiGenericRegex([]string{"hubspot"}, + `[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}`), + SecretGroup: 1, + Keywords: []string{"hubspot"}, + } + + // validate + tps := []string{ + `const hubspotKey = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/intercom.go b/cmd/generate/config/rules/intercom.go new file mode 100644 index 000000000..edb2bbd4a --- /dev/null +++ b/cmd/generate/config/rules/intercom.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Intercom() *config.Rule { + // define rule + r := config.Rule{ + Description: "Intercom API Token", + RuleID: "intercom-api-key", + Regex: generateSemiGenericRegex([]string{"intercom"}, alphaNumericExtended("60")), + SecretGroup: 1, + Keywords: []string{"intercom"}, + } + + // validate + tps := []string{ + generateSampleSecret("intercom", secrets.NewSecret(alphaNumericExtended("60"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/jwt.go b/cmd/generate/config/rules/jwt.go new file mode 100644 index 000000000..4d36d64d3 --- /dev/null +++ b/cmd/generate/config/rules/jwt.go @@ -0,0 +1,21 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/config" +) + +func JWT() *config.Rule { + // define rule + r := config.Rule{ + Description: "JSON Web Token", + RuleID: "jwt", + Regex: generateUniqueTokenRegex(`ey[0-9a-z]{30,34}\.ey[0-9a-z-\/_]{30,500}\.[0-9a-zA-Z-\/_]{10,200}`), + Keywords: []string{"ey"}, + } + + // validate + tps := []string{`eyJhbGciOieeeiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwic3ViZSI6IjEyMzQ1Njc4OTAiLCJuYW1lZWEiOiJKb2huIERvZSIsInN1ZmV3YWZiIjoiMTIzNDU2Nzg5MCIsIm5hbWVmZWF3ZnciOiJKb2huIERvZSIsIm5hbWVhZmV3ZmEiOiJKb2huIERvZSIsInN1ZndhZndlYWIiOiIxMjM0NTY3ODkwIiwibmFtZWZ3YWYiOiJKb2huIERvZSIsInN1YmZ3YWYiOiIxMjM0NTY3ODkwIiwibmFtZndhZSI6IkpvaG4gRG9lIiwiaWZ3YWZhYXQiOjE1MTYyMzkwMjJ9.a_5icKBDo-8EjUlrfvz2k2k-FYaindQ0DEYNrlsnRG0`, // gitleaks:allow + `JWT := eyJhbGciOieeeiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwic3ViZSI6IjEyMzQ1Njc4OTAiLCJuYW1lZWEiOiJKb2huIERvZSIsInN1ZmV3YWZiIjoiMTIzNDU2Nzg5MCIsIm5hbWVmZWF3ZnciOiJKb2huIERvZSIsIm5hbWVhZmV3ZmEiOiJKb2huIERvZSIsInN1ZndhZndlYWIiOiIxMjM0NTY3ODkwIiwibmFtZWZ3YWYiOiJKb2huIERvZSIsInN1YmZ3YWYiOiIxMjM0NTY3ODkwIiwibmFtZndhZSI6IkpvaG4gRG9lIiwiaWZ3YWZhYXQiOjE1MTYyMzkwMjJ9.a_5icKBDo-8EjUlrfvz2k2k-FYaindQ0DEYNrlsnRG0`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/kraken.go b/cmd/generate/config/rules/kraken.go new file mode 100644 index 000000000..dafabe1d0 --- /dev/null +++ b/cmd/generate/config/rules/kraken.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func KrakenAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kraken-access-token", + Description: "Kraken Access Token", + Regex: generateSemiGenericRegex([]string{"kraken"}, + alphaNumericExtendedLong("80,90")), + SecretGroup: 1, + Keywords: []string{ + "kraken", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kraken", + secrets.NewSecret(alphaNumericExtendedLong("80,90"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/kucoin.go b/cmd/generate/config/rules/kucoin.go new file mode 100644 index 000000000..fd1c39135 --- /dev/null +++ b/cmd/generate/config/rules/kucoin.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func KucoinAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kucoin-access-token", + Description: "Kucoin Access Token", + Regex: generateSemiGenericRegex([]string{"kucoin"}, hex("24")), + SecretGroup: 1, + Keywords: []string{ + "kucoin", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kucoin", secrets.NewSecret(hex("24"))), + } + return validate(r, tps, nil) +} + +func KucoinSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "kucoin-secret-key", + Description: "Kucoin Secret Key", + Regex: generateSemiGenericRegex([]string{"kucoin"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "kucoin", + }, + } + + // validate + tps := []string{ + generateSampleSecret("kucoin", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/launchdarkly.go b/cmd/generate/config/rules/launchdarkly.go new file mode 100644 index 000000000..84814c366 --- /dev/null +++ b/cmd/generate/config/rules/launchdarkly.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LaunchDarklyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "launchdarkly-access-token", + Description: "Launchdarkly Access Token", + Regex: generateSemiGenericRegex([]string{"launchdarkly"}, alphaNumericExtended("40")), + SecretGroup: 1, + Keywords: []string{ + "launchdarkly", + }, + } + + // validate + tps := []string{ + generateSampleSecret("launchdarkly", secrets.NewSecret(alphaNumericExtended("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/linear.go b/cmd/generate/config/rules/linear.go new file mode 100644 index 000000000..270cd2391 --- /dev/null +++ b/cmd/generate/config/rules/linear.go @@ -0,0 +1,41 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LinearAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Linear API Token", + RuleID: "linear-api-key", + Regex: regexp.MustCompile(`lin_api_(?i)[a-z0-9]{40}`), + Keywords: []string{"lin_api_"}, + } + + // validate + tps := []string{ + generateSampleSecret("linear", "lin_api_"+secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} + +func LinearClientSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Linear Client Secret", + RuleID: "linear-client-secret", + Regex: generateSemiGenericRegex([]string{"linear"}, hex("32")), + Keywords: []string{"linear"}, + SecretGroup: 1, + } + + // validate + tps := []string{ + generateSampleSecret("linear", secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/linkedin.go b/cmd/generate/config/rules/linkedin.go new file mode 100644 index 000000000..2df9c6dc8 --- /dev/null +++ b/cmd/generate/config/rules/linkedin.go @@ -0,0 +1,52 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LinkedinClientSecret() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "linkedin-client-secret", + Description: "LinkedIn Client secret", + Regex: generateSemiGenericRegex([]string{ + "linkedin", + "linked-in", + }, alphaNumeric("16")), + SecretGroup: 1, + Keywords: []string{ + "linkedin", + "linked-in", + }, + } + + // validate + tps := []string{ + generateSampleSecret("linkedin", secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} + +func LinkedinClientID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "linkedin-client-id", + Description: "LinkedIn Client ID", + Regex: generateSemiGenericRegex([]string{ + "linkedin", + "linked-in", + }, alphaNumeric("14")), + SecretGroup: 1, + Keywords: []string{ + "linkedin", + "linked-in", + }, + } + + // validate + tps := []string{ + generateSampleSecret("linkedin", secrets.NewSecret(alphaNumeric("14"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/lob.go b/cmd/generate/config/rules/lob.go new file mode 100644 index 000000000..3aea66172 --- /dev/null +++ b/cmd/generate/config/rules/lob.go @@ -0,0 +1,47 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func LobPubAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Lob Publishable API Key", + RuleID: "lob-pub-api-key", + Regex: generateSemiGenericRegex([]string{"lob"}, `(test|live)_pub_[a-f0-9]{31}`), + SecretGroup: 1, + Keywords: []string{ + "test_pub", + "live_pub", + "_pub", + }, + } + + // validate + tps := []string{ + generateSampleSecret("lob", "test_pub_"+secrets.NewSecret(hex("31"))), + } + return validate(r, tps, nil) +} + +func LobAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Lob API Key", + RuleID: "lob-api-key", + Regex: generateSemiGenericRegex([]string{"lob"}, `(live|test)_[a-f0-9]{35}`), + Keywords: []string{ + "test_", + "live_", + }, + SecretGroup: 1, + } + + // validate + tps := []string{ + generateSampleSecret("lob", "test_"+secrets.NewSecret(hex("35"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mailchimp.go b/cmd/generate/config/rules/mailchimp.go new file mode 100644 index 000000000..7fa87b904 --- /dev/null +++ b/cmd/generate/config/rules/mailchimp.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MailChimp() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailchimp-api-key", + Description: "Mailchimp API key", + Regex: generateSemiGenericRegex([]string{"mailchimp"}, `[a-f0-9]{32}-us20`), + SecretGroup: 1, + Keywords: []string{ + "mailchimp", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailchimp", secrets.NewSecret(hex("32"))+"-us20"), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mailgun.go b/cmd/generate/config/rules/mailgun.go new file mode 100644 index 000000000..c135e7273 --- /dev/null +++ b/cmd/generate/config/rules/mailgun.go @@ -0,0 +1,63 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MailGunPrivateAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-private-api-token", + Description: "Mailgun private API token", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `key-[a-f0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", "key-"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func MailGunPubAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-pub-key", + Description: "Mailgun public validation key", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `pubkey-[a-f0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", "pubkey-"+secrets.NewSecret(hex("32"))), + } + return validate(r, tps, nil) +} + +func MailGunSigningKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mailgun-signing-key", + Description: "Mailgun webhook signing key", + Regex: generateSemiGenericRegex([]string{"mailgun"}, `[a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8}`), + SecretGroup: 1, + Keywords: []string{ + "mailgun", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mailgun", secrets.NewSecret(hex("32"))+"-00001111-22223333"), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mapbox.go b/cmd/generate/config/rules/mapbox.go new file mode 100644 index 000000000..bed791fac --- /dev/null +++ b/cmd/generate/config/rules/mapbox.go @@ -0,0 +1,23 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MapBox() *config.Rule { + // define rule + r := config.Rule{ + Description: "MapBox API token", + RuleID: "mapbox-api-token", + Regex: generateSemiGenericRegex([]string{"mapbox"}, `pk\.[a-z0-9]{60}\.[a-z0-9]{22}`), + SecretGroup: 1, + Keywords: []string{"mapbox"}, + } + + // validate + tps := []string{ + generateSampleSecret("mapbox", "pk."+secrets.NewSecret(alphaNumeric("60"))+"."+secrets.NewSecret(alphaNumeric("22"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/mattermost.go b/cmd/generate/config/rules/mattermost.go new file mode 100644 index 000000000..7f73ba85d --- /dev/null +++ b/cmd/generate/config/rules/mattermost.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MattermostAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "mattermost-access-token", + Description: "Mattermost Access Token", + Regex: generateSemiGenericRegex([]string{"mattermost"}, alphaNumeric("26")), + SecretGroup: 1, + Keywords: []string{ + "mattermost", + }, + } + + // validate + tps := []string{ + generateSampleSecret("mattermost", secrets.NewSecret(alphaNumeric("26"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/messagebird.go b/cmd/generate/config/rules/messagebird.go new file mode 100644 index 000000000..6973a4fb5 --- /dev/null +++ b/cmd/generate/config/rules/messagebird.go @@ -0,0 +1,58 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func MessageBirdAPIToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "MessageBird API token", + RuleID: "messagebird-api-token", + Regex: generateSemiGenericRegex([]string{ + "messagebird", + "message-bird", + "message_bird", + }, alphaNumeric("25")), + SecretGroup: 1, + Keywords: []string{ + "messagebird", + "message-bird", + "message_bird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("messagebird", secrets.NewSecret(alphaNumeric("25"))), + generateSampleSecret("message-bird", secrets.NewSecret(alphaNumeric("25"))), + generateSampleSecret("message_bird", secrets.NewSecret(alphaNumeric("25"))), + } + return validate(r, tps, nil) +} + +func MessageBirdClientID() *config.Rule { + // define rule + r := config.Rule{ + Description: "MessageBird client ID", + RuleID: "messagebird-client-id", + Regex: generateSemiGenericRegex([]string{ + "messagebird", + "message-bird", + "message_bird", + }, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "messagebird", + "message-bird", + "message_bird", + }, + } + + // validate + tps := []string{ + `const MessageBirdClientID = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/netlify.go b/cmd/generate/config/rules/netlify.go new file mode 100644 index 000000000..2997c65e0 --- /dev/null +++ b/cmd/generate/config/rules/netlify.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NetlifyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "netlify-access-token", + Description: "Netlify Access Token", + Regex: generateSemiGenericRegex([]string{"netlify"}, + alphaNumericExtended("40,46")), + SecretGroup: 1, + Keywords: []string{ + "netlify", + }, + } + + // validate + tps := []string{ + generateSampleSecret("netlify", secrets.NewSecret(alphaNumericExtended("40,46"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/newrelic.go b/cmd/generate/config/rules/newrelic.go new file mode 100644 index 000000000..8f5645e58 --- /dev/null +++ b/cmd/generate/config/rules/newrelic.go @@ -0,0 +1,77 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NewRelicUserID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-user-api-key", + Description: "New Relic user API Key", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, `NRAK-[a-z0-9]{27}`), + SecretGroup: 1, + Keywords: []string{ + "NRAK", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", "NRAK-"+secrets.NewSecret(alphaNumeric("27"))), + } + return validate(r, tps, nil) +} + +func NewRelicUserKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-user-api-id", + Description: "New Relic user API ID", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "new-relic", + "newrelic", + "new_relic", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} + +func NewRelicBrowserAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "new-relic-browser-api-token", + Description: "New Relic ingest browser API token", + Regex: generateSemiGenericRegex([]string{ + "new-relic", + "newrelic", + "new_relic", + }, `NRJS-[a-f0-9]{19}`), + SecretGroup: 1, + Keywords: []string{ + "NRJS-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("new-relic", "NRJS-"+secrets.NewSecret(hex("19"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/npm.go b/cmd/generate/config/rules/npm.go new file mode 100644 index 000000000..96031fceb --- /dev/null +++ b/cmd/generate/config/rules/npm.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NPM() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "npm-access-token", + Description: "npm access token", + Regex: generateUniqueTokenRegex(`npm_[a-z0-9]{36}`), + SecretGroup: 1, + Keywords: []string{ + "npm_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("npmAccessToken", "npm_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/nytimes.go b/cmd/generate/config/rules/nytimes.go new file mode 100644 index 000000000..58fb6df86 --- /dev/null +++ b/cmd/generate/config/rules/nytimes.go @@ -0,0 +1,29 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func NytimesAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "nytimes-access-token", + Description: "Nytimes Access Token", + Regex: generateSemiGenericRegex([]string{ + "nytimes", "new-york-times,", "newyorktimes"}, + alphaNumericExtended("32")), + SecretGroup: 1, + Keywords: []string{ + "nytimes", + "new-york-times", + "newyorktimes", + }, + } + + // validate + tps := []string{ + generateSampleSecret("nytimes", secrets.NewSecret(alphaNumeric("32"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/okta.go b/cmd/generate/config/rules/okta.go new file mode 100644 index 000000000..650ffc4fe --- /dev/null +++ b/cmd/generate/config/rules/okta.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func OktaAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "okta-access-token", + Description: "Okta Access Token", + Regex: generateSemiGenericRegex([]string{"okta"}, + alphaNumericExtended("42")), + SecretGroup: 1, + Keywords: []string{ + "okta", + }, + } + + // validate + tps := []string{ + generateSampleSecret("okta", secrets.NewSecret(alphaNumeric("42"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/plaid.go b/cmd/generate/config/rules/plaid.go new file mode 100644 index 000000000..8cfc16d00 --- /dev/null +++ b/cmd/generate/config/rules/plaid.go @@ -0,0 +1,66 @@ +package rules + +import ( + "fmt" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PlaidAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-client-id", + Description: "Plaid Client ID", + Regex: generateSemiGenericRegex([]string{"plaid"}, alphaNumeric("24")), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(alphaNumeric("24"))), + } + return validate(r, tps, nil) +} + +func PlaidSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-secret-key", + Description: "Plaid Secret key", + Regex: generateSemiGenericRegex([]string{"plaid"}, alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} + +func PlaidAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "plaid-api-token", + Description: "Plaid API Token", + Regex: generateSemiGenericRegex([]string{"plaid"}, + fmt.Sprintf("access-(?:sandbox|development|production)-%s", hex8_4_4_4_12())), + SecretGroup: 1, + Keywords: []string{ + "plaid", + }, + } + + // validate + tps := []string{ + generateSampleSecret("plaid", secrets.NewSecret(fmt.Sprintf("access-(?:sandbox|development|production)-%s", hex8_4_4_4_12()))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/planetscale.go b/cmd/generate/config/rules/planetscale.go new file mode 100644 index 000000000..847055123 --- /dev/null +++ b/cmd/generate/config/rules/planetscale.go @@ -0,0 +1,69 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PlanetScalePassword() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-password", + Description: "PlanetScale password", + Regex: generateUniqueTokenRegex(`pscale_pw_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_pw_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_pw_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} + +func PlanetScaleAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-api-token", + Description: "PlanetScale API token", + Regex: generateUniqueTokenRegex(`pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_tkn_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_tkn_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} + +func PlanetScaleOAuthToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "planetscale-oauth-token", + Description: "PlanetScale OAuth token", + Regex: generateUniqueTokenRegex(`pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64}`), + SecretGroup: 1, + Keywords: []string{ + "pscale_oauth_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("32"))), + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("43"))), + generateSampleSecret("planetScalePassword", "pscale_oauth_"+secrets.NewSecret(alphaNumericExtended("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/postman.go b/cmd/generate/config/rules/postman.go new file mode 100644 index 000000000..5e2bf3762 --- /dev/null +++ b/cmd/generate/config/rules/postman.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PostManAPI() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "postman-api-token", + Description: "Postman API token", + Regex: generateUniqueTokenRegex(`PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34}`), + SecretGroup: 1, + Keywords: []string{ + "PMAK-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("postmanAPItoken", "PMAK-"+secrets.NewSecret(hex("24"))+"-"+secrets.NewSecret(hex("34"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/prefect.go b/cmd/generate/config/rules/prefect.go new file mode 100644 index 000000000..5ab23137d --- /dev/null +++ b/cmd/generate/config/rules/prefect.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Prefect() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "prefect-api-token", + Description: "Prefect API token", + Regex: generateUniqueTokenRegex(`pnu_[a-z0-9]{36}`), + SecretGroup: 1, + Keywords: []string{ + "pnu_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("api-token", "pnu_"+secrets.NewSecret(alphaNumeric("36"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/privatekey.go b/cmd/generate/config/rules/privatekey.go new file mode 100644 index 000000000..9ca2a995c --- /dev/null +++ b/cmd/generate/config/rules/privatekey.go @@ -0,0 +1,28 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func PrivateKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Private Key", + RuleID: "private-key", + Regex: regexp.MustCompile(`(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY----`), + Keywords: []string{"-----BEGIN"}, + } + + // validate + tps := []string{`-----BEGIN PRIVATE KEY----- +anything +-----END PRIVATE KEY-----`, + `-----BEGIN RSA PRIVATE KEY----- +abcdefghijklmnopqrstuvwxyz +-----END RSA PRIVATE KEY----- +`, + } // gitleaks:allow + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/pulumi.go b/cmd/generate/config/rules/pulumi.go new file mode 100644 index 000000000..53edea9dc --- /dev/null +++ b/cmd/generate/config/rules/pulumi.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PulumiAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "pulumi-api-token", + Description: "Pulumi API token", + Regex: generateUniqueTokenRegex(`pul-[a-f0-9]{40}`), + SecretGroup: 1, + Keywords: []string{ + "pul-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("pulumi-api-token", "pul-"+secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/pypi.go b/cmd/generate/config/rules/pypi.go new file mode 100644 index 000000000..9fcdc0e01 --- /dev/null +++ b/cmd/generate/config/rules/pypi.go @@ -0,0 +1,26 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func PyPiUploadToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "PyPI upload token", + RuleID: "pypi-upload-token", + Regex: regexp.MustCompile( + `pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}`), + Keywords: []string{ + "pypi-AgEIcHlwaS5vcmc", + }, + } + + // validate + tps := []string{"pypiToken := \"pypi-AgEIcHlwaS5vcmc" + secrets.NewSecret(hex("32")) + + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rapidapi.go b/cmd/generate/config/rules/rapidapi.go new file mode 100644 index 000000000..dd2841ea1 --- /dev/null +++ b/cmd/generate/config/rules/rapidapi.go @@ -0,0 +1,27 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func RapidAPIAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "rapidapi-access-token", + Description: "RapidAPI Access Token", + Regex: generateSemiGenericRegex([]string{"rapidapi"}, + alphaNumericExtendedShort("50")), + SecretGroup: 1, + Keywords: []string{ + "rapidapi", + }, + } + + // validate + tps := []string{ + generateSampleSecret("rapidapi", + secrets.NewSecret(alphaNumericExtendedShort("50"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/readme.go b/cmd/generate/config/rules/readme.go new file mode 100644 index 000000000..ac68cced2 --- /dev/null +++ b/cmd/generate/config/rules/readme.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ReadMe() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "readme-api-token", + Description: "Readme API token", + Regex: generateUniqueTokenRegex(`rdme_[a-z0-9]{70}`), + SecretGroup: 1, + Keywords: []string{ + "rdme_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("api-token", "rdme_"+secrets.NewSecret(alphaNumeric("70"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rubygems.go b/cmd/generate/config/rules/rubygems.go new file mode 100644 index 000000000..8329cd741 --- /dev/null +++ b/cmd/generate/config/rules/rubygems.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func RubyGemsAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "rubygems-api-token", + Description: "Rubygem API token", + Regex: generateUniqueTokenRegex(`rubygems_[a-f0-9]{48}`), + SecretGroup: 1, + Keywords: []string{ + "rubygems_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("rubygemsAPIToken", "rubygems_"+secrets.NewSecret(hex("48"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/rule.go b/cmd/generate/config/rules/rule.go new file mode 100644 index 000000000..24d4e9016 --- /dev/null +++ b/cmd/generate/config/rules/rule.go @@ -0,0 +1,110 @@ +package rules + +import ( + "fmt" + "regexp" + "strings" + + "github.com/rs/zerolog/log" + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" +) + +const ( + // case insensitive prefix + caseInsensitive = `(?i)` + + // identifier prefix (just an ignore group) + identifierPrefix = `(?:` + identifierSuffix = `)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}` + + // commonly used assignment operators or function call + operator = `(?:=|>|:=|\|\|:|<=|=>|:)` + + // boundaries for the secret + // \x60 = ` + secretPrefixUnique = `\b(` + secretPrefix = `(?:'|\"|\s|=|\x60){0,5}(` + secretSuffix = `)(?:['|\"|\n|\r|\s|\x60|;]|$)` +) + +func generateSemiGenericRegex(identifiers []string, secretRegex string) *regexp.Regexp { + var sb strings.Builder + sb.WriteString(caseInsensitive) + sb.WriteString(identifierPrefix) + sb.WriteString(strings.Join(identifiers, "|")) + sb.WriteString(identifierSuffix) + sb.WriteString(operator) + sb.WriteString(secretPrefix) + sb.WriteString(secretRegex) + sb.WriteString(secretSuffix) + return regexp.MustCompile(sb.String()) +} + +func generateUniqueTokenRegex(secretRegex string) *regexp.Regexp { + var sb strings.Builder + sb.WriteString(caseInsensitive) + sb.WriteString(secretPrefixUnique) + sb.WriteString(secretRegex) + sb.WriteString(secretSuffix) + return regexp.MustCompile(sb.String()) +} + +func generateSampleSecret(identifier string, secret string) string { + return fmt.Sprintf("%s_api_token = \"%s\"", identifier, secret) +} + +func validate(r config.Rule, truePositives []string, falsePositives []string) *config.Rule { + // normalize keywords like in the config package + var keywords []string + for _, k := range r.Keywords { + keywords = append(keywords, strings.ToLower(k)) + } + r.Keywords = keywords + + rules := make(map[string]config.Rule) + rules[r.RuleID] = r + d := detect.NewDetector(config.Config{ + Rules: rules, + Keywords: keywords, + }) + for _, tp := range truePositives { + if len(d.DetectString(tp)) != 1 { + log.Fatal().Msgf("Failed to validate. For rule ID [%s], true positive [%s] was not detected by regexp [%s]", r.RuleID, tp, r.Regex) + } + } + for _, fp := range falsePositives { + if len(d.DetectString(fp)) != 0 { + log.Fatal().Msgf("Failed to validate (fp) [%s]", r.RuleID) + } + } + return &r +} + +func numeric(size string) string { + return fmt.Sprintf(`[0-9]{%s}`, size) +} + +func hex(size string) string { + return fmt.Sprintf(`[a-f0-9]{%s}`, size) +} + +func alphaNumeric(size string) string { + return fmt.Sprintf(`[a-z0-9]{%s}`, size) +} + +func alphaNumericExtendedShort(size string) string { + return fmt.Sprintf(`[a-z0-9_-]{%s}`, size) +} + +func alphaNumericExtended(size string) string { + return fmt.Sprintf(`[a-z0-9=_\-]{%s}`, size) +} + +func alphaNumericExtendedLong(size string) string { + return fmt.Sprintf(`[a-z0-9\/=_\+\-]{%s}`, size) +} + +func hex8_4_4_4_12() string { + return `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}` +} diff --git a/cmd/generate/config/rules/sendbird.go b/cmd/generate/config/rules/sendbird.go new file mode 100644 index 000000000..204768318 --- /dev/null +++ b/cmd/generate/config/rules/sendbird.go @@ -0,0 +1,44 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendbirdAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendbird-access-token", + Description: "Sendbird Access Token", + Regex: generateSemiGenericRegex([]string{"sendbird"}, hex("40")), + SecretGroup: 1, + Keywords: []string{ + "sendbird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendbird", secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} + +func SendbirdAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendbird-access-id", + Description: "Sendbird Access ID", + Regex: generateSemiGenericRegex([]string{"sendbird"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "sendbird", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendbird", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sendgrid.go b/cmd/generate/config/rules/sendgrid.go new file mode 100644 index 000000000..80b1001a9 --- /dev/null +++ b/cmd/generate/config/rules/sendgrid.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendGridAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendgrid-api-token", + Description: "SendGrid API token", + Regex: generateUniqueTokenRegex(`SG\.(?i)[a-z0-9=_\-\.]{66}`), + SecretGroup: 1, + Keywords: []string{ + "SG.", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sengridAPIToken", "SG."+secrets.NewSecret(alphaNumericExtended("66"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sendinblue.go b/cmd/generate/config/rules/sendinblue.go new file mode 100644 index 000000000..41f75104d --- /dev/null +++ b/cmd/generate/config/rules/sendinblue.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SendInBlueAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sendinblue-api-token", + Description: "Sendinblue API token", + Regex: generateUniqueTokenRegex(`xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16}`), + SecretGroup: 1, + Keywords: []string{ + "xkeysib-", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sendinblue", "xkeysib-"+secrets.NewSecret(hex("64"))+"-"+secrets.NewSecret(alphaNumeric("16"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sentry.go b/cmd/generate/config/rules/sentry.go new file mode 100644 index 000000000..74452ebbc --- /dev/null +++ b/cmd/generate/config/rules/sentry.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SentryAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sentry-access-token", + Description: "Sentry Access Token", + Regex: generateSemiGenericRegex([]string{"sentry"}, hex("64")), + SecretGroup: 1, + Keywords: []string{ + "sentry", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sentry", secrets.NewSecret(hex("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/shippo.go b/cmd/generate/config/rules/shippo.go new file mode 100644 index 000000000..494777e15 --- /dev/null +++ b/cmd/generate/config/rules/shippo.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ShippoAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "shippo-api-token", + Description: "Shippo API token", + Regex: generateUniqueTokenRegex(`shippo_(live|test)_[a-f0-9]{40}`), + SecretGroup: 1, + Keywords: []string{ + "shippo_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("shippo", "shippo_live_"+secrets.NewSecret(hex("40"))), + generateSampleSecret("shippo", "shippo_test_"+secrets.NewSecret(hex("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/shopify.go b/cmd/generate/config/rules/shopify.go new file mode 100644 index 000000000..b6bf4e881 --- /dev/null +++ b/cmd/generate/config/rules/shopify.go @@ -0,0 +1,64 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ShopifySharedSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify shared secret", + RuleID: "shopify-shared-secret", + Regex: regexp.MustCompile(`shpss_[a-fA-F0-9]{32}`), + Keywords: []string{"shpss_"}, + } + + // validate + tps := []string{"shopifySecret := \"shpss_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify access token", + RuleID: "shopify-access-token", + Regex: regexp.MustCompile(`shpat_[a-fA-F0-9]{32}`), + Keywords: []string{"shpat_"}, + } + + // validate + tps := []string{"shopifyToken := \"shpat_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyCustomAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify custom access token", + RuleID: "shopify-custom-access-token", + Regex: regexp.MustCompile(`shpca_[a-fA-F0-9]{32}`), + Keywords: []string{"shpca_"}, + } + + // validate + tps := []string{"shopifyToken := \"shpca_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} + +func ShopifyPrivateAppAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Shopify private app access token", + RuleID: "shopify-private-app-access-token", + Regex: regexp.MustCompile(`shppa_[a-fA-F0-9]{32}`), + Keywords: []string{"shppa_"}, + } + + // validate + tps := []string{"shopifyToken := \"shppa_" + secrets.NewSecret(hex("32")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sidekiq.go b/cmd/generate/config/rules/sidekiq.go new file mode 100644 index 000000000..71f0c8059 --- /dev/null +++ b/cmd/generate/config/rules/sidekiq.go @@ -0,0 +1,60 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func SidekiqSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Sidekiq Secret", + RuleID: "sidekiq-secret", + SecretGroup: 1, + Regex: generateSemiGenericRegex([]string{"BUNDLE_ENTERPRISE__CONTRIBSYS__COM", "BUNDLE_GEMS__CONTRIBSYS__COM"}, + `[a-f0-9]{8}:[a-f0-9]{8}`), + Keywords: []string{"BUNDLE_ENTERPRISE__CONTRIBSYS__COM", "BUNDLE_GEMS__CONTRIBSYS__COM"}, + } + + // validate + tps := []string{ + "BUNDLE_ENTERPRISE__CONTRIBSYS__COM: cafebabe:deadbeef", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM = cafebabe:deadbeef", + "BUNDLE_GEMS__CONTRIBSYS__COM: \"cafebabe:deadbeef\"", + "export BUNDLE_GEMS__CONTRIBSYS__COM=\"cafebabe:deadbeef\"", + "export BUNDLE_GEMS__CONTRIBSYS__COM = \"cafebabe:deadbeef\"", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;", + "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef && echo 'hello world'", + } + return validate(r, tps, nil) +} + +func SidekiqSensitiveUrl() *config.Rule { + // define rule + r := config.Rule{ + Description: "Sidekiq Sensitive URL", + RuleID: "sidekiq-sensitive-url", + SecretGroup: 2, + Regex: regexp.MustCompile(`(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)`), + Keywords: []string{"gems.contribsys.com", "enterprise.contribsys.com"}, + } + + // validate + tps := []string{ + "https://cafebabe:deadbeef@gems.contribsys.com/", + "https://cafebabe:deadbeef@gems.contribsys.com", + "https://cafeb4b3:d3adb33f@enterprise.contribsys.com/", + "https://cafeb4b3:d3adb33f@enterprise.contribsys.com", + "http://cafebabe:deadbeef@gems.contribsys.com/", + "http://cafebabe:deadbeef@gems.contribsys.com", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com/", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com#heading1", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com?param1=true¶m2=false", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80", + "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/slack.go b/cmd/generate/config/rules/slack.go new file mode 100644 index 000000000..63484be06 --- /dev/null +++ b/cmd/generate/config/rules/slack.go @@ -0,0 +1,51 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SlackAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Slack token", + RuleID: "slack-access-token", + Regex: regexp.MustCompile( + "xox[baprs]-([0-9a-zA-Z]{10,48})"), + Keywords: []string{ + "xoxb", + "xoxa", + "xoxp", + "xoxr", + "xoxs", + }, + } + + // validate + tps := []string{ + "\"slackToken\": \"xoxb-" + secrets.NewSecret(alphaNumeric("30")) + "\"", + } + return validate(r, tps, nil) +} + +func SlackWebHook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Slack Webhook", + RuleID: "slack-web-hook", + Regex: regexp.MustCompile( + `https:\/\/hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{44,46}`), + Keywords: []string{ + "hooks.slack.com", + }, + } + + // validate + tps := []string{ + "https://hooks.slack.com/services/" + secrets.NewSecret(alphaNumeric("44")), // gitleaks:allow + "https://hooks.slack.com/workflows/" + secrets.NewSecret(alphaNumeric("44")), // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/square.go b/cmd/generate/config/rules/square.go new file mode 100644 index 000000000..a9da8fb76 --- /dev/null +++ b/cmd/generate/config/rules/square.go @@ -0,0 +1,38 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SquareAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "square-access-token", + Description: "Square Access Token", + Regex: generateUniqueTokenRegex(`sq0atp-[0-9A-Za-z\-_]{22}`), + Keywords: []string{"sq0atp-"}, + } + + // validate + tps := []string{ + generateSampleSecret("square", secrets.NewSecret(`sq0atp-[0-9A-Za-z\-_]{22}`)), + } + return validate(r, tps, nil) +} + +func SquareSecret() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "square-secret", + Description: "Square Secret", + Regex: generateUniqueTokenRegex(`sq0csp-[0-9A-Za-z\\-_]{43}`), + Keywords: []string{"sq0csp-"}, + } + + // validate + tps := []string{ + generateSampleSecret("square", secrets.NewSecret(`sq0csp-[0-9A-Za-z\\-_]{43}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/squarespace.go b/cmd/generate/config/rules/squarespace.go new file mode 100644 index 000000000..51b7deab2 --- /dev/null +++ b/cmd/generate/config/rules/squarespace.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SquareSpaceAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "squarespace-access-token", + Description: "Squarespace Access Token", + Regex: generateSemiGenericRegex([]string{"squarespace"}, hex8_4_4_4_12()), + SecretGroup: 1, + Keywords: []string{ + "squarespace", + }, + } + + // validate + tps := []string{ + generateSampleSecret("squarespace", secrets.NewSecret(hex8_4_4_4_12())), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/stopwords.go b/cmd/generate/config/rules/stopwords.go new file mode 100644 index 000000000..8aa07d551 --- /dev/null +++ b/cmd/generate/config/rules/stopwords.go @@ -0,0 +1,1489 @@ +package rules + +// TODO introduce skiplists: +// https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/wordlist-skipfish.fuzz.txt +// https://github.com/e3b0c442/keywords +// https://gist.github.com/maxtruxa/b2ca551e42d3aead2b3d +// https://github.com/HChakraborty/projects/commit/e860cb863ee9585c38db8360814b04ef9fa1bdce +// https://github.com/UraniumX92/Discord-Bot-using-py/tree/224b2b71a58c25f420ce980f2ea49627b4b646f1/Data%20Files +// https://github.com/Meen11/BSBI-Indexing/blob/63032017aa24f3111f18468607cd0db5997bb891/datasets/citeseer/11/10.1.1.27.6385.txt + +var DefaultStopWords = []string{ + "client", + "endpoint", + "vpn", + "_ec2_", + "aws_", + "authorize", + "author", + "define", + "config", + "credential", + "setting", + "sample", + "xxxxxx", + "000000", + "buffer", + "delete", + "aaaaaa", + "fewfwef", + "getenv", + "env_", + "system", + "example", + "ecdsa", + "sha256", + "sha1", + "sha2", + "md5", + "alert", + "wizard", + "target", + "onboard", + "welcome", + "page", + "exploit", + "experiment", + "expire", + "rabbitmq", + "scraper", + "widget", + "music", + "dns_", + "dns-", + "yahoo", + "want", + "json", + "action", + "script", + "fix_", + "fix-", + "develop", + "compas", + "stripe", + "service", + "master", + "metric", + "tech", + "gitignore", + "rich", + "open", + "stack", + "irc_", + "irc-", + "sublime", + "kohana", + "has_", + "has-", + "fabric", + "wordpres", + "role", + "osx_", + "osx-", + "boost", + "addres", + "queue", + "working", + "sandbox", + "internet", + "print", + "vision", + "tracking", + "being", + "generator", + "traffic", + "world", + "pull", + "rust", + "watcher", + "small", + "auth", + "full", + "hash", + "more", + "install", + "auto", + "complete", + "learn", + "paper", + "installer", + "research", + "acces", + "last", + "binding", + "spine", + "into", + "chat", + "algorithm", + "resource", + "uploader", + "video", + "maker", + "next", + "proc", + "lock", + "robot", + "snake", + "patch", + "matrix", + "drill", + "terminal", + "term", + "stuff", + "genetic", + "generic", + "identity", + "audit", + "pattern", + "audio", + "web_", + "web-", + "crud", + "problem", + "statu", + "cms-", + "cms_", + "arch", + "coffee", + "workflow", + "changelog", + "another", + "uiview", + "content", + "kitchen", + "gnu_", + "gnu-", + "gnu.", + "conf", + "couchdb", + "client", + "opencv", + "rendering", + "update", + "concept", + "varnish", + "gui_", + "gui-", + "gui.", + "version", + "shared", + "extra", + "product", + "still", + "not_", + "not-", + "not.", + "drop", + "ring", + "png_", + "png-", + "png.", + "actively", + "import", + "output", + "backup", + "start", + "embedded", + "registry", + "pool", + "semantic", + "instagram", + "bash", + "system", + "ninja", + "drupal", + "jquery", + "polyfill", + "physic", + "league", + "guide", + "pack", + "synopsi", + "sketch", + "injection", + "svg_", + "svg-", + "svg.", + "friendly", + "wave", + "convert", + "manage", + "camera", + "link", + "slide", + "timer", + "wrapper", + "gallery", + "url_", + "url-", + "url.", + "todomvc", + "requirej", + "party", + "http", + "payment", + "async", + "library", + "home", + "coco", + "gaia", + "display", + "universal", + "func", + "metadata", + "hipchat", + "under", + "room", + "config", + "personal", + "realtime", + "resume", + "database", + "testing", + "tiny", + "basic", + "forum", + "meetup", + "yet_", + "yet-", + "yet.", + "cento", + "dead", + "fluentd", + "editor", + "utilitie", + "run_", + "run-", + "run.", + "box_", + "box-", + "box.", + "bot_", + "bot-", + "bot.", + "making", + "sample", + "group", + "monitor", + "ajax", + "parallel", + "cassandra", + "ultimate", + "site", + "get_", + "get-", + "get.", + "gen_", + "gen-", + "gen.", + "gem_", + "gem-", + "gem.", + "extended", + "image", + "knife", + "asset", + "nested", + "zero", + "plugin", + "bracket", + "mule", + "mozilla", + "number", + "act_", + "act-", + "act.", + "map_", + "map-", + "map.", + "micro", + "debug", + "openshift", + "chart", + "expres", + "backend", + "task", + "source", + "translate", + "jbos", + "composer", + "sqlite", + "profile", + "mustache", + "mqtt", + "yeoman", + "have", + "builder", + "smart", + "like", + "oauth", + "school", + "guideline", + "captcha", + "filter", + "bitcoin", + "bridge", + "color", + "toolbox", + "discovery", + "new_", + "new-", + "new.", + "dashboard", + "when", + "setting", + "level", + "post", + "standard", + "port", + "platform", + "yui_", + "yui-", + "yui.", + "grunt", + "animation", + "haskell", + "icon", + "latex", + "cheat", + "lua_", + "lua-", + "lua.", + "gulp", + "case", + "author", + "without", + "simulator", + "wifi", + "directory", + "lisp", + "list", + "flat", + "adventure", + "story", + "storm", + "gpu_", + "gpu-", + "gpu.", + "store", + "caching", + "attention", + "solr", + "logger", + "demo", + "shortener", + "hadoop", + "finder", + "phone", + "pipeline", + "range", + "textmate", + "showcase", + "app_", + "app-", + "app.", + "idiomatic", + "edit", + "our_", + "our-", + "our.", + "out_", + "out-", + "out.", + "sentiment", + "linked", + "why_", + "why-", + "why.", + "local", + "cube", + "gmail", + "job_", + "job-", + "job.", + "rpc_", + "rpc-", + "rpc.", + "contest", + "tcp_", + "tcp-", + "tcp.", + "usage", + "buildout", + "weather", + "transfer", + "automated", + "sphinx", + "issue", + "sas_", + "sas-", + "sas.", + "parallax", + "jasmine", + "addon", + "machine", + "solution", + "dsl_", + "dsl-", + "dsl.", + "episode", + "menu", + "theme", + "best", + "adapter", + "debugger", + "chrome", + "tutorial", + "life", + "step", + "people", + "joomla", + "paypal", + "developer", + "solver", + "team", + "current", + "love", + "visual", + "date", + "data", + "canva", + "container", + "future", + "xml_", + "xml-", + "xml.", + "twig", + "nagio", + "spatial", + "original", + "sync", + "archived", + "refinery", + "science", + "mapping", + "gitlab", + "play", + "ext_", + "ext-", + "ext.", + "session", + "impact", + "set_", + "set-", + "set.", + "see_", + "see-", + "see.", + "migration", + "commit", + "community", + "shopify", + "what'", + "cucumber", + "statamic", + "mysql", + "location", + "tower", + "line", + "code", + "amqp", + "hello", + "send", + "index", + "high", + "notebook", + "alloy", + "python", + "field", + "document", + "soap", + "edition", + "email", + "php_", + "php-", + "php.", + "command", + "transport", + "official", + "upload", + "study", + "secure", + "angularj", + "akka", + "scalable", + "package", + "request", + "con_", + "con-", + "con.", + "flexible", + "security", + "comment", + "module", + "flask", + "graph", + "flash", + "apache", + "change", + "window", + "space", + "lambda", + "sheet", + "bookmark", + "carousel", + "friend", + "objective", + "jekyll", + "bootstrap", + "first", + "article", + "gwt_", + "gwt-", + "gwt.", + "classic", + "media", + "websocket", + "touch", + "desktop", + "real", + "read", + "recorder", + "moved", + "storage", + "validator", + "add-on", + "pusher", + "scs_", + "scs-", + "scs.", + "inline", + "asp_", + "asp-", + "asp.", + "timeline", + "base", + "encoding", + "ffmpeg", + "kindle", + "tinymce", + "pretty", + "jpa_", + "jpa-", + "jpa.", + "used", + "user", + "required", + "webhook", + "download", + "resque", + "espresso", + "cloud", + "mongo", + "benchmark", + "pure", + "cakephp", + "modx", + "mode", + "reactive", + "fuel", + "written", + "flickr", + "mail", + "brunch", + "meteor", + "dynamic", + "neo_", + "neo-", + "neo.", + "new_", + "new-", + "new.", + "net_", + "net-", + "net.", + "typo", + "type", + "keyboard", + "erlang", + "adobe", + "logging", + "ckeditor", + "message", + "iso_", + "iso-", + "iso.", + "hook", + "ldap", + "folder", + "reference", + "railscast", + "www_", + "www-", + "www.", + "tracker", + "azure", + "fork", + "form", + "digital", + "exporter", + "skin", + "string", + "template", + "designer", + "gollum", + "fluent", + "entity", + "language", + "alfred", + "summary", + "wiki", + "kernel", + "calendar", + "plupload", + "symfony", + "foundry", + "remote", + "talk", + "search", + "dev_", + "dev-", + "dev.", + "del_", + "del-", + "del.", + "token", + "idea", + "sencha", + "selector", + "interface", + "create", + "fun_", + "fun-", + "fun.", + "groovy", + "query", + "grail", + "red_", + "red-", + "red.", + "laravel", + "monkey", + "slack", + "supported", + "instant", + "value", + "center", + "latest", + "work", + "but_", + "but-", + "but.", + "bug_", + "bug-", + "bug.", + "virtual", + "tweet", + "statsd", + "studio", + "path", + "real-time", + "frontend", + "notifier", + "coding", + "tool", + "firmware", + "flow", + "random", + "mediawiki", + "bosh", + "been", + "beer", + "lightbox", + "theory", + "origin", + "redmine", + "hub_", + "hub-", + "hub.", + "require", + "pro_", + "pro-", + "pro.", + "ant_", + "ant-", + "ant.", + "any_", + "any-", + "any.", + "recipe", + "closure", + "mapper", + "event", + "todo", + "model", + "redi", + "provider", + "rvm_", + "rvm-", + "rvm.", + "program", + "memcached", + "rail", + "silex", + "foreman", + "activity", + "license", + "strategy", + "batch", + "streaming", + "fast", + "use_", + "use-", + "use.", + "usb_", + "usb-", + "usb.", + "impres", + "academy", + "slider", + "please", + "layer", + "cros", + "now_", + "now-", + "now.", + "miner", + "extension", + "own_", + "own-", + "own.", + "app_", + "app-", + "app.", + "debian", + "symphony", + "example", + "feature", + "serie", + "tree", + "project", + "runner", + "entry", + "leetcode", + "layout", + "webrtc", + "logic", + "login", + "worker", + "toolkit", + "mocha", + "support", + "back", + "inside", + "device", + "jenkin", + "contact", + "fake", + "awesome", + "ocaml", + "bit_", + "bit-", + "bit.", + "drive", + "screen", + "prototype", + "gist", + "binary", + "nosql", + "rest", + "overview", + "dart", + "dark", + "emac", + "mongoid", + "solarized", + "homepage", + "emulator", + "commander", + "django", + "yandex", + "gradle", + "xcode", + "writer", + "crm_", + "crm-", + "crm.", + "jade", + "startup", + "error", + "using", + "format", + "name", + "spring", + "parser", + "scratch", + "magic", + "try_", + "try-", + "try.", + "rack", + "directive", + "challenge", + "slim", + "counter", + "element", + "chosen", + "doc_", + "doc-", + "doc.", + "meta", + "should", + "button", + "packet", + "stream", + "hardware", + "android", + "infinite", + "password", + "software", + "ghost", + "xamarin", + "spec", + "chef", + "interview", + "hubot", + "mvc_", + "mvc-", + "mvc.", + "exercise", + "leaflet", + "launcher", + "air_", + "air-", + "air.", + "photo", + "board", + "boxen", + "way_", + "way-", + "way.", + "computing", + "welcome", + "notepad", + "portfolio", + "cat_", + "cat-", + "cat.", + "can_", + "can-", + "can.", + "magento", + "yaml", + "domain", + "card", + "yii_", + "yii-", + "yii.", + "checker", + "browser", + "upgrade", + "only", + "progres", + "aura", + "ruby_", + "ruby-", + "ruby.", + "polymer", + "util", + "lite", + "hackathon", + "rule", + "log_", + "log-", + "log.", + "opengl", + "stanford", + "skeleton", + "history", + "inspector", + "help", + "soon", + "selenium", + "lab_", + "lab-", + "lab.", + "scheme", + "schema", + "look", + "ready", + "leveldb", + "docker", + "game", + "minimal", + "logstash", + "messaging", + "within", + "heroku", + "mongodb", + "kata", + "suite", + "picker", + "win_", + "win-", + "win.", + "wip_", + "wip-", + "wip.", + "panel", + "started", + "starter", + "front-end", + "detector", + "deploy", + "editing", + "based", + "admin", + "capture", + "spree", + "page", + "bundle", + "goal", + "rpg_", + "rpg-", + "rpg.", + "setup", + "side", + "mean", + "reader", + "cookbook", + "mini", + "modern", + "seed", + "dom_", + "dom-", + "dom.", + "doc_", + "doc-", + "doc.", + "dot_", + "dot-", + "dot.", + "syntax", + "sugar", + "loader", + "website", + "make", + "kit_", + "kit-", + "kit.", + "protocol", + "human", + "daemon", + "golang", + "manager", + "countdown", + "connector", + "swagger", + "map_", + "map-", + "map.", + "mac_", + "mac-", + "mac.", + "man_", + "man-", + "man.", + "orm_", + "orm-", + "orm.", + "org_", + "org-", + "org.", + "little", + "zsh_", + "zsh-", + "zsh.", + "shop", + "show", + "workshop", + "money", + "grid", + "server", + "octopres", + "svn_", + "svn-", + "svn.", + "ember", + "embed", + "general", + "file", + "important", + "dropbox", + "portable", + "public", + "docpad", + "fish", + "sbt_", + "sbt-", + "sbt.", + "done", + "para", + "network", + "common", + "readme", + "popup", + "simple", + "purpose", + "mirror", + "single", + "cordova", + "exchange", + "object", + "design", + "gateway", + "account", + "lamp", + "intellij", + "math", + "mit_", + "mit-", + "mit.", + "control", + "enhanced", + "emitter", + "multi", + "add_", + "add-", + "add.", + "about", + "socket", + "preview", + "vagrant", + "cli_", + "cli-", + "cli.", + "powerful", + "top_", + "top-", + "top.", + "radio", + "watch", + "fluid", + "amazon", + "report", + "couchbase", + "automatic", + "detection", + "sprite", + "pyramid", + "portal", + "advanced", + "plu_", + "plu-", + "plu.", + "runtime", + "git_", + "git-", + "git.", + "uri_", + "uri-", + "uri.", + "haml", + "node", + "sql_", + "sql-", + "sql.", + "cool", + "core", + "obsolete", + "handler", + "iphone", + "extractor", + "array", + "copy", + "nlp_", + "nlp-", + "nlp.", + "reveal", + "pop_", + "pop-", + "pop.", + "engine", + "parse", + "check", + "html", + "nest", + "all_", + "all-", + "all.", + "chinese", + "buildpack", + "what", + "tag_", + "tag-", + "tag.", + "proxy", + "style", + "cookie", + "feed", + "restful", + "compiler", + "creating", + "prelude", + "context", + "java", + "rspec", + "mock", + "backbone", + "light", + "spotify", + "flex", + "related", + "shell", + "which", + "clas", + "webapp", + "swift", + "ansible", + "unity", + "console", + "tumblr", + "export", + "campfire", + "conway'", + "made", + "riak", + "hero", + "here", + "unix", + "unit", + "glas", + "smtp", + "how_", + "how-", + "how.", + "hot_", + "hot-", + "hot.", + "debug", + "release", + "diff", + "player", + "easy", + "right", + "old_", + "old-", + "old.", + "animate", + "time", + "push", + "explorer", + "course", + "training", + "nette", + "router", + "draft", + "structure", + "note", + "salt", + "where", + "spark", + "trello", + "power", + "method", + "social", + "via_", + "via-", + "via.", + "vim_", + "vim-", + "vim.", + "select", + "webkit", + "github", + "ftp_", + "ftp-", + "ftp.", + "creator", + "mongoose", + "led_", + "led-", + "led.", + "movie", + "currently", + "pdf_", + "pdf-", + "pdf.", + "load", + "markdown", + "phalcon", + "input", + "custom", + "atom", + "oracle", + "phonegap", + "ubuntu", + "great", + "rdf_", + "rdf-", + "rdf.", + "popcorn", + "firefox", + "zip_", + "zip-", + "zip.", + "cuda", + "dotfile", + "static", + "openwrt", + "viewer", + "powered", + "graphic", + "les_", + "les-", + "les.", + "doe_", + "doe-", + "doe.", + "maven", + "word", + "eclipse", + "lab_", + "lab-", + "lab.", + "hacking", + "steam", + "analytic", + "option", + "abstract", + "archive", + "reality", + "switcher", + "club", + "write", + "kafka", + "arduino", + "angular", + "online", + "title", + "don't", + "contao", + "notice", + "analyzer", + "learning", + "zend", + "external", + "staging", + "busines", + "tdd_", + "tdd-", + "tdd.", + "scanner", + "building", + "snippet", + "modular", + "bower", + "stm_", + "stm-", + "stm.", + "lib_", + "lib-", + "lib.", + "alpha", + "mobile", + "clean", + "linux", + "nginx", + "manifest", + "some", + "raspberry", + "gnome", + "ide_", + "ide-", + "ide.", + "block", + "statistic", + "info", + "drag", + "youtube", + "koan", + "facebook", + "paperclip", + "art_", + "art-", + "art.", + "quality", + "tab_", + "tab-", + "tab.", + "need", + "dojo", + "shield", + "computer", + "stat", + "state", + "twitter", + "utility", + "converter", + "hosting", + "devise", + "liferay", + "updated", + "force", + "tip_", + "tip-", + "tip.", + "behavior", + "active", + "call", + "answer", + "deck", + "better", + "principle", + "ches", + "bar_", + "bar-", + "bar.", + "reddit", + "three", + "haxe", + "just", + "plug-in", + "agile", + "manual", + "tetri", + "super", + "beta", + "parsing", + "doctrine", + "minecraft", + "useful", + "perl", + "sharing", + "agent", + "switch", + "view", + "dash", + "channel", + "repo", + "pebble", + "profiler", + "warning", + "cluster", + "running", + "markup", + "evented", + "mod_", + "mod-", + "mod.", + // "api_", lin_api_ is used for linear + // "api-", + // "api.", + "share", + "csv_", + "csv-", + "csv.", + "response", + "good", + "house", + "connect", + "built", + "build", + "find", + "ipython", + "webgl", + "big_", + "big-", + "big.", + "google", + "scala", + "sdl_", + "sdl-", + "sdl.", + "sdk_", + "sdk-", + "sdk.", + "native", + "day_", + "day-", + "day.", + "puppet", + "text", + "routing", + "helper", + "linkedin", + "crawler", + "host", + "guard", + "merchant", + "poker", + "over", + "writing", + "free", + "classe", + "component", + "craft", + "nodej", + "phoenix", + "longer", + "quick", + "lazy", + "memory", + "clone", + "hacker", + "middleman", + "factory", + "motion", + "multiple", + "tornado", + "hack", + "ssh_", + "ssh-", + "ssh.", + "review", + "vimrc", + "driver", + "driven", + "blog", + "particle", + "table", + "intro", + "importer", + "thrift", + "xmpp", + "framework", + "refresh", + "react", + "font", + "librarie", + "variou", + "formatter", + "analysi", + "karma", + "scroll", + "tut_", + "tut-", + "tut.", + "apple", + "tag_", + "tag-", + "tag.", + "tab_", + "tab-", + "tab.", + "category", + "ionic", + "cache", + "homebrew", + "reverse", + "english", + "getting", + "shipping", + "clojure", + "boot", + "book", + "branch", + "combination", + "combo", +} diff --git a/cmd/generate/config/rules/stripe.go b/cmd/generate/config/rules/stripe.go new file mode 100644 index 000000000..e4e8b7c9e --- /dev/null +++ b/cmd/generate/config/rules/stripe.go @@ -0,0 +1,27 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func StripeAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Stripe", + RuleID: "stripe-access-token", + Regex: regexp.MustCompile(`(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}`), + Keywords: []string{ + "sk_test", + "pk_test", + "sk_live", + "pk_live", + }, + } + + // validate + tps := []string{"stripeToken := \"sk_test_" + secrets.NewSecret(alphaNumeric("30")) + "\""} + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/sumologic.go b/cmd/generate/config/rules/sumologic.go new file mode 100644 index 000000000..c9f5d9b86 --- /dev/null +++ b/cmd/generate/config/rules/sumologic.go @@ -0,0 +1,46 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func SumoLogicAccessID() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sumologic-access-id", + Description: "SumoLogic Access ID", + Regex: generateSemiGenericRegex([]string{"sumo"}, + alphaNumeric("14")), + SecretGroup: 1, + Keywords: []string{ + "sumo", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sumo", secrets.NewSecret(alphaNumeric("14"))), + } + return validate(r, tps, nil) +} + +func SumoLogicAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "sumologic-access-token", + Description: "SumoLogic Access Token", + Regex: generateSemiGenericRegex([]string{"sumo"}, + alphaNumeric("64")), + SecretGroup: 1, + Keywords: []string{ + "sumo", + }, + } + + // validate + tps := []string{ + generateSampleSecret("sumo", secrets.NewSecret(alphaNumeric("64"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/teams.go b/cmd/generate/config/rules/teams.go new file mode 100644 index 000000000..2904c9cc1 --- /dev/null +++ b/cmd/generate/config/rules/teams.go @@ -0,0 +1,29 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TeamsWebhook() *config.Rule { + // define rule + r := config.Rule{ + Description: "Microsoft Teams Webhook", + RuleID: "microsoft-teams-webhook", + Regex: regexp.MustCompile( + `https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}`), + Keywords: []string{ + "webhook.office.com", + "webhookb2", + "IncomingWebhook", + }, + } + + // validate + tps := []string{ + "https://mycompany.webhook.office.com/webhookb2/" + secrets.NewSecret(`[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}`), // gitleaks:allow + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/telegram.go b/cmd/generate/config/rules/telegram.go new file mode 100644 index 000000000..e17027fb7 --- /dev/null +++ b/cmd/generate/config/rules/telegram.go @@ -0,0 +1,57 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TelegramBotToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Telegram Bot API Token", + RuleID: "telegram-bot-api-token", + SecretGroup: 1, + Regex: regexp.MustCompile(`(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])`), + Keywords: []string{ + "telegram", + "api", + "bot", + "token", + "url", + }, + } + + // validate + validToken := secrets.NewSecret(numeric("8") + ":A" + alphaNumericExtendedShort("34")) + minToken := secrets.NewSecret(numeric("5") + ":A" + alphaNumericExtendedShort("34")) + maxToken := secrets.NewSecret(numeric("16") + ":A" + alphaNumericExtendedShort("34")) + tps := []string{ + // variable assigment + generateSampleSecret("telegram", validToken), + // URL contaning token + generateSampleSecret("url", "https://api.telegram.org/bot"+validToken+"/sendMessage"), + // object constructor + `const bot = new Telegraf("` + validToken + `")`, + // .env + `API_TOKEN = ` + validToken, + // YAML + `bot: ` + validToken, + // Token with min bot_id + generateSampleSecret("telegram", minToken), + // Token with max bot_id + generateSampleSecret("telegram", maxToken), + } + + tooSmallToken := secrets.NewSecret(numeric("4") + ":A" + alphaNumericExtendedShort("34")) + tooBigToken := secrets.NewSecret(numeric("17") + ":A" + alphaNumericExtendedShort("34")) + fps := []string{ + // Token with too small bot_id + generateSampleSecret("telegram", tooSmallToken), + // Token with too big bot_id + generateSampleSecret("telegram", tooBigToken), + } + + return validate(r, tps, fps) +} diff --git a/cmd/generate/config/rules/travisci.go b/cmd/generate/config/rules/travisci.go new file mode 100644 index 000000000..458b12a7c --- /dev/null +++ b/cmd/generate/config/rules/travisci.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TravisCIAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "travisci-access-token", + Description: "Travis CI Access Token", + Regex: generateSemiGenericRegex([]string{"travis"}, alphaNumeric("22")), + SecretGroup: 1, + Keywords: []string{ + "travis", + }, + } + + // validate + tps := []string{ + generateSampleSecret("travis", secrets.NewSecret(alphaNumeric("22"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/trello.go b/cmd/generate/config/rules/trello.go new file mode 100644 index 000000000..6d713c065 --- /dev/null +++ b/cmd/generate/config/rules/trello.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TrelloAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "trello-access-token", + Description: "Trello Access Token", + Regex: generateSemiGenericRegex([]string{"trello"}, `[a-zA-Z-0-9]{32}`), + SecretGroup: 1, + Keywords: []string{ + "trello", + }, + } + + // validate + tps := []string{ + generateSampleSecret("trello", secrets.NewSecret(`[a-zA-Z-0-9]{32}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twilio.go b/cmd/generate/config/rules/twilio.go new file mode 100644 index 000000000..f2c3b6f9c --- /dev/null +++ b/cmd/generate/config/rules/twilio.go @@ -0,0 +1,24 @@ +package rules + +import ( + "regexp" + + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Twilio() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twilio API Key", + RuleID: "twilio-api-key", + Regex: regexp.MustCompile(`SK[0-9a-fA-F]{32}`), + Keywords: []string{"twilio"}, + } + + // validate + tps := []string{ + "twilioAPIKey := \"SK" + secrets.NewSecret(hex("32")) + "\"", + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twitch.go b/cmd/generate/config/rules/twitch.go new file mode 100644 index 000000000..d41d8a569 --- /dev/null +++ b/cmd/generate/config/rules/twitch.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TwitchAPIToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "twitch-api-token", + Description: "Twitch API token", + Regex: generateSemiGenericRegex([]string{"twitch"}, alphaNumeric("30")), + SecretGroup: 1, + Keywords: []string{ + "twitch", + }, + } + + // validate + tps := []string{ + generateSampleSecret("twitch", secrets.NewSecret(alphaNumeric("30"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/twitter.go b/cmd/generate/config/rules/twitter.go new file mode 100644 index 000000000..bf13e000c --- /dev/null +++ b/cmd/generate/config/rules/twitter.go @@ -0,0 +1,91 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func TwitterAPIKey() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter API Key", + RuleID: "twitter-api-key", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("25")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("25"))), + } + return validate(r, tps, nil) +} + +func TwitterAPISecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter API Secret", + RuleID: "twitter-api-secret", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("50")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("50"))), + } + return validate(r, tps, nil) +} + +func TwitterBearerToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Bearer Token", + RuleID: "twitter-bearer-token", + Regex: generateSemiGenericRegex([]string{"twitter"}, "A{22}[a-zA-Z0-9%]{80,100}"), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret("A{22}[a-zA-Z0-9%]{80,100}")), + } + return validate(r, tps, nil) +} + +func TwitterAccessToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Access Token", + RuleID: "twitter-access-token", + Regex: generateSemiGenericRegex([]string{"twitter"}, "[0-9]{15,25}-[a-zA-Z0-9]{20,40}"), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret("[0-9]{15,25}-[a-zA-Z0-9]{20,40}")), + } + return validate(r, tps, nil) +} + +func TwitterAccessSecret() *config.Rule { + // define rule + r := config.Rule{ + Description: "Twitter Access Secret", + RuleID: "twitter-access-secret", + Regex: generateSemiGenericRegex([]string{"twitter"}, alphaNumeric("45")), + SecretGroup: 1, + Keywords: []string{"twitter"}, + } + + // validate + tps := []string{ + generateSampleSecret("twitter", secrets.NewSecret(alphaNumeric("45"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/typeform.go b/cmd/generate/config/rules/typeform.go new file mode 100644 index 000000000..3d5214873 --- /dev/null +++ b/cmd/generate/config/rules/typeform.go @@ -0,0 +1,26 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func Typeform() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "typeform-api-token", + Description: "Typeform API token", + Regex: generateSemiGenericRegex([]string{"typeform"}, + `tfp_[a-z0-9\-_\.=]{59}`), + SecretGroup: 1, + Keywords: []string{ + "tfp_", + }, + } + + // validate + tps := []string{ + generateSampleSecret("typeformAPIToken", "tfp_"+secrets.NewSecret(alphaNumericExtended("59"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/vault.go b/cmd/generate/config/rules/vault.go new file mode 100644 index 000000000..4645f5608 --- /dev/null +++ b/cmd/generate/config/rules/vault.go @@ -0,0 +1,38 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func VaultServiceToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Vault Service Token", + RuleID: "vault-service-token", + Regex: generateUniqueTokenRegex(`hvs\.[a-z0-9_-]{90,100}`), + Keywords: []string{"hvs"}, + } + + // validate + tps := []string{ + generateSampleSecret("vault", "hvs."+secrets.NewSecret(alphaNumericExtendedShort("90"))), + } + return validate(r, tps, nil) +} + +func VaultBatchToken() *config.Rule { + // define rule + r := config.Rule{ + Description: "Vault Batch Token", + RuleID: "vault-batch-token", + Regex: generateUniqueTokenRegex(`hvb\.[a-z0-9_-]{138,212}`), + Keywords: []string{"hvb"}, + } + + // validate + tps := []string{ + generateSampleSecret("vault", "hvb."+secrets.NewSecret(alphaNumericExtendedShort("138"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/yandex.go b/cmd/generate/config/rules/yandex.go new file mode 100644 index 000000000..f1fcce11a --- /dev/null +++ b/cmd/generate/config/rules/yandex.go @@ -0,0 +1,69 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func YandexAWSAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-aws-access-token", + Description: "Yandex AWS Access Token", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `YC[a-zA-Z0-9_\-]{38}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`YC[a-zA-Z0-9_\-]{38}`)), + } + return validate(r, tps, nil) +} + +func YandexAPIKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-api-key", + Description: "Yandex API Key", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `AQVN[A-Za-z0-9_\-]{35,38}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`AQVN[A-Za-z0-9_\-]{35,38}`)), + } + return validate(r, tps, nil) +} + +func YandexAccessToken() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "yandex-access-token", + Description: "Yandex Access Token", + Regex: generateSemiGenericRegex([]string{"yandex"}, + `t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}`), + SecretGroup: 1, + Keywords: []string{ + "yandex", + }, + } + + // validate + tps := []string{ + generateSampleSecret("yandex", + secrets.NewSecret(`t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}`)), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/config/rules/zendesk.go b/cmd/generate/config/rules/zendesk.go new file mode 100644 index 000000000..ec263c322 --- /dev/null +++ b/cmd/generate/config/rules/zendesk.go @@ -0,0 +1,25 @@ +package rules + +import ( + "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" + "github.com/zricethezav/gitleaks/v8/config" +) + +func ZendeskSecretKey() *config.Rule { + // define rule + r := config.Rule{ + RuleID: "zendesk-secret-key", + Description: "Zendesk Secret Key", + Regex: generateSemiGenericRegex([]string{"zendesk"}, alphaNumeric("40")), + SecretGroup: 1, + Keywords: []string{ + "zendesk", + }, + } + + // validate + tps := []string{ + generateSampleSecret("zendesk", secrets.NewSecret(alphaNumeric("40"))), + } + return validate(r, tps, nil) +} diff --git a/cmd/generate/secrets/regen.go b/cmd/generate/secrets/regen.go new file mode 100644 index 000000000..ee7496eaa --- /dev/null +++ b/cmd/generate/secrets/regen.go @@ -0,0 +1,15 @@ +// Package reggen generates text based on regex definitions +// This is a slightly altered version of https://github.com/lucasjones/reggen +package secrets + +import ( + "github.com/lucasjones/reggen" +) + +func NewSecret(regex string) string { + g, err := reggen.NewGenerator(regex) + if err != nil { + panic(err) + } + return g.Generate(1) +} diff --git a/cmd/protect.go b/cmd/protect.go new file mode 100644 index 000000000..434d6843e --- /dev/null +++ b/cmd/protect.go @@ -0,0 +1,105 @@ +package cmd + +import ( + "os" + "path/filepath" + "time" + + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect" + "github.com/zricethezav/gitleaks/v8/report" +) + +func init() { + protectCmd.Flags().Bool("staged", false, "detect secrets in a --staged state") + rootCmd.AddCommand(protectCmd) +} + +var protectCmd = &cobra.Command{ + Use: "protect", + Short: "protect secrets in code", + Run: runProtect, +} + +func runProtect(cmd *cobra.Command, args []string) { + initConfig() + var vc config.ViperConfig + + if err := viper.Unmarshal(&vc); err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + cfg, err := vc.Translate() + if err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + + cfg.Path, _ = cmd.Flags().GetString("config") + exitCode, _ := cmd.Flags().GetInt("exit-code") + staged, _ := cmd.Flags().GetBool("staged") + start := time.Now() + + // Setup detector + detector := detect.NewDetector(cfg) + detector.Config.Path, err = cmd.Flags().GetString("config") + if err != nil { + log.Fatal().Err(err).Msg("") + } + source, err := cmd.Flags().GetString("source") + if err != nil { + log.Fatal().Err(err).Msg("") + } + // if config path is not set, then use the {source}/.gitleaks.toml path. + // note that there may not be a `{source}/.gitleaks.toml` file, this is ok. + if detector.Config.Path == "" { + detector.Config.Path = filepath.Join(source, ".gitleaks.toml") + } + // set verbose flag + if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil { + log.Fatal().Err(err).Msg("") + } + // set redact flag + if detector.Redact, err = cmd.Flags().GetBool("redact"); err != nil { + log.Fatal().Err(err).Msg("") + } + + // get log options for git scan + logOpts, err := cmd.Flags().GetString("log-opts") + if err != nil { + log.Fatal().Err(err).Msg("") + } + + // start git scan + var findings []report.Finding + if staged { + findings, err = detector.DetectGit(source, logOpts, detect.ProtectStagedType) + } else { + findings, err = detector.DetectGit(source, logOpts, detect.ProtectType) + } + if err != nil { + // don't exit on error, just log it + log.Error().Err(err).Msg("") + } + + // log info about the scan + log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start))) + if len(findings) != 0 { + log.Warn().Msgf("leaks found: %d", len(findings)) + } else { + log.Info().Msg("no leaks found") + } + + reportPath, _ := cmd.Flags().GetString("report-path") + ext, _ := cmd.Flags().GetString("report-format") + if reportPath != "" { + if err = report.Write(findings, cfg, ext, reportPath); err != nil { + log.Fatal().Err(err).Msg("") + } + } + if len(findings) != 0 { + os.Exit(exitCode) + } +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 000000000..fcb29f26a --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,147 @@ +package cmd + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const banner = ` + ○ + │╲ + │ ○ + ○ ░ + ░ gitleaks + +` + +const configDescription = `config file path +order of precedence: +1. --config/-c +2. env var GITLEAKS_CONFIG +3. (--source/-s)/.gitleaks.toml +If none of the three options are used, then gitleaks will use the default config` + +var rootCmd = &cobra.Command{ + Use: "gitleaks", + Short: "Gitleaks scans code, past or present, for secrets", +} + +func init() { + cobra.OnInitialize(initLog) + rootCmd.PersistentFlags().StringP("config", "c", "", configDescription) + rootCmd.PersistentFlags().Int("exit-code", 1, "exit code when leaks have been encountered") + rootCmd.PersistentFlags().StringP("source", "s", ".", "path to source (default: $PWD)") + rootCmd.PersistentFlags().StringP("report-path", "r", "", "report file") + rootCmd.PersistentFlags().StringP("report-format", "f", "json", "output format (json, csv, sarif)") + rootCmd.PersistentFlags().StringP("baseline-path", "b", "", "path to baseline with issues that can be ignored") + rootCmd.PersistentFlags().StringP("log-level", "l", "info", "log level (trace, debug, info, warn, error, fatal)") + rootCmd.PersistentFlags().BoolP("verbose", "v", false, "show verbose output from scan") + rootCmd.PersistentFlags().Bool("redact", false, "redact secrets from logs and stdout") + rootCmd.PersistentFlags().Bool("no-banner", false, "suppress banner") + err := viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config")) + if err != nil { + log.Fatal().Msgf("err binding config %s", err.Error()) + } +} + +func initLog() { + zerolog.SetGlobalLevel(zerolog.InfoLevel) + ll, err := rootCmd.Flags().GetString("log-level") + if err != nil { + log.Fatal().Msg(err.Error()) + } + switch strings.ToLower(ll) { + case "trace": + zerolog.SetGlobalLevel(zerolog.TraceLevel) + case "debug": + zerolog.SetGlobalLevel(zerolog.DebugLevel) + case "info": + zerolog.SetGlobalLevel(zerolog.InfoLevel) + case "warn": + zerolog.SetGlobalLevel(zerolog.WarnLevel) + case "err", "error": + zerolog.SetGlobalLevel(zerolog.ErrorLevel) + case "fatal": + zerolog.SetGlobalLevel(zerolog.FatalLevel) + default: + zerolog.SetGlobalLevel(zerolog.InfoLevel) + } +} + +func initConfig() { + hideBanner, err := rootCmd.Flags().GetBool("no-banner") + if err != nil { + log.Fatal().Msg(err.Error()) + } + if !hideBanner { + _, _ = fmt.Fprint(os.Stderr, banner) + } + cfgPath, err := rootCmd.Flags().GetString("config") + if err != nil { + log.Fatal().Msg(err.Error()) + } + if cfgPath != "" { + viper.SetConfigFile(cfgPath) + log.Debug().Msgf("using gitleaks config %s from `--config`", cfgPath) + } else if os.Getenv("GITLEAKS_CONFIG") != "" { + envPath := os.Getenv("GITLEAKS_CONFIG") + viper.SetConfigFile(envPath) + log.Debug().Msgf("using gitleaks config from GITLEAKS_CONFIG env var: %s", envPath) + } else { + source, err := rootCmd.Flags().GetString("source") + if err != nil { + log.Fatal().Msg(err.Error()) + } + fileInfo, err := os.Stat(source) + if err != nil { + log.Fatal().Msg(err.Error()) + } + + if !fileInfo.IsDir() { + log.Debug().Msgf("unable to load gitleaks config from %s since --source=%s is a file, using default config", + filepath.Join(source, ".gitleaks.toml"), source) + viper.SetConfigType("toml") + if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil { + log.Fatal().Msgf("err reading toml %s", err.Error()) + } + return + } + + if _, err := os.Stat(filepath.Join(source, ".gitleaks.toml")); os.IsNotExist(err) { + log.Debug().Msgf("no gitleaks config found in path %s, using default gitleaks config", filepath.Join(source, ".gitleaks.toml")) + viper.SetConfigType("toml") + if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil { + log.Fatal().Msgf("err reading default config toml %s", err.Error()) + } + return + } else { + log.Debug().Msgf("using existing gitleaks config %s from `(--source)/.gitleaks.toml`", filepath.Join(source, ".gitleaks.toml")) + } + + viper.AddConfigPath(source) + viper.SetConfigName(".gitleaks") + viper.SetConfigType("toml") + } + if err := viper.ReadInConfig(); err != nil { + log.Fatal().Msgf("unable to load gitleaks config, err: %s", err) + } +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + if strings.Contains(err.Error(), "unknown flag") { + // exit code 126: Command invoked cannot execute + os.Exit(126) + } + log.Fatal().Msg(err.Error()) + } +} diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 000000000..9594a203f --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var Version = "version is set by build process" + +func init() { + rootCmd.AddCommand(versionCmd) +} + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "display gitleaks version", + Run: runVersion, +} + +func runVersion(cmd *cobra.Command, args []string) { + fmt.Println(Version) +} diff --git a/config/allowlist.go b/config/allowlist.go new file mode 100644 index 000000000..014286363 --- /dev/null +++ b/config/allowlist.go @@ -0,0 +1,60 @@ +package config + +import ( + "regexp" + "strings" +) + +// Allowlist allows a rule to be ignored for specific +// regexes, paths, and/or commits +type Allowlist struct { + // Short human readable description of the allowlist. + Description string + + // Regexes is slice of content regular expressions that are allowed to be ignored. + Regexes []*regexp.Regexp + + // Paths is a slice of path regular expressions that are allowed to be ignored. + Paths []*regexp.Regexp + + // Commits is a slice of commit SHAs that are allowed to be ignored. + Commits []string + + // StopWords is a slice of stop words that are allowed to be ignored. + // This targets the _secret_, not the content of the regex match like the + // Regexes slice. + StopWords []string +} + +// CommitAllowed returns true if the commit is allowed to be ignored. +func (a *Allowlist) CommitAllowed(c string) bool { + if c == "" { + return false + } + for _, commit := range a.Commits { + if commit == c { + return true + } + } + return false +} + +// PathAllowed returns true if the path is allowed to be ignored. +func (a *Allowlist) PathAllowed(path string) bool { + return anyRegexMatch(path, a.Paths) +} + +// RegexAllowed returns true if the regex is allowed to be ignored. +func (a *Allowlist) RegexAllowed(s string) bool { + return anyRegexMatch(s, a.Regexes) +} + +func (a *Allowlist) ContainsStopWord(s string) bool { + s = strings.ToLower(s) + for _, stopWord := range a.StopWords { + if strings.Contains(s, strings.ToLower(stopWord)) { + return true + } + } + return false +} diff --git a/config/allowlist_test.go b/config/allowlist_test.go new file mode 100644 index 000000000..be416ee3d --- /dev/null +++ b/config/allowlist_test.go @@ -0,0 +1,93 @@ +package config + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCommitAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + commit string + commitAllowed bool + }{ + { + allowlist: Allowlist{ + Commits: []string{"commitA"}, + }, + commit: "commitA", + commitAllowed: true, + }, + { + allowlist: Allowlist{ + Commits: []string{"commitB"}, + }, + commit: "commitA", + commitAllowed: false, + }, + { + allowlist: Allowlist{ + Commits: []string{"commitB"}, + }, + commit: "", + commitAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.commitAllowed, tt.allowlist.CommitAllowed(tt.commit)) + } +} + +func TestRegexAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + secret string + regexAllowed bool + }{ + { + allowlist: Allowlist{ + Regexes: []*regexp.Regexp{regexp.MustCompile("matchthis")}, + }, + secret: "a secret: matchthis, done", + regexAllowed: true, + }, + { + allowlist: Allowlist{ + Regexes: []*regexp.Regexp{regexp.MustCompile("matchthis")}, + }, + secret: "a secret", + regexAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.regexAllowed, tt.allowlist.RegexAllowed(tt.secret)) + } +} + +func TestPathAllowed(t *testing.T) { + tests := []struct { + allowlist Allowlist + path string + pathAllowed bool + }{ + { + allowlist: Allowlist{ + Paths: []*regexp.Regexp{regexp.MustCompile("path")}, + }, + path: "a path", + pathAllowed: true, + }, + { + allowlist: Allowlist{ + Paths: []*regexp.Regexp{regexp.MustCompile("path")}, + }, + path: "a ???", + pathAllowed: false, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.pathAllowed, tt.allowlist.PathAllowed(tt.path)) + } +} diff --git a/config/config.go b/config/config.go index b16918aec..acd887cef 100644 --- a/config/config.go +++ b/config/config.go @@ -1,249 +1,249 @@ package config import ( + _ "embed" "fmt" - "path" "regexp" - "strconv" + "strings" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/BurntSushi/toml" - log "github.com/sirupsen/logrus" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" ) -// AllowList is struct containing items that if encountered will allowlist -// a commit/line of code that would be considered a leak. -type AllowList struct { - Description string - Regexes []*regexp.Regexp - Commits []string - Files []*regexp.Regexp - Paths []*regexp.Regexp - Repos []*regexp.Regexp -} +//go:embed gitleaks.toml +var DefaultConfig string -// Entropy represents an entropy range -type Entropy struct { - Min float64 - Max float64 - Group int -} +// use to keep track of how many configs we can extend +// yea I know, globals bad +var extendDepth int -// Rule is a struct that contains information that is loaded from a gitleaks config. -// This struct is used in the Config struct as an array of Rules and is iterated -// over during an scan. Each rule will be checked. If a regex match is found AND -// that match is not allowlisted (globally or locally), then a leak will be appended -// to the final scan report. -type Rule struct { - Description string - Regex *regexp.Regexp - File *regexp.Regexp - Path *regexp.Regexp - Tags []string - AllowList AllowList - Entropies []Entropy -} +const maxExtendDepth = 2 -// Config is a composite struct of Rules and Allowlists -// Each Rule contains a description, regular expression, tags, and allowlists if available -type Config struct { - Rules []Rule - Allowlist AllowList -} - -// TomlAllowList is a struct used in the TomlLoader that loads in allowlists from -// specific rules or globally at the top level config -type TomlAllowList struct { +// ViperConfig is the config struct used by the Viper config package +// to parse the config file. This struct does not include regular expressions. +// It is used as an intermediary to convert the Viper config to the Config struct. +type ViperConfig struct { Description string - Regexes []string - Commits []string - Files []string - Paths []string - Repos []string -} - -// TomlLoader gets loaded with the values from a gitleaks toml config -// see the config in config/defaults.go for an example. TomlLoader is used -// to generate Config values (compiling regexes, etc). -type TomlLoader struct { - AllowList TomlAllowList - Rules []struct { + Extend Extend + Rules []struct { + ID string Description string + Entropy float64 + SecretGroup int Regex string - File string + Keywords []string Path string Tags []string - Entropies []struct { - Min string - Max string - Group string + + Allowlist struct { + Regexes []string + Paths []string + Commits []string + StopWords []string } - AllowList TomlAllowList + } + Allowlist struct { + Regexes []string + Paths []string + Commits []string + StopWords []string } } -// NewConfig will create a new config struct which contains -// rules on how gitleaks will proceed with its scan. -// If no options are passed via cli then NewConfig will return -// a default config which can be seen in config.go -func NewConfig(options options.Options) (Config, error) { - var cfg Config - tomlLoader := TomlLoader{} - - var err error - if options.Config != "" { - _, err = toml.DecodeFile(options.Config, &tomlLoader) - // append a allowlist rule for allowlisting the config - tomlLoader.AllowList.Files = append(tomlLoader.AllowList.Files, path.Base(options.Config)) - } else { - _, err = toml.Decode(DefaultConfig, &tomlLoader) - } - if err != nil { - return cfg, err - } +// Config is a configuration struct that contains rules and an allowlist if present. +type Config struct { + Extend Extend + Path string + Description string + Rules map[string]Rule + Allowlist Allowlist + Keywords []string - cfg, err = tomlLoader.Parse() - if err != nil { - return cfg, err - } + // used to keep sarif results consistent + orderedRules []string +} - return cfg, nil +// Extend is a struct that allows users to define how they want their +// configuration extended by other configuration files. +type Extend struct { + Path string + URL string + UseDefault bool } -// Parse will parse the values set in a TomlLoader and use those values -// to create compiled regular expressions and rules used in scans -func (tomlLoader TomlLoader) Parse() (Config, error) { - var cfg Config - for _, rule := range tomlLoader.Rules { - // check and make sure the rule is valid - if rule.Regex == "" && rule.Path == "" && rule.File == "" && len(rule.Entropies) == 0 { - log.Warnf("Rule %s does not define any actionable data", rule.Description) - continue - } - re, err := regexp.Compile(rule.Regex) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) +func (vc *ViperConfig) Translate() (Config, error) { + var ( + keywords []string + orderedRules []string + ) + rulesMap := make(map[string]Rule) + + for _, r := range vc.Rules { + var allowlistRegexes []*regexp.Regexp + for _, a := range r.Allowlist.Regexes { + allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a)) } - fileNameRe, err := regexp.Compile(rule.File) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + var allowlistPaths []*regexp.Regexp + for _, a := range r.Allowlist.Paths { + allowlistPaths = append(allowlistPaths, regexp.MustCompile(a)) } - filePathRe, err := regexp.Compile(rule.Path) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - - // rule specific allowlists - var allowList AllowList - // rule specific regexes - for _, re := range rule.AllowList.Regexes { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + if r.Keywords == nil { + r.Keywords = []string{} + } else { + for _, k := range r.Keywords { + keywords = append(keywords, strings.ToLower(k)) } - allowList.Regexes = append(allowList.Regexes, allowListedRegex) } - // rule specific filenames - for _, re := range rule.AllowList.Files { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - allowList.Files = append(allowList.Files, allowListedRegex) + if r.Tags == nil { + r.Tags = []string{} } - // rule specific paths - for _, re := range rule.AllowList.Paths { - allowListedRegex, err := regexp.Compile(re) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - allowList.Paths = append(allowList.Paths, allowListedRegex) + var configRegex *regexp.Regexp + var configPathRegex *regexp.Regexp + if r.Regex == "" { + configRegex = nil + } else { + configRegex = regexp.MustCompile(r.Regex) } - - var entropies []Entropy - for _, e := range rule.Entropies { - min, err := strconv.ParseFloat(e.Min, 64) - if err != nil { - return cfg, err - } - max, err := strconv.ParseFloat(e.Max, 64) - if err != nil { - return cfg, err - } - if e.Group == "" { - e.Group = "0" - } - group, err := strconv.ParseInt(e.Group, 10, 64) - if err != nil { - return cfg, err - } else if int(group) >= len(re.SubexpNames()) { - return cfg, fmt.Errorf("problem loading config: group cannot be higher than number of groups in regexp") - } else if group < 0 { - return cfg, fmt.Errorf("problem loading config: group cannot be lower than 0") - } else if min > 8.0 || min < 0.0 || max > 8.0 || max < 0.0 { - return cfg, fmt.Errorf("problem loading config: invalid entropy ranges, must be within 0.0-8.0") - } else if min > max { - return cfg, fmt.Errorf("problem loading config: entropy Min value cannot be higher than Max value") - } - - entropies = append(entropies, Entropy{Min: min, Max: max, Group: int(group)}) + if r.Path == "" { + configPathRegex = nil + } else { + configPathRegex = regexp.MustCompile(r.Path) } - r := Rule{ - Description: rule.Description, - Regex: re, - File: fileNameRe, - Path: filePathRe, - Tags: rule.Tags, - AllowList: allowList, - Entropies: entropies, + Description: r.Description, + RuleID: r.ID, + Regex: configRegex, + Path: configPathRegex, + SecretGroup: r.SecretGroup, + Entropy: r.Entropy, + Tags: r.Tags, + Keywords: r.Keywords, + Allowlist: Allowlist{ + Regexes: allowlistRegexes, + Paths: allowlistPaths, + Commits: r.Allowlist.Commits, + StopWords: r.Allowlist.StopWords, + }, } + orderedRules = append(orderedRules, r.RuleID) - cfg.Rules = append(cfg.Rules, r) + if r.Regex != nil && r.SecretGroup > r.Regex.NumSubexp() { + return Config{}, fmt.Errorf("%s invalid regex secret group %d, max regex secret group %d", r.Description, r.SecretGroup, r.Regex.NumSubexp()) + } + rulesMap[r.RuleID] = r + } + var allowlistRegexes []*regexp.Regexp + for _, a := range vc.Allowlist.Regexes { + allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a)) + } + var allowlistPaths []*regexp.Regexp + for _, a := range vc.Allowlist.Paths { + allowlistPaths = append(allowlistPaths, regexp.MustCompile(a)) + } + c := Config{ + Description: vc.Description, + Extend: vc.Extend, + Rules: rulesMap, + Allowlist: Allowlist{ + Regexes: allowlistRegexes, + Paths: allowlistPaths, + Commits: vc.Allowlist.Commits, + StopWords: vc.Allowlist.StopWords, + }, + Keywords: keywords, + orderedRules: orderedRules, } - // global regex allowLists - for _, allowListRegex := range tomlLoader.AllowList.Regexes { - re, err := regexp.Compile(allowListRegex) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + if maxExtendDepth != extendDepth { + // disallow both usedefault and path from being set + if c.Extend.Path != "" && c.Extend.UseDefault { + log.Fatal().Msg("unable to load config due to extend.path and extend.useDefault being set") + } + if c.Extend.UseDefault { + c.extendDefault() + } else if c.Extend.Path != "" { + c.extendPath() } - cfg.Allowlist.Regexes = append(cfg.Allowlist.Regexes, re) + } - // global file name allowLists - for _, allowListFileName := range tomlLoader.AllowList.Files { - re, err := regexp.Compile(allowListFileName) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) + return c, nil +} + +func (c *Config) OrderedRules() []Rule { + var orderedRules []Rule + for _, id := range c.orderedRules { + if _, ok := c.Rules[id]; ok { + orderedRules = append(orderedRules, c.Rules[id]) } - cfg.Allowlist.Files = append(cfg.Allowlist.Files, re) } + return orderedRules +} - // global file path allowLists - for _, allowListFilePath := range tomlLoader.AllowList.Paths { - re, err := regexp.Compile(allowListFilePath) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - cfg.Allowlist.Paths = append(cfg.Allowlist.Paths, re) +func (c *Config) extendDefault() { + extendDepth++ + viper.SetConfigType("toml") + if err := viper.ReadConfig(strings.NewReader(DefaultConfig)); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return } + defaultViperConfig := ViperConfig{} + if err := viper.Unmarshal(&defaultViperConfig); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + cfg, err := defaultViperConfig.Translate() + if err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + log.Debug().Msg("extending config with default config") + c.extend(cfg) - // global repo allowLists - for _, allowListRepo := range tomlLoader.AllowList.Repos { - re, err := regexp.Compile(allowListRepo) - if err != nil { - return cfg, fmt.Errorf("problem loading config: %v", err) - } - cfg.Allowlist.Repos = append(cfg.Allowlist.Repos, re) +} + +func (c *Config) extendPath() { + extendDepth++ + viper.SetConfigFile(c.Extend.Path) + if err := viper.ReadInConfig(); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + extensionViperConfig := ViperConfig{} + if err := viper.Unmarshal(&extensionViperConfig); err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return } + cfg, err := extensionViperConfig.Translate() + if err != nil { + log.Fatal().Msgf("failed to load extended config, err: %s", err) + return + } + log.Debug().Msgf("extending config with %s", c.Extend.Path) + c.extend(cfg) +} - cfg.Allowlist.Commits = tomlLoader.AllowList.Commits - cfg.Allowlist.Description = tomlLoader.AllowList.Description +func (c *Config) extendURL() { + // TODO +} + +func (c *Config) extend(extensionConfig Config) { + for ruleID, rule := range extensionConfig.Rules { + if _, ok := c.Rules[ruleID]; !ok { + log.Trace().Msgf("adding %s to base config", ruleID) + c.Rules[ruleID] = rule + c.Keywords = append(c.Keywords, rule.Keywords...) + } + } - return cfg, nil + // append allowlists, not attempting to merge + c.Allowlist.Commits = append(c.Allowlist.Commits, + extensionConfig.Allowlist.Commits...) + c.Allowlist.Paths = append(c.Allowlist.Paths, + extensionConfig.Allowlist.Paths...) + c.Allowlist.Regexes = append(c.Allowlist.Regexes, + extensionConfig.Allowlist.Regexes...) } diff --git a/config/config_test.go b/config/config_test.go index d824d17c8..7c2ad366f 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,127 +5,144 @@ import ( "regexp" "testing" - "github.com/zricethezav/gitleaks/v6/options" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" ) -func TestParse(t *testing.T) { +const configPath = "../testdata/config/" + +func TestTranslate(t *testing.T) { tests := []struct { - description string - opts options.Options - wantErr error - wantFileRegex *regexp.Regexp - wantMessages *regexp.Regexp - wantAllowlist AllowList + cfgName string + cfg Config + wantError error }{ { - description: "default config", - opts: options.Options{}, - }, - { - description: "test successful load", - opts: options.Options{ - Config: "../test_data/test_configs/aws_key.toml", + cfgName: "allow_aws_re", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Regexes: []*regexp.Regexp{ + regexp.MustCompile("AKIALALEMEL33243OLIA"), + }, + }, + }, + }, }, }, { - description: "test bad toml", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key.toml", + cfgName: "allow_commit", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Commits: []string{"allowthiscommit"}, + }, + }, + }, }, - wantErr: fmt.Errorf("Near line 7 (last key parsed 'rules.description'): expected value but found \"AWS\" instead"), }, { - description: "test bad regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_regex_aws_key.toml", + cfgName: "allow_path", + cfg: Config{ + Rules: map[string]Rule{"aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + Allowlist: Allowlist{ + Paths: []*regexp.Regexp{ + regexp.MustCompile(".go"), + }, + }, + }, + }, }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: invalid nested repetition operator: `???`"), }, { - description: "test bad global allowlist file regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key_global_allowlist_file.toml", + cfgName: "entropy_group", + cfg: Config{ + Rules: map[string]Rule{"discord-api-key": { + Description: "Discord API key", + Regex: regexp.MustCompile(`(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]`), + RuleID: "discord-api-key", + Allowlist: Allowlist{}, + Entropy: 3.5, + SecretGroup: 3, + Tags: []string{}, + Keywords: []string{}, + }, + }, }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: missing argument to repetition operator: `??`"), }, { - description: "test bad global file regex", - opts: options.Options{ - Config: "../test_data/test_configs/bad_aws_key_file_regex.toml", - }, - wantErr: fmt.Errorf("problem loading config: error parsing regexp: missing argument to repetition operator: `??`"), + cfgName: "bad_entropy_group", + cfg: Config{}, + wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"), }, { - description: "test successful load big ol thing", - opts: options.Options{ - Config: "../test_data/test_configs/large.toml", + cfgName: "base", + cfg: Config{ + Rules: map[string]Rule{ + "aws-access-key": { + Description: "AWS Access Key", + Regex: regexp.MustCompile("(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-access-key", + }, + "aws-secret-key": { + Description: "AWS Secret Key", + Regex: regexp.MustCompile(`(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}`), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-secret-key", + }, + "aws-secret-key-again": { + Description: "AWS Secret Key", + Regex: regexp.MustCompile(`(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}`), + Tags: []string{"key", "AWS"}, + Keywords: []string{}, + RuleID: "aws-secret-key-again", + }, + }, }, }, - { - description: "test load entropy", - opts: options.Options{ - Config: "../test_data/test_configs/entropy.toml", - }, - }, - { - description: "test entropy bad range", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_1.toml", - }, - wantErr: fmt.Errorf("problem loading config: entropy Min value cannot be higher than Max value"), - }, - { - description: "test entropy value max", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_2.toml", - }, - wantErr: fmt.Errorf("strconv.ParseFloat: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value min", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_3.toml", - }, - wantErr: fmt.Errorf("strconv.ParseFloat: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_4.toml", - }, - wantErr: fmt.Errorf("strconv.ParseInt: parsing \"x\": invalid syntax"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_5.toml", - }, - wantErr: fmt.Errorf("problem loading config: group cannot be lower than 0"), - }, - { - description: "test entropy value group", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_6.toml", - }, - wantErr: fmt.Errorf("problem loading config: group cannot be higher than number of groups in regexp"), - }, - { - description: "test entropy range limits", - opts: options.Options{ - Config: "../test_data/test_configs/bad_entropy_7.toml", - }, - wantErr: fmt.Errorf("problem loading config: invalid entropy ranges, must be within 0.0-8.0"), - }, } - for _, test := range tests { - _, err := NewConfig(test.opts) + for _, tt := range tests { + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(tt.cfgName) + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc ViperConfig + err = viper.Unmarshal(&vc) if err != nil { - if test.wantErr == nil { - t.Error(test.description, err) - } else if test.wantErr.Error() != err.Error() { - t.Errorf("expected err: %s, got %s", test.wantErr, err) + t.Error(err) + } + cfg, err := vc.Translate() + if tt.wantError != nil { + if err == nil { + t.Errorf("expected error") } + assert.Equal(t, tt.wantError, err) } + + assert.Equal(t, cfg.Rules, tt.cfg.Rules) } } diff --git a/config/default.go b/config/default.go deleted file mode 100644 index 854c9fc36..000000000 --- a/config/default.go +++ /dev/null @@ -1,139 +0,0 @@ -package config - -// DefaultConfig is the default gitleaks configuration. If --config={path-to-config} is set than the config located -// at {path-to-config} will be used. Alternatively, if --repo-config is set then gitleaks will attempt to -// use the config set in a gitleaks.toml or .gitleaks.toml file in the repo that is run with --repo-config set. -const DefaultConfig = ` -title = "gitleaks config" - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?[0-9a-z]{35,44}''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?[0-9a-z]{18,25}''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)[0-9a-zA-Z]{35,40}''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?[0-9a-z]{16}''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "Asymmetric Private Key" - regex = '''-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----''' - tags = ["key", "AsymmetricPrivateKey"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - -[[rules]] - description = "Google (GCP) Service Account" - regex = '''"type": "service_account"''' - tags = ["key", "Google"] - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "SendGrid API Key" - regex = '''SG\.[\w_]{16,32}\.[\w_]{16,64}''' - tags = ["key", "SendGrid"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?SK[0-9a-f]{32}''' - tags = ["key", "twilio"] - -[allowlist] - description = "Allowlisted files" - files = ['''^\.?gitleaks.toml$''', - '''(.*?)(jpg|gif|doc|pdf|bin)$''', - '''(go.mod|go.sum)$'''] -` diff --git a/config/gitleaks.toml b/config/gitleaks.toml new file mode 100644 index 000000000..60f4652d4 --- /dev/null +++ b/config/gitleaks.toml @@ -0,0 +1,2758 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md + +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''', + '''node_modules''', + '''vendor''', +] + +[[rules]] +description = "Adafruit API Key" +id = "adafruit-api-key" +regex = '''(?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "adafruit", +] + +[[rules]] +description = "Adobe Client ID (OAuth Web)" +id = "adobe-client-id" +regex = '''(?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "adobe", +] + +[[rules]] +description = "Adobe Client Secret" +id = "adobe-client-secret" +regex = '''(?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "p8e-", +] + +[[rules]] +description = "Age secret key" +id = "age secret key" +regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}''' +keywords = [ + "age-secret-key-1", +] + +[[rules]] +description = "Airtable API Key" +id = "airtable-api-key" +regex = '''(?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "airtable", +] + +[[rules]] +description = "Algolia API Key" +id = "algolia-api-key" +regex = '''(?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "algolia", +] + +[[rules]] +description = "Alibaba AccessKey ID" +id = "alibaba-access-key-id" +regex = '''(?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ltai", +] + +[[rules]] +description = "Alibaba Secret Key" +id = "alibaba-secret-key" +regex = '''(?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "alibaba", +] + +[[rules]] +description = "Asana Client ID" +id = "asana-client-id" +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "asana", +] + +[[rules]] +description = "Asana Client Secret" +id = "asana-client-secret" +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "asana", +] + +[[rules]] +description = "Atlassian API token" +id = "atlassian-api-token" +regex = '''(?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "atlassian","confluence","jira", +] + +[[rules]] +description = "AWS" +id = "aws-access-token" +regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' +keywords = [ + "akia","agpa","aida","aroa","aipa","anpa","anva","asia", +] + +[[rules]] +description = "Beamer API token" +id = "beamer-api-token" +regex = '''(?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "beamer", +] + +[[rules]] +description = "Bitbucket Client ID" +id = "bitbucket-client-id" +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bitbucket", +] + +[[rules]] +description = "Bitbucket Client Secret" +id = "bitbucket-client-secret" +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bitbucket", +] + +[[rules]] +description = "Bittrex Access Key" +id = "bittrex-access-key" +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bittrex", +] + +[[rules]] +description = "Bittrex Secret Key" +id = "bittrex-secret-key" +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bittrex", +] + +[[rules]] +description = "Clojars API token" +id = "clojars-api-token" +regex = '''(?i)(CLOJARS_)[a-z0-9]{60}''' +keywords = [ + "clojars", +] + +[[rules]] +description = "Codecov Access Token" +id = "codecov-access-token" +regex = '''(?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "codecov", +] + +[[rules]] +description = "Coinbase Access Token" +id = "coinbase-access-token" +regex = '''(?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "coinbase", +] + +[[rules]] +description = "Confluent Access Token" +id = "confluent-access-token" +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "confluent", +] + +[[rules]] +description = "Confluent Secret Key" +id = "confluent-secret-key" +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "confluent", +] + +[[rules]] +description = "Contentful delivery API token" +id = "contentful-delivery-api-token" +regex = '''(?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "contentful", +] + +[[rules]] +description = "Databricks API token" +id = "databricks-api-token" +regex = '''(?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dapi", +] + +[[rules]] +description = "Datadog Access Token" +id = "datadog-access-token" +regex = '''(?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "datadog", +] + +[[rules]] +description = "DigitalOcean OAuth Access Token" +id = "digitalocean-access-token" +regex = '''(?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "doo_v1_", +] + +[[rules]] +description = "DigitalOcean Personal Access Token" +id = "digitalocean-pat" +regex = '''(?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dop_v1_", +] + +[[rules]] +description = "DigitalOcean OAuth Refresh Token" +id = "digitalocean-refresh-token" +regex = '''(?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dor_v1_", +] + +[[rules]] +description = "Discord API key" +id = "discord-api-token" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Discord client ID" +id = "discord-client-id" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Discord client secret" +id = "discord-client-secret" +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "discord", +] + +[[rules]] +description = "Doppler API token" +id = "doppler-api-token" +regex = '''(dp\.pt\.)(?i)[a-z0-9]{43}''' +keywords = [ + "doppler", +] + +[[rules]] +description = "Droneci Access Token" +id = "droneci-access-token" +regex = '''(?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "droneci", +] + +[[rules]] +description = "Dropbox API secret" +id = "dropbox-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "dropbox", +] + +[[rules]] +description = "Dropbox long lived API token" +id = "dropbox-long-lived-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +description = "Dropbox short lived API token" +id = "dropbox-short-lived-api-token" +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +description = "Duffel API token" +id = "duffel-api-token" +regex = '''duffel_(test|live)_(?i)[a-z0-9_\-=]{43}''' +keywords = [ + "duffel", +] + +[[rules]] +description = "Dynatrace API token" +id = "dynatrace-api-token" +regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}''' +keywords = [ + "dynatrace", +] + +[[rules]] +description = "EasyPost API token" +id = "easypost-api-token" +regex = '''EZAK(?i)[a-z0-9]{54}''' +keywords = [ + "ezak", +] + +[[rules]] +description = "EasyPost test API token" +id = "easypost-test-api-token" +regex = '''EZTK(?i)[a-z0-9]{54}''' +keywords = [ + "eztk", +] + +[[rules]] +description = "Etsy Access Token" +id = "etsy-access-token" +regex = '''(?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "etsy", +] + +[[rules]] +description = "Facebook" +id = "facebook" +regex = '''(?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "facebook", +] + +[[rules]] +description = "Fastly API key" +id = "fastly-api-token" +regex = '''(?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "fastly", +] + +[[rules]] +description = "Finicity API token" +id = "finicity-api-token" +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finicity", +] + +[[rules]] +description = "Finicity Client Secret" +id = "finicity-client-secret" +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finicity", +] + +[[rules]] +description = "Finnhub Access Token" +id = "finnhub-access-token" +regex = '''(?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "finnhub", +] + +[[rules]] +description = "Flickr Access Token" +id = "flickr-access-token" +regex = '''(?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "flickr", +] + +[[rules]] +description = "Flutterwave Encryption Key" +id = "flutterwave-encryption-key" +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{12}''' +keywords = [ + "flwseck_test", +] + +[[rules]] +description = "Finicity Public Key" +id = "flutterwave-public-key" +regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwpubk_test", +] + +[[rules]] +description = "Flutterwave Secret Key" +id = "flutterwave-secret-key" +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwseck_test", +] + +[[rules]] +description = "Frame.io API token" +id = "frameio-api-token" +regex = '''fio-u-(?i)[a-z0-9\-_=]{64}''' +keywords = [ + "fio-u-", +] + +[[rules]] +description = "Freshbooks Access Token" +id = "freshbooks-access-token" +regex = '''(?i)(?:freshbooks)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "freshbooks", +] + +[[rules]] +description = "GCP API key" +id = "gcp-api-key" +regex = '''(?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "aiza", +] + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-z\-_.=]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +entropy = 3.5 +keywords = [ + "key","api","token","secret","client","passwd","password","auth","access", +] +[rules.allowlist] +paths = [ + '''Database.refactorlog''' +] +stopwords= [ + "client", + "endpoint", + "vpn", + "_ec2_", + "aws_", + "authorize", + "author", + "define", + "config", + "credential", + "setting", + "sample", + "xxxxxx", + "000000", + "buffer", + "delete", + "aaaaaa", + "fewfwef", + "getenv", + "env_", + "system", + "example", + "ecdsa", + "sha256", + "sha1", + "sha2", + "md5", + "alert", + "wizard", + "target", + "onboard", + "welcome", + "page", + "exploit", + "experiment", + "expire", + "rabbitmq", + "scraper", + "widget", + "music", + "dns_", + "dns-", + "yahoo", + "want", + "json", + "action", + "script", + "fix_", + "fix-", + "develop", + "compas", + "stripe", + "service", + "master", + "metric", + "tech", + "gitignore", + "rich", + "open", + "stack", + "irc_", + "irc-", + "sublime", + "kohana", + "has_", + "has-", + "fabric", + "wordpres", + "role", + "osx_", + "osx-", + "boost", + "addres", + "queue", + "working", + "sandbox", + "internet", + "print", + "vision", + "tracking", + "being", + "generator", + "traffic", + "world", + "pull", + "rust", + "watcher", + "small", + "auth", + "full", + "hash", + "more", + "install", + "auto", + "complete", + "learn", + "paper", + "installer", + "research", + "acces", + "last", + "binding", + "spine", + "into", + "chat", + "algorithm", + "resource", + "uploader", + "video", + "maker", + "next", + "proc", + "lock", + "robot", + "snake", + "patch", + "matrix", + "drill", + "terminal", + "term", + "stuff", + "genetic", + "generic", + "identity", + "audit", + "pattern", + "audio", + "web_", + "web-", + "crud", + "problem", + "statu", + "cms-", + "cms_", + "arch", + "coffee", + "workflow", + "changelog", + "another", + "uiview", + "content", + "kitchen", + "gnu_", + "gnu-", + "gnu.", + "conf", + "couchdb", + "client", + "opencv", + "rendering", + "update", + "concept", + "varnish", + "gui_", + "gui-", + "gui.", + "version", + "shared", + "extra", + "product", + "still", + "not_", + "not-", + "not.", + "drop", + "ring", + "png_", + "png-", + "png.", + "actively", + "import", + "output", + "backup", + "start", + "embedded", + "registry", + "pool", + "semantic", + "instagram", + "bash", + "system", + "ninja", + "drupal", + "jquery", + "polyfill", + "physic", + "league", + "guide", + "pack", + "synopsi", + "sketch", + "injection", + "svg_", + "svg-", + "svg.", + "friendly", + "wave", + "convert", + "manage", + "camera", + "link", + "slide", + "timer", + "wrapper", + "gallery", + "url_", + "url-", + "url.", + "todomvc", + "requirej", + "party", + "http", + "payment", + "async", + "library", + "home", + "coco", + "gaia", + "display", + "universal", + "func", + "metadata", + "hipchat", + "under", + "room", + "config", + "personal", + "realtime", + "resume", + "database", + "testing", + "tiny", + "basic", + "forum", + "meetup", + "yet_", + "yet-", + "yet.", + "cento", + "dead", + "fluentd", + "editor", + "utilitie", + "run_", + "run-", + "run.", + "box_", + "box-", + "box.", + "bot_", + "bot-", + "bot.", + "making", + "sample", + "group", + "monitor", + "ajax", + "parallel", + "cassandra", + "ultimate", + "site", + "get_", + "get-", + "get.", + "gen_", + "gen-", + "gen.", + "gem_", + "gem-", + "gem.", + "extended", + "image", + "knife", + "asset", + "nested", + "zero", + "plugin", + "bracket", + "mule", + "mozilla", + "number", + "act_", + "act-", + "act.", + "map_", + "map-", + "map.", + "micro", + "debug", + "openshift", + "chart", + "expres", + "backend", + "task", + "source", + "translate", + "jbos", + "composer", + "sqlite", + "profile", + "mustache", + "mqtt", + "yeoman", + "have", + "builder", + "smart", + "like", + "oauth", + "school", + "guideline", + "captcha", + "filter", + "bitcoin", + "bridge", + "color", + "toolbox", + "discovery", + "new_", + "new-", + "new.", + "dashboard", + "when", + "setting", + "level", + "post", + "standard", + "port", + "platform", + "yui_", + "yui-", + "yui.", + "grunt", + "animation", + "haskell", + "icon", + "latex", + "cheat", + "lua_", + "lua-", + "lua.", + "gulp", + "case", + "author", + "without", + "simulator", + "wifi", + "directory", + "lisp", + "list", + "flat", + "adventure", + "story", + "storm", + "gpu_", + "gpu-", + "gpu.", + "store", + "caching", + "attention", + "solr", + "logger", + "demo", + "shortener", + "hadoop", + "finder", + "phone", + "pipeline", + "range", + "textmate", + "showcase", + "app_", + "app-", + "app.", + "idiomatic", + "edit", + "our_", + "our-", + "our.", + "out_", + "out-", + "out.", + "sentiment", + "linked", + "why_", + "why-", + "why.", + "local", + "cube", + "gmail", + "job_", + "job-", + "job.", + "rpc_", + "rpc-", + "rpc.", + "contest", + "tcp_", + "tcp-", + "tcp.", + "usage", + "buildout", + "weather", + "transfer", + "automated", + "sphinx", + "issue", + "sas_", + "sas-", + "sas.", + "parallax", + "jasmine", + "addon", + "machine", + "solution", + "dsl_", + "dsl-", + "dsl.", + "episode", + "menu", + "theme", + "best", + "adapter", + "debugger", + "chrome", + "tutorial", + "life", + "step", + "people", + "joomla", + "paypal", + "developer", + "solver", + "team", + "current", + "love", + "visual", + "date", + "data", + "canva", + "container", + "future", + "xml_", + "xml-", + "xml.", + "twig", + "nagio", + "spatial", + "original", + "sync", + "archived", + "refinery", + "science", + "mapping", + "gitlab", + "play", + "ext_", + "ext-", + "ext.", + "session", + "impact", + "set_", + "set-", + "set.", + "see_", + "see-", + "see.", + "migration", + "commit", + "community", + "shopify", + "what'", + "cucumber", + "statamic", + "mysql", + "location", + "tower", + "line", + "code", + "amqp", + "hello", + "send", + "index", + "high", + "notebook", + "alloy", + "python", + "field", + "document", + "soap", + "edition", + "email", + "php_", + "php-", + "php.", + "command", + "transport", + "official", + "upload", + "study", + "secure", + "angularj", + "akka", + "scalable", + "package", + "request", + "con_", + "con-", + "con.", + "flexible", + "security", + "comment", + "module", + "flask", + "graph", + "flash", + "apache", + "change", + "window", + "space", + "lambda", + "sheet", + "bookmark", + "carousel", + "friend", + "objective", + "jekyll", + "bootstrap", + "first", + "article", + "gwt_", + "gwt-", + "gwt.", + "classic", + "media", + "websocket", + "touch", + "desktop", + "real", + "read", + "recorder", + "moved", + "storage", + "validator", + "add-on", + "pusher", + "scs_", + "scs-", + "scs.", + "inline", + "asp_", + "asp-", + "asp.", + "timeline", + "base", + "encoding", + "ffmpeg", + "kindle", + "tinymce", + "pretty", + "jpa_", + "jpa-", + "jpa.", + "used", + "user", + "required", + "webhook", + "download", + "resque", + "espresso", + "cloud", + "mongo", + "benchmark", + "pure", + "cakephp", + "modx", + "mode", + "reactive", + "fuel", + "written", + "flickr", + "mail", + "brunch", + "meteor", + "dynamic", + "neo_", + "neo-", + "neo.", + "new_", + "new-", + "new.", + "net_", + "net-", + "net.", + "typo", + "type", + "keyboard", + "erlang", + "adobe", + "logging", + "ckeditor", + "message", + "iso_", + "iso-", + "iso.", + "hook", + "ldap", + "folder", + "reference", + "railscast", + "www_", + "www-", + "www.", + "tracker", + "azure", + "fork", + "form", + "digital", + "exporter", + "skin", + "string", + "template", + "designer", + "gollum", + "fluent", + "entity", + "language", + "alfred", + "summary", + "wiki", + "kernel", + "calendar", + "plupload", + "symfony", + "foundry", + "remote", + "talk", + "search", + "dev_", + "dev-", + "dev.", + "del_", + "del-", + "del.", + "token", + "idea", + "sencha", + "selector", + "interface", + "create", + "fun_", + "fun-", + "fun.", + "groovy", + "query", + "grail", + "red_", + "red-", + "red.", + "laravel", + "monkey", + "slack", + "supported", + "instant", + "value", + "center", + "latest", + "work", + "but_", + "but-", + "but.", + "bug_", + "bug-", + "bug.", + "virtual", + "tweet", + "statsd", + "studio", + "path", + "real-time", + "frontend", + "notifier", + "coding", + "tool", + "firmware", + "flow", + "random", + "mediawiki", + "bosh", + "been", + "beer", + "lightbox", + "theory", + "origin", + "redmine", + "hub_", + "hub-", + "hub.", + "require", + "pro_", + "pro-", + "pro.", + "ant_", + "ant-", + "ant.", + "any_", + "any-", + "any.", + "recipe", + "closure", + "mapper", + "event", + "todo", + "model", + "redi", + "provider", + "rvm_", + "rvm-", + "rvm.", + "program", + "memcached", + "rail", + "silex", + "foreman", + "activity", + "license", + "strategy", + "batch", + "streaming", + "fast", + "use_", + "use-", + "use.", + "usb_", + "usb-", + "usb.", + "impres", + "academy", + "slider", + "please", + "layer", + "cros", + "now_", + "now-", + "now.", + "miner", + "extension", + "own_", + "own-", + "own.", + "app_", + "app-", + "app.", + "debian", + "symphony", + "example", + "feature", + "serie", + "tree", + "project", + "runner", + "entry", + "leetcode", + "layout", + "webrtc", + "logic", + "login", + "worker", + "toolkit", + "mocha", + "support", + "back", + "inside", + "device", + "jenkin", + "contact", + "fake", + "awesome", + "ocaml", + "bit_", + "bit-", + "bit.", + "drive", + "screen", + "prototype", + "gist", + "binary", + "nosql", + "rest", + "overview", + "dart", + "dark", + "emac", + "mongoid", + "solarized", + "homepage", + "emulator", + "commander", + "django", + "yandex", + "gradle", + "xcode", + "writer", + "crm_", + "crm-", + "crm.", + "jade", + "startup", + "error", + "using", + "format", + "name", + "spring", + "parser", + "scratch", + "magic", + "try_", + "try-", + "try.", + "rack", + "directive", + "challenge", + "slim", + "counter", + "element", + "chosen", + "doc_", + "doc-", + "doc.", + "meta", + "should", + "button", + "packet", + "stream", + "hardware", + "android", + "infinite", + "password", + "software", + "ghost", + "xamarin", + "spec", + "chef", + "interview", + "hubot", + "mvc_", + "mvc-", + "mvc.", + "exercise", + "leaflet", + "launcher", + "air_", + "air-", + "air.", + "photo", + "board", + "boxen", + "way_", + "way-", + "way.", + "computing", + "welcome", + "notepad", + "portfolio", + "cat_", + "cat-", + "cat.", + "can_", + "can-", + "can.", + "magento", + "yaml", + "domain", + "card", + "yii_", + "yii-", + "yii.", + "checker", + "browser", + "upgrade", + "only", + "progres", + "aura", + "ruby_", + "ruby-", + "ruby.", + "polymer", + "util", + "lite", + "hackathon", + "rule", + "log_", + "log-", + "log.", + "opengl", + "stanford", + "skeleton", + "history", + "inspector", + "help", + "soon", + "selenium", + "lab_", + "lab-", + "lab.", + "scheme", + "schema", + "look", + "ready", + "leveldb", + "docker", + "game", + "minimal", + "logstash", + "messaging", + "within", + "heroku", + "mongodb", + "kata", + "suite", + "picker", + "win_", + "win-", + "win.", + "wip_", + "wip-", + "wip.", + "panel", + "started", + "starter", + "front-end", + "detector", + "deploy", + "editing", + "based", + "admin", + "capture", + "spree", + "page", + "bundle", + "goal", + "rpg_", + "rpg-", + "rpg.", + "setup", + "side", + "mean", + "reader", + "cookbook", + "mini", + "modern", + "seed", + "dom_", + "dom-", + "dom.", + "doc_", + "doc-", + "doc.", + "dot_", + "dot-", + "dot.", + "syntax", + "sugar", + "loader", + "website", + "make", + "kit_", + "kit-", + "kit.", + "protocol", + "human", + "daemon", + "golang", + "manager", + "countdown", + "connector", + "swagger", + "map_", + "map-", + "map.", + "mac_", + "mac-", + "mac.", + "man_", + "man-", + "man.", + "orm_", + "orm-", + "orm.", + "org_", + "org-", + "org.", + "little", + "zsh_", + "zsh-", + "zsh.", + "shop", + "show", + "workshop", + "money", + "grid", + "server", + "octopres", + "svn_", + "svn-", + "svn.", + "ember", + "embed", + "general", + "file", + "important", + "dropbox", + "portable", + "public", + "docpad", + "fish", + "sbt_", + "sbt-", + "sbt.", + "done", + "para", + "network", + "common", + "readme", + "popup", + "simple", + "purpose", + "mirror", + "single", + "cordova", + "exchange", + "object", + "design", + "gateway", + "account", + "lamp", + "intellij", + "math", + "mit_", + "mit-", + "mit.", + "control", + "enhanced", + "emitter", + "multi", + "add_", + "add-", + "add.", + "about", + "socket", + "preview", + "vagrant", + "cli_", + "cli-", + "cli.", + "powerful", + "top_", + "top-", + "top.", + "radio", + "watch", + "fluid", + "amazon", + "report", + "couchbase", + "automatic", + "detection", + "sprite", + "pyramid", + "portal", + "advanced", + "plu_", + "plu-", + "plu.", + "runtime", + "git_", + "git-", + "git.", + "uri_", + "uri-", + "uri.", + "haml", + "node", + "sql_", + "sql-", + "sql.", + "cool", + "core", + "obsolete", + "handler", + "iphone", + "extractor", + "array", + "copy", + "nlp_", + "nlp-", + "nlp.", + "reveal", + "pop_", + "pop-", + "pop.", + "engine", + "parse", + "check", + "html", + "nest", + "all_", + "all-", + "all.", + "chinese", + "buildpack", + "what", + "tag_", + "tag-", + "tag.", + "proxy", + "style", + "cookie", + "feed", + "restful", + "compiler", + "creating", + "prelude", + "context", + "java", + "rspec", + "mock", + "backbone", + "light", + "spotify", + "flex", + "related", + "shell", + "which", + "clas", + "webapp", + "swift", + "ansible", + "unity", + "console", + "tumblr", + "export", + "campfire", + "conway'", + "made", + "riak", + "hero", + "here", + "unix", + "unit", + "glas", + "smtp", + "how_", + "how-", + "how.", + "hot_", + "hot-", + "hot.", + "debug", + "release", + "diff", + "player", + "easy", + "right", + "old_", + "old-", + "old.", + "animate", + "time", + "push", + "explorer", + "course", + "training", + "nette", + "router", + "draft", + "structure", + "note", + "salt", + "where", + "spark", + "trello", + "power", + "method", + "social", + "via_", + "via-", + "via.", + "vim_", + "vim-", + "vim.", + "select", + "webkit", + "github", + "ftp_", + "ftp-", + "ftp.", + "creator", + "mongoose", + "led_", + "led-", + "led.", + "movie", + "currently", + "pdf_", + "pdf-", + "pdf.", + "load", + "markdown", + "phalcon", + "input", + "custom", + "atom", + "oracle", + "phonegap", + "ubuntu", + "great", + "rdf_", + "rdf-", + "rdf.", + "popcorn", + "firefox", + "zip_", + "zip-", + "zip.", + "cuda", + "dotfile", + "static", + "openwrt", + "viewer", + "powered", + "graphic", + "les_", + "les-", + "les.", + "doe_", + "doe-", + "doe.", + "maven", + "word", + "eclipse", + "lab_", + "lab-", + "lab.", + "hacking", + "steam", + "analytic", + "option", + "abstract", + "archive", + "reality", + "switcher", + "club", + "write", + "kafka", + "arduino", + "angular", + "online", + "title", + "don't", + "contao", + "notice", + "analyzer", + "learning", + "zend", + "external", + "staging", + "busines", + "tdd_", + "tdd-", + "tdd.", + "scanner", + "building", + "snippet", + "modular", + "bower", + "stm_", + "stm-", + "stm.", + "lib_", + "lib-", + "lib.", + "alpha", + "mobile", + "clean", + "linux", + "nginx", + "manifest", + "some", + "raspberry", + "gnome", + "ide_", + "ide-", + "ide.", + "block", + "statistic", + "info", + "drag", + "youtube", + "koan", + "facebook", + "paperclip", + "art_", + "art-", + "art.", + "quality", + "tab_", + "tab-", + "tab.", + "need", + "dojo", + "shield", + "computer", + "stat", + "state", + "twitter", + "utility", + "converter", + "hosting", + "devise", + "liferay", + "updated", + "force", + "tip_", + "tip-", + "tip.", + "behavior", + "active", + "call", + "answer", + "deck", + "better", + "principle", + "ches", + "bar_", + "bar-", + "bar.", + "reddit", + "three", + "haxe", + "just", + "plug-in", + "agile", + "manual", + "tetri", + "super", + "beta", + "parsing", + "doctrine", + "minecraft", + "useful", + "perl", + "sharing", + "agent", + "switch", + "view", + "dash", + "channel", + "repo", + "pebble", + "profiler", + "warning", + "cluster", + "running", + "markup", + "evented", + "mod_", + "mod-", + "mod.", + "share", + "csv_", + "csv-", + "csv.", + "response", + "good", + "house", + "connect", + "built", + "build", + "find", + "ipython", + "webgl", + "big_", + "big-", + "big.", + "google", + "scala", + "sdl_", + "sdl-", + "sdl.", + "sdk_", + "sdk-", + "sdk.", + "native", + "day_", + "day-", + "day.", + "puppet", + "text", + "routing", + "helper", + "linkedin", + "crawler", + "host", + "guard", + "merchant", + "poker", + "over", + "writing", + "free", + "classe", + "component", + "craft", + "nodej", + "phoenix", + "longer", + "quick", + "lazy", + "memory", + "clone", + "hacker", + "middleman", + "factory", + "motion", + "multiple", + "tornado", + "hack", + "ssh_", + "ssh-", + "ssh.", + "review", + "vimrc", + "driver", + "driven", + "blog", + "particle", + "table", + "intro", + "importer", + "thrift", + "xmpp", + "framework", + "refresh", + "react", + "font", + "librarie", + "variou", + "formatter", + "analysi", + "karma", + "scroll", + "tut_", + "tut-", + "tut.", + "apple", + "tag_", + "tag-", + "tag.", + "tab_", + "tab-", + "tab.", + "category", + "ionic", + "cache", + "homebrew", + "reverse", + "english", + "getting", + "shipping", + "clojure", + "boot", + "book", + "branch", + "combination", + "combo", +] +[[rules]] +description = "GitHub App Token" +id = "github-app-token" +regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' +keywords = [ + "ghu_","ghs_", +] + +[[rules]] +description = "GitHub OAuth Access Token" +id = "github-oauth" +regex = '''gho_[0-9a-zA-Z]{36}''' +keywords = [ + "gho_", +] + +[[rules]] +description = "GitHub Personal Access Token" +id = "github-pat" +regex = '''ghp_[0-9a-zA-Z]{36}''' +keywords = [ + "ghp_", +] + +[[rules]] +description = "GitHub Refresh Token" +id = "github-refresh-token" +regex = '''ghr_[0-9a-zA-Z]{36}''' +keywords = [ + "ghr_", +] + +[[rules]] +description = "GitLab Personal Access Token" +id = "gitlab-pat" +regex = '''glpat-[0-9a-zA-Z\-\_]{20}''' +keywords = [ + "glpat-", +] + +[[rules]] +description = "Gitter Access Token" +id = "gitter-access-token" +regex = '''(?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "gitter", +] + +[[rules]] +description = "GoCardless API token" +id = "gocardless-api-token" +regex = '''(?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "live_","gocardless", +] + +[[rules]] +description = "Grafana api key (or Grafana cloud api key)" +id = "grafana-api-key" +regex = '''(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "eyjrijoi", +] + +[[rules]] +description = "Grafana cloud api token" +id = "grafana-cloud-api-token" +regex = '''(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "glc_", +] + +[[rules]] +description = "Grafana service account token" +id = "grafana-service-account-token" +regex = '''(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "glsa_", +] + +[[rules]] +description = "HashiCorp Terraform user/org API token" +id = "hashicorp-tf-api-token" +regex = '''(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}''' +keywords = [ + "atlasv1", +] + +[[rules]] +description = "Heroku API Key" +id = "heroku-api-key" +regex = '''(?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "heroku", +] + +[[rules]] +description = "HubSpot API Token" +id = "hubspot-api-key" +regex = '''(?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "hubspot", +] + +[[rules]] +description = "Intercom API Token" +id = "intercom-api-key" +regex = '''(?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "intercom", +] + +[[rules]] +description = "JSON Web Token" +id = "jwt" +regex = '''(?i)\b(ey[0-9a-z]{30,34}\.ey[0-9a-z-\/_]{30,500}\.[0-9a-zA-Z-\/_]{10,200})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ey", +] + +[[rules]] +description = "Kraken Access Token" +id = "kraken-access-token" +regex = '''(?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kraken", +] + +[[rules]] +description = "Kucoin Access Token" +id = "kucoin-access-token" +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kucoin", +] + +[[rules]] +description = "Kucoin Secret Key" +id = "kucoin-secret-key" +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "kucoin", +] + +[[rules]] +description = "Launchdarkly Access Token" +id = "launchdarkly-access-token" +regex = '''(?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "launchdarkly", +] + +[[rules]] +description = "Linear API Token" +id = "linear-api-key" +regex = '''lin_api_(?i)[a-z0-9]{40}''' +keywords = [ + "lin_api_", +] + +[[rules]] +description = "Linear Client Secret" +id = "linear-client-secret" +regex = '''(?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linear", +] + +[[rules]] +description = "LinkedIn Client ID" +id = "linkedin-client-id" +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +description = "LinkedIn Client secret" +id = "linkedin-client-secret" +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +description = "Lob API Key" +id = "lob-api-key" +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "test_","live_", +] + +[[rules]] +description = "Lob Publishable API Key" +id = "lob-pub-api-key" +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "test_pub","live_pub","_pub", +] + +[[rules]] +description = "Mailchimp API key" +id = "mailchimp-api-key" +regex = '''(?i)(?:mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us20)(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailchimp", +] + +[[rules]] +description = "Mailgun private API token" +id = "mailgun-private-api-token" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "Mailgun public validation key" +id = "mailgun-pub-key" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "Mailgun webhook signing key" +id = "mailgun-signing-key" +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mailgun", +] + +[[rules]] +description = "MapBox API token" +id = "mapbox-api-token" +regex = '''(?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mapbox", +] + +[[rules]] +description = "Mattermost Access Token" +id = "mattermost-access-token" +regex = '''(?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "mattermost", +] + +[[rules]] +description = "MessageBird API token" +id = "messagebird-api-token" +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +description = "MessageBird client ID" +id = "messagebird-client-id" +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +description = "Microsoft Teams Webhook" +id = "microsoft-teams-webhook" +regex = '''https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}''' +keywords = [ + "webhook.office.com","webhookb2","incomingwebhook", +] + +[[rules]] +description = "Netlify Access Token" +id = "netlify-access-token" +regex = '''(?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "netlify", +] + +[[rules]] +description = "New Relic ingest browser API token" +id = "new-relic-browser-api-token" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nrjs-", +] + +[[rules]] +description = "New Relic user API ID" +id = "new-relic-user-api-id" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "new-relic","newrelic","new_relic", +] + +[[rules]] +description = "New Relic user API Key" +id = "new-relic-user-api-key" +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nrak", +] + +[[rules]] +description = "npm access token" +id = "npm-access-token" +regex = '''(?i)\b(npm_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "npm_", +] + +[[rules]] +description = "Nytimes Access Token" +id = "nytimes-access-token" +regex = '''(?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "nytimes","new-york-times","newyorktimes", +] + +[[rules]] +description = "Okta Access Token" +id = "okta-access-token" +regex = '''(?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "okta", +] + +[[rules]] +description = "Plaid API Token" +id = "plaid-api-token" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "Plaid Client ID" +id = "plaid-client-id" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "Plaid Secret key" +id = "plaid-secret-key" +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "plaid", +] + +[[rules]] +description = "PlanetScale API token" +id = "planetscale-api-token" +regex = '''(?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_tkn_", +] + +[[rules]] +description = "PlanetScale OAuth token" +id = "planetscale-oauth-token" +regex = '''(?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_oauth_", +] + +[[rules]] +description = "PlanetScale password" +id = "planetscale-password" +regex = '''(?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pscale_pw_", +] + +[[rules]] +description = "Postman API token" +id = "postman-api-token" +regex = '''(?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pmak-", +] + +[[rules]] +description = "Prefect API token" +id = "prefect-api-token" +regex = '''(?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pnu_", +] + +[[rules]] +description = "Private Key" +id = "private-key" +regex = '''(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY----''' +keywords = [ + "-----begin", +] + +[[rules]] +description = "Pulumi API token" +id = "pulumi-api-token" +regex = '''(?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "pul-", +] + +[[rules]] +description = "PyPI upload token" +id = "pypi-upload-token" +regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' +keywords = [ + "pypi-ageichlwas5vcmc", +] + +[[rules]] +description = "RapidAPI Access Token" +id = "rapidapi-access-token" +regex = '''(?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rapidapi", +] + +[[rules]] +description = "Readme API token" +id = "readme-api-token" +regex = '''(?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rdme_", +] + +[[rules]] +description = "Rubygem API token" +id = "rubygems-api-token" +regex = '''(?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "rubygems_", +] + +[[rules]] +description = "Sendbird Access ID" +id = "sendbird-access-id" +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sendbird", +] + +[[rules]] +description = "Sendbird Access Token" +id = "sendbird-access-token" +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sendbird", +] + +[[rules]] +description = "SendGrid API token" +id = "sendgrid-api-token" +regex = '''(?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sg.", +] + +[[rules]] +description = "Sendinblue API token" +id = "sendinblue-api-token" +regex = '''(?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "xkeysib-", +] + +[[rules]] +description = "Sentry Access Token" +id = "sentry-access-token" +regex = '''(?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sentry", +] + +[[rules]] +description = "Shippo API token" +id = "shippo-api-token" +regex = '''(?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "shippo_", +] + +[[rules]] +description = "Shopify access token" +id = "shopify-access-token" +regex = '''shpat_[a-fA-F0-9]{32}''' +keywords = [ + "shpat_", +] + +[[rules]] +description = "Shopify custom access token" +id = "shopify-custom-access-token" +regex = '''shpca_[a-fA-F0-9]{32}''' +keywords = [ + "shpca_", +] + +[[rules]] +description = "Shopify private app access token" +id = "shopify-private-app-access-token" +regex = '''shppa_[a-fA-F0-9]{32}''' +keywords = [ + "shppa_", +] + +[[rules]] +description = "Shopify shared secret" +id = "shopify-shared-secret" +regex = '''shpss_[a-fA-F0-9]{32}''' +keywords = [ + "shpss_", +] + +[[rules]] +description = "Sidekiq Secret" +id = "sidekiq-secret" +regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", +] + +[[rules]] +description = "Sidekiq Sensitive URL" +id = "sidekiq-sensitive-url" +regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' +secretGroup = 2 +keywords = [ + "gems.contribsys.com","enterprise.contribsys.com", +] + +[[rules]] +description = "Slack token" +id = "slack-access-token" +regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})''' +keywords = [ + "xoxb","xoxa","xoxp","xoxr","xoxs", +] + +[[rules]] +description = "Slack Webhook" +id = "slack-web-hook" +regex = '''https:\/\/hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{44,46}''' +keywords = [ + "hooks.slack.com", +] + +[[rules]] +description = "Square Access Token" +id = "square-access-token" +regex = '''(?i)\b(sq0atp-[0-9A-Za-z\-_]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sq0atp-", +] + +[[rules]] +description = "Squarespace Access Token" +id = "squarespace-access-token" +regex = '''(?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "squarespace", +] + +[[rules]] +description = "Stripe" +id = "stripe-access-token" +regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}''' +keywords = [ + "sk_test","pk_test","sk_live","pk_live", +] + +[[rules]] +description = "SumoLogic Access ID" +id = "sumologic-access-id" +regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sumo", +] + +[[rules]] +description = "SumoLogic Access Token" +id = "sumologic-access-token" +regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "sumo", +] + +[[rules]] +description = "Telegram Bot API Token" +id = "telegram-bot-api-token" +regex = '''(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])''' +secretGroup = 1 +keywords = [ + "telegram","api","bot","token","url", +] + +[[rules]] +description = "Travis CI Access Token" +id = "travisci-access-token" +regex = '''(?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "travis", +] + +[[rules]] +description = "Twilio API Key" +id = "twilio-api-key" +regex = '''SK[0-9a-fA-F]{32}''' +keywords = [ + "twilio", +] + +[[rules]] +description = "Twitch API token" +id = "twitch-api-token" +regex = '''(?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitch", +] + +[[rules]] +description = "Twitter Access Secret" +id = "twitter-access-secret" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter Access Token" +id = "twitter-access-token" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter API Key" +id = "twitter-api-key" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter API Secret" +id = "twitter-api-secret" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Twitter Bearer Token" +id = "twitter-bearer-token" +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "twitter", +] + +[[rules]] +description = "Typeform API token" +id = "typeform-api-token" +regex = '''(?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "tfp_", +] + +[[rules]] +description = "Vault Batch Token" +id = "vault-batch-token" +regex = '''(?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvb", +] + +[[rules]] +description = "Vault Service Token" +id = "vault-service-token" +regex = '''(?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvs", +] + +[[rules]] +description = "Yandex Access Token" +id = "yandex-access-token" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Yandex API Key" +id = "yandex-api-key" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Yandex AWS Access Token" +id = "yandex-aws-access-token" +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "yandex", +] + +[[rules]] +description = "Zendesk Secret Key" +id = "zendesk-secret-key" +regex = '''(?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +secretGroup = 1 +keywords = [ + "zendesk", +] + diff --git a/config/rule.go b/config/rule.go new file mode 100644 index 000000000..b7c8c1518 --- /dev/null +++ b/config/rule.go @@ -0,0 +1,43 @@ +package config + +import ( + "regexp" +) + +// Rules contain information that define details on how to detect secrets +type Rule struct { + // Description is the description of the rule. + Description string + + // RuleID is a unique identifier for this rule + RuleID string + + // Entropy is a float representing the minimum shannon + // entropy a regex group must have to be considered a secret. + Entropy float64 + + // SecretGroup is an int used to extract secret from regex + // match and used as the group that will have its entropy + // checked if `entropy` is set. + SecretGroup int + + // Regex is a golang regular expression used to detect secrets. + Regex *regexp.Regexp + + // Path is a golang regular expression used to + // filter secrets by path + Path *regexp.Regexp + + // Tags is an array of strings used for metadata + // and reporting purposes. + Tags []string + + // Keywords are used for pre-regex check filtering. Rules that contain + // keywords will perform a quick string compare check to make sure the + // keyword(s) are in the content being scanned. + Keywords []string + + // Allowlist allows a rule to be ignored for specific + // regexes, paths, and/or commits + Allowlist Allowlist +} diff --git a/config/utils.go b/config/utils.go new file mode 100644 index 000000000..ada6ff0fe --- /dev/null +++ b/config/utils.go @@ -0,0 +1,24 @@ +package config + +import ( + "regexp" +) + +func anyRegexMatch(f string, res []*regexp.Regexp) bool { + for _, re := range res { + if regexMatched(f, re) { + return true + } + } + return false +} + +func regexMatched(f string, re *regexp.Regexp) bool { + if re == nil { + return false + } + if re.FindString(f) != "" { + return true + } + return false +} diff --git a/detect/baseline.go b/detect/baseline.go new file mode 100644 index 000000000..b002fd4bf --- /dev/null +++ b/detect/baseline.go @@ -0,0 +1,65 @@ +package detect + +import ( + "encoding/json" + "fmt" + "io" + "os" + + "github.com/rs/zerolog/log" + + "github.com/zricethezav/gitleaks/v8/report" +) + +func IsNew(finding report.Finding, baseline []report.Finding) bool { + // Explicitly testing each property as it gives significantly better performance in comparison to cmp.Equal(). Drawback is that + // the code requires maintanance if/when the Finding struct changes + for _, b := range baseline { + + if finding.Author == b.Author && + finding.Commit == b.Commit && + finding.Date == b.Date && + finding.Description == b.Description && + finding.Email == b.Email && + finding.EndColumn == b.EndColumn && + finding.EndLine == b.EndLine && + finding.Entropy == b.Entropy && + finding.File == b.File && + // Omit checking finding.Fingerprint - if the format of the fingerprint changes, the users will see unexpected behaviour + finding.Match == b.Match && + finding.Message == b.Message && + finding.RuleID == b.RuleID && + finding.Secret == b.Secret && + finding.StartColumn == b.StartColumn && + finding.StartLine == b.StartLine { + return false + } + } + return true +} + +func LoadBaseline(baselinePath string) ([]report.Finding, error) { + var previousFindings []report.Finding + jsonFile, err := os.Open(baselinePath) + if err != nil { + return nil, fmt.Errorf("could not open %s", baselinePath) + } + + defer func() { + if cerr := jsonFile.Close(); cerr != nil { + log.Warn().Err(cerr).Msg("problem closing jsonFile handle") + } + }() + + bytes, err := io.ReadAll(jsonFile) + if err != nil { + return nil, fmt.Errorf("could not read data from the file %s", baselinePath) + } + + err = json.Unmarshal(bytes, &previousFindings) + if err != nil { + return nil, fmt.Errorf("the format of the file %s is not supported", baselinePath) + } + + return previousFindings, nil +} diff --git a/detect/baseline_test.go b/detect/baseline_test.go new file mode 100644 index 000000000..eb8983945 --- /dev/null +++ b/detect/baseline_test.go @@ -0,0 +1,137 @@ +package detect + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/zricethezav/gitleaks/v8/report" +) + +func TestIsNew(t *testing.T) { + tests := []struct { + findings report.Finding + baseline []report.Finding + expect bool + }{ + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0000", + }, + }, + expect: false, + }, + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0002", + }, + }, + expect: true, + }, + { + findings: report.Finding{ + Author: "a", + Commit: "0000", + Tags: []string{"a", "b"}, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "0000", + Tags: []string{"a", "c"}, + }, + }, + expect: false, // Updated tags doesn't make it a new finding + }, + } + for _, test := range tests { + assert.Equal(t, test.expect, IsNew(test.findings, test.baseline)) + } +} + +func TestFileLoadBaseline(t *testing.T) { + tests := []struct { + Filename string + ExpectedError error + }{ + { + Filename: "../testdata/baseline/baseline.csv", + ExpectedError: errors.New("the format of the file ../testdata/baseline/baseline.csv is not supported"), + }, + { + Filename: "../testdata/baseline/baseline.sarif", + ExpectedError: errors.New("the format of the file ../testdata/baseline/baseline.sarif is not supported"), + }, + { + Filename: "../testdata/baseline/notfound.json", + ExpectedError: errors.New("could not open ../testdata/baseline/notfound.json"), + }, + } + + for _, test := range tests { + _, err := LoadBaseline(test.Filename) + assert.Equal(t, test.ExpectedError.Error(), err.Error()) + } +} + +func TestIgnoreIssuesInBaseline(t *testing.T) { + tests := []struct { + findings []report.Finding + baseline []report.Finding + expectCount int + }{ + { + findings: []report.Finding{ + { + Author: "a", + Commit: "5", + }, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "5", + }, + }, + expectCount: 0, + }, + { + findings: []report.Finding{ + { + Author: "a", + Commit: "5", + Fingerprint: "a", + }, + }, + baseline: []report.Finding{ + { + Author: "a", + Commit: "5", + Fingerprint: "b", + }, + }, + expectCount: 0, + }, + } + + for _, test := range tests { + d, _ := NewDetectorDefaultConfig() + d.baseline = test.baseline + for _, finding := range test.findings { + d.addFinding(finding) + } + assert.Equal(t, test.expectCount, len(d.findings)) + } +} diff --git a/detect/detect.go b/detect/detect.go new file mode 100644 index 000000000..c0784462b --- /dev/null +++ b/detect/detect.go @@ -0,0 +1,511 @@ +package detect + +import ( + "bufio" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/detect/git" + "github.com/zricethezav/gitleaks/v8/report" + + "github.com/fatih/semgroup" + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/h2non/filetype" + ahocorasick "github.com/petar-dambovaliev/aho-corasick" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" +) + +// Type used to differentiate between git scan types: +// $ gitleaks detect +// $ gitleaks protect +// $ gitleaks protect staged +type GitScanType int + +const ( + DetectType GitScanType = iota + ProtectType + ProtectStagedType + + gitleaksAllowSignature = "gitleaks:allow" +) + +// Detector is the main detector struct +type Detector struct { + // Config is the configuration for the detector + Config config.Config + + // Redact is a flag to redact findings. This is exported + // so users using gitleaks as a library can set this flag + // without calling `detector.Start(cmd *cobra.Command)` + Redact bool + + // verbose is a flag to print findings + Verbose bool + + // commitMap is used to keep track of commits that have been scanned. + // This is only used for logging purposes and git scans. + commitMap map[string]bool + + // findingMutex is to prevent concurrent access to the + // findings slice when adding findings. + findingMutex *sync.Mutex + + // findings is a slice of report.Findings. This is the result + // of the detector's scan which can then be used to generate a + // report. + findings []report.Finding + + // prefilter is a ahocorasick struct used for doing efficient string + // matching given a set of words (keywords from the rules in the config) + prefilter ahocorasick.AhoCorasick + + // a list of known findings that should be ignored + baseline []report.Finding + + // path to baseline + baselinePath string + + // gitleaksIgnore + gitleaksIgnore map[string]bool +} + +// Fragment contains the data to be scanned +type Fragment struct { + // Raw is the raw content of the fragment + Raw string + + // FilePath is the path to the file if applicable + FilePath string + + // CommitSHA is the SHA of the commit if applicable + CommitSHA string + + // newlineIndices is a list of indices of newlines in the raw content. + // This is used to calculate the line location of a finding + newlineIndices [][]int + + // keywords is a map of all the keywords contain within the contents + // of this fragment + keywords map[string]bool +} + +// NewDetector creates a new detector with the given config +func NewDetector(cfg config.Config) *Detector { + builder := ahocorasick.NewAhoCorasickBuilder(ahocorasick.Opts{ + AsciiCaseInsensitive: true, + MatchOnlyWholeWords: false, + MatchKind: ahocorasick.LeftMostLongestMatch, + DFA: true, + }) + + return &Detector{ + commitMap: make(map[string]bool), + gitleaksIgnore: make(map[string]bool), + findingMutex: &sync.Mutex{}, + findings: make([]report.Finding, 0), + Config: cfg, + prefilter: builder.Build(cfg.Keywords), + } +} + +// NewDetectorDefaultConfig creates a new detector with the default config +func NewDetectorDefaultConfig() (*Detector, error) { + viper.SetConfigType("toml") + err := viper.ReadConfig(strings.NewReader(config.DefaultConfig)) + if err != nil { + return nil, err + } + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + return nil, err + } + cfg, err := vc.Translate() + if err != nil { + return nil, err + } + return NewDetector(cfg), nil +} + +func (d *Detector) AddGitleaksIgnore(gitleaksIgnorePath string) error { + log.Debug().Msg("found .gitleaksignore file") + file, err := os.Open(gitleaksIgnorePath) + + if err != nil { + return err + } + + defer file.Close() + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + d.gitleaksIgnore[scanner.Text()] = true + } + return nil +} + +func (d *Detector) AddBaseline(baselinePath string) error { + if baselinePath != "" { + baseline, err := LoadBaseline(baselinePath) + if err != nil { + return err + } + d.baseline = baseline + } + d.baselinePath = baselinePath + return nil +} + +// DetectBytes scans the given bytes and returns a list of findings +func (d *Detector) DetectBytes(content []byte) []report.Finding { + return d.DetectString(string(content)) +} + +// DetectString scans the given string and returns a list of findings +func (d *Detector) DetectString(content string) []report.Finding { + return d.Detect(Fragment{ + Raw: content, + }) +} + +// detectRule scans the given fragment for the given rule and returns a list of findings +func (d *Detector) detectRule(fragment Fragment, rule config.Rule) []report.Finding { + var findings []report.Finding + + // check if filepath or commit is allowed for this rule + if rule.Allowlist.CommitAllowed(fragment.CommitSHA) || + rule.Allowlist.PathAllowed(fragment.FilePath) { + return findings + } + + if rule.Path != nil && rule.Regex == nil { + // Path _only_ rule + if rule.Path.Match([]byte(fragment.FilePath)) { + finding := report.Finding{ + Description: rule.Description, + File: fragment.FilePath, + RuleID: rule.RuleID, + Match: fmt.Sprintf("file detected: %s", fragment.FilePath), + Tags: rule.Tags, + } + return append(findings, finding) + } + } else if rule.Path != nil { + // if path is set _and_ a regex is set, then we need to check both + // so if the path does not match, then we should return early and not + // consider the regex + if !rule.Path.Match([]byte(fragment.FilePath)) { + return findings + } + } + + // if path only rule, skip content checks + if rule.Regex == nil { + return findings + } + + matchIndices := rule.Regex.FindAllStringIndex(fragment.Raw, -1) + for _, matchIndex := range matchIndices { + // extract secret from match + secret := strings.Trim(fragment.Raw[matchIndex[0]:matchIndex[1]], "\n") + + // determine location of match. Note that the location + // in the finding will be the line/column numbers of the _match_ + // not the _secret_, which will be different if the secretGroup + // value is set for this rule + loc := location(fragment, matchIndex) + + if matchIndex[1] > loc.endLineIndex { + loc.endLineIndex = matchIndex[1] + } + + finding := report.Finding{ + Description: rule.Description, + File: fragment.FilePath, + RuleID: rule.RuleID, + StartLine: loc.startLine, + EndLine: loc.endLine, + StartColumn: loc.startColumn, + EndColumn: loc.endColumn, + Secret: secret, + Match: secret, + Tags: rule.Tags, + Line: fragment.Raw[loc.startLineIndex:loc.endLineIndex], + } + + if strings.Contains(fragment.Raw[loc.startLineIndex:loc.endLineIndex], + gitleaksAllowSignature) { + continue + } + + // check if the secret is in the allowlist + if rule.Allowlist.RegexAllowed(finding.Secret) || + d.Config.Allowlist.RegexAllowed(finding.Secret) { + continue + } + + // extract secret from secret group if set + if rule.SecretGroup != 0 { + groups := rule.Regex.FindStringSubmatch(secret) + if len(groups) <= rule.SecretGroup || len(groups) == 0 { + // Config validation should prevent this + continue + } + secret = groups[rule.SecretGroup] + finding.Secret = secret + } + + // check if the secret is in the list of stopwords + if rule.Allowlist.ContainsStopWord(finding.Secret) || + d.Config.Allowlist.ContainsStopWord(finding.Secret) { + continue + } + + // check entropy + entropy := shannonEntropy(finding.Secret) + finding.Entropy = float32(entropy) + if rule.Entropy != 0.0 { + if entropy <= rule.Entropy { + // entropy is too low, skip this finding + continue + } + // NOTE: this is a goofy hack to get around the fact there golang's regex engine + // does not support positive lookaheads. Ideally we would want to add a + // restriction on generic rules regex that requires the secret match group + // contains both numbers and alphabetical characters, not just alphabetical characters. + // What this bit of code does is check if the ruleid is prepended with "generic" and enforces the + // secret contains both digits and alphabetical characters. + // TODO: this should be replaced with stop words + if strings.HasPrefix(rule.RuleID, "generic") { + if !containsDigit(secret) { + continue + } + } + } + + findings = append(findings, finding) + } + return findings +} + +// GitScan accepts a *gitdiff.File channel which contents a git history generated from +// the output of `git log -p ...`. startGitScan will look at each file (patch) in the history +// and determine if the patch contains any findings. +func (d *Detector) DetectGit(source string, logOpts string, gitScanType GitScanType) ([]report.Finding, error) { + var ( + gitdiffFiles <-chan *gitdiff.File + err error + ) + switch gitScanType { + case DetectType: + gitdiffFiles, err = git.GitLog(source, logOpts) + if err != nil { + return d.findings, err + } + case ProtectType: + gitdiffFiles, err = git.GitDiff(source, false) + if err != nil { + return d.findings, err + } + case ProtectStagedType: + gitdiffFiles, err = git.GitDiff(source, true) + if err != nil { + return d.findings, err + } + } + + s := semgroup.NewGroup(context.Background(), 4) + + for gitdiffFile := range gitdiffFiles { + gitdiffFile := gitdiffFile + + // skip binary files + if gitdiffFile.IsBinary || gitdiffFile.IsDelete { + continue + } + + // Check if commit is allowed + commitSHA := "" + if gitdiffFile.PatchHeader != nil { + commitSHA = gitdiffFile.PatchHeader.SHA + if d.Config.Allowlist.CommitAllowed(gitdiffFile.PatchHeader.SHA) { + continue + } + } + d.addCommit(commitSHA) + + s.Go(func() error { + for _, textFragment := range gitdiffFile.TextFragments { + if textFragment == nil { + return nil + } + + fragment := Fragment{ + Raw: textFragment.Raw(gitdiff.OpAdd), + CommitSHA: commitSHA, + FilePath: gitdiffFile.NewName, + } + + for _, finding := range d.Detect(fragment) { + d.addFinding(augmentGitFinding(finding, textFragment, gitdiffFile)) + } + } + return nil + }) + } + + if err := s.Wait(); err != nil { + return d.findings, err + } + log.Info().Msgf("%d commits scanned.", len(d.commitMap)) + log.Debug().Msg("Note: this number might be smaller than expected due to commits with no additions") + if git.ErrEncountered { + return d.findings, fmt.Errorf("%s", "git error encountered, see logs") + } + return d.findings, nil +} + +// DetectFiles accepts a path to a source directory or file and begins a scan of the +// file or directory. +func (d *Detector) DetectFiles(source string) ([]report.Finding, error) { + s := semgroup.NewGroup(context.Background(), 4) + paths := make(chan string) + s.Go(func() error { + defer close(paths) + return filepath.Walk(source, + func(path string, fInfo os.FileInfo, err error) error { + if err != nil { + return err + } + if fInfo.Name() == ".git" && fInfo.IsDir() { + return filepath.SkipDir + } + if fInfo.Size() == 0 { + return nil + } + if fInfo.Mode().IsRegular() { + paths <- path + } + return nil + }) + }) + for pa := range paths { + p := pa + s.Go(func() error { + b, err := os.ReadFile(p) + if err != nil { + return err + } + + mimetype, err := filetype.Match(b) + if err != nil { + return err + } + if mimetype.MIME.Type == "application" { + return nil // skip binary files + } + + fragment := Fragment{ + Raw: string(b), + FilePath: p, + } + for _, finding := range d.Detect(fragment) { + // need to add 1 since line counting starts at 1 + finding.EndLine++ + finding.StartLine++ + d.addFinding(finding) + } + + return nil + }) + } + + if err := s.Wait(); err != nil { + return d.findings, err + } + + return d.findings, nil +} + +// Detect scans the given fragment and returns a list of findings +func (d *Detector) Detect(fragment Fragment) []report.Finding { + var findings []report.Finding + + // initiate fragment keywords + fragment.keywords = make(map[string]bool) + + // check if filepath is allowed + if fragment.FilePath != "" && (d.Config.Allowlist.PathAllowed(fragment.FilePath) || + fragment.FilePath == d.Config.Path || (d.baselinePath != "" && fragment.FilePath == d.baselinePath)) { + return findings + } + + // add newline indices for location calculation in detectRule + fragment.newlineIndices = regexp.MustCompile("\n").FindAllStringIndex(fragment.Raw, -1) + + // build keyword map for prefiltering rules + normalizedRaw := strings.ToLower(fragment.Raw) + matches := d.prefilter.FindAll(normalizedRaw) + for _, m := range matches { + fragment.keywords[normalizedRaw[m.Start():m.End()]] = true + } + + for _, rule := range d.Config.Rules { + if len(rule.Keywords) == 0 { + // if not keywords are associated with the rule always scan the + // fragment using the rule + findings = append(findings, d.detectRule(fragment, rule)...) + continue + } + fragmentContainsKeyword := false + // check if keywords are in the fragment + for _, k := range rule.Keywords { + if _, ok := fragment.keywords[strings.ToLower(k)]; ok { + fragmentContainsKeyword = true + } + } + if fragmentContainsKeyword { + findings = append(findings, d.detectRule(fragment, rule)...) + } + } + return filter(findings, d.Redact) +} + +// addFinding synchronously adds a finding to the findings slice +func (d *Detector) addFinding(finding report.Finding) { + if finding.Commit == "" { + finding.Fingerprint = fmt.Sprintf("%s:%s:%d", finding.File, finding.RuleID, finding.StartLine) + } else { + finding.Fingerprint = fmt.Sprintf("%s:%s:%s:%d", finding.Commit, finding.File, finding.RuleID, finding.StartLine) + } + // check if we should ignore this finding + if _, ok := d.gitleaksIgnore[finding.Fingerprint]; ok { + log.Debug().Msgf("ignoring finding with Fingerprint %s", + finding.Fingerprint) + return + } + + if d.baseline != nil && !IsNew(finding, d.baseline) { + log.Debug().Msgf("baseline duplicate -- ignoring finding with Fingerprint %s", finding.Fingerprint) + return + } + + d.findingMutex.Lock() + d.findings = append(d.findings, finding) + if d.Verbose { + printFinding(finding) + } + d.findingMutex.Unlock() +} + +// addCommit synchronously adds a commit to the commit slice +func (d *Detector) addCommit(commit string) { + d.commitMap[commit] = true +} diff --git a/detect/detect_test.go b/detect/detect_test.go new file mode 100644 index 000000000..c4c4863d8 --- /dev/null +++ b/detect/detect_test.go @@ -0,0 +1,578 @@ +package detect + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + + "github.com/zricethezav/gitleaks/v8/config" + "github.com/zricethezav/gitleaks/v8/report" +) + +const configPath = "../testdata/config/" +const repoBasePath = "../testdata/repos/" + +func TestDetect(t *testing.T) { + tests := []struct { + cfgName string + fragment Fragment + expectedFindings []report.Finding + wantError error + }{ + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OKIA\ // gitleaks:allow"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \ + + \"AKIALALEMEL33243OKIA\ // gitleaks:allow" + + `, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OKIA\" + + // gitleaks:allow" + + `, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + Secret: "AKIALALEMEL33243OKIA", + Match: "AKIALALEMEL33243OKIA", + File: "tmp.go", + Line: `awsToken := \"AKIALALEMEL33243OKIA\"`, + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + StartLine: 0, + EndLine: 0, + StartColumn: 15, + EndColumn: 34, + Entropy: 3.1464393, + }, + }, + }, + { + cfgName: "escaped_character_group", + fragment: Fragment{ + Raw: `pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "PyPI upload token", + Secret: "pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB", + Match: "pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB", + Line: `pypi-AgEIcHlwaS5vcmcAAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAA-AAAAAAAAAAB`, + File: "tmp.go", + RuleID: "pypi-upload-token", + Tags: []string{"key", "pypi"}, + StartLine: 1, + EndLine: 1, + StartColumn: 1, + EndColumn: 86, + Entropy: 1.9606875, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + Line: `awsToken := \"AKIALALEMEL33243OLIA\"`, + File: "tmp.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + StartLine: 1, + EndLine: 1, + StartColumn: 15, + EndColumn: 34, + Entropy: 3.0841837, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Secret", + Match: "BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;", + Secret: "cafebabe:deadbeef", + Line: `export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef;`, + File: "tmp.sh", + RuleID: "sidekiq-secret", + Tags: []string{}, + Entropy: 2.6098502, + StartLine: 1, + EndLine: 1, + StartColumn: 8, + EndColumn: 60, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `echo hello1; export BUNDLE_ENTERPRISE__CONTRIBSYS__COM="cafebabe:deadbeef" && echo hello2`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Secret", + Match: "BUNDLE_ENTERPRISE__CONTRIBSYS__COM=\"cafebabe:deadbeef\"", + Secret: "cafebabe:deadbeef", + File: "tmp.sh", + Line: `echo hello1; export BUNDLE_ENTERPRISE__CONTRIBSYS__COM="cafebabe:deadbeef" && echo hello2`, + RuleID: "sidekiq-secret", + Tags: []string{}, + Entropy: 2.6098502, + StartLine: 1, + EndLine: 1, + StartColumn: 21, + EndColumn: 74, + }, + }, + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `url = "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1"`, + FilePath: "tmp.sh", + }, + expectedFindings: []report.Finding{ + { + Description: "Sidekiq Sensitive URL", + Match: "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:", + Secret: "cafeb4b3:d3adb33f", + File: "tmp.sh", + Line: `url = "http://cafeb4b3:d3adb33f@enterprise.contribsys.com:80/path?param1=true¶m2=false#heading1"`, + RuleID: "sidekiq-sensitive-url", + Tags: []string{}, + Entropy: 2.984234, + StartLine: 1, + EndLine: 1, + StartColumn: 8, + EndColumn: 58, + }, + }, + }, + { + cfgName: "allow_aws_re", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_path", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_commit", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + CommitSHA: "allowthiscommit", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "entropy_group", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{ + { + Description: "Discord API key", + Match: "Discord_Public_Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"", + Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5", + Line: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + File: "tmp.go", + RuleID: "discord-api-key", + Tags: []string{}, + Entropy: 3.7906237, + StartLine: 1, + EndLine: 1, + StartColumn: 7, + EndColumn: 93, + }, + }, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{ + { + Description: "Generic API Key", + Match: "Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"", + Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5", + Line: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + File: "tmp.py", + RuleID: "generic-api-key", + Tags: []string{}, + Entropy: 3.7906237, + StartLine: 1, + EndLine: 1, + StartColumn: 22, + EndColumn: 93, + }, + }, + }, + { + cfgName: "path_only", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{ + { + Description: "Python Files", + Match: "file detected: tmp.py", + File: "tmp.py", + RuleID: "python-files-only", + Tags: []string{}, + }, + }, + }, + { + cfgName: "bad_entropy_group", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"), + }, + { + cfgName: "simple", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: filepath.Join(configPath, "simple.toml"), + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "allow_global_aws_re", + fragment: Fragment{ + Raw: `awsToken := \"AKIALALEMEL33243OLIA\"`, + FilePath: "tmp.go", + }, + expectedFindings: []report.Finding{}, + }, + { + cfgName: "generic_with_py_path", + fragment: Fragment{ + Raw: `const Discord_Public_Key = "load2523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`, + FilePath: "tmp.py", + }, + expectedFindings: []report.Finding{}, + }, + } + + for _, tt := range tests { + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(tt.cfgName) + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, err := vc.Translate() + cfg.Path = filepath.Join(configPath, tt.cfgName+".toml") + if tt.wantError != nil { + if err == nil { + t.Errorf("expected error") + } + assert.Equal(t, tt.wantError, err) + } + d := NewDetector(cfg) + + findings := d.Detect(tt.fragment) + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +// TestFromGit tests the FromGit function +func TestFromGit(t *testing.T) { + tests := []struct { + cfgName string + source string + logOpts string + expectedFindings []report.Finding + }{ + { + source: filepath.Join(repoBasePath, "small"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 19, + EndColumn: 38, + Line: "\n awsToken := \"AKIALALEMEL33243OLIA\"", + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + File: "main.go", + Date: "2021-11-02T23:37:53Z", + Commit: "1b6da43b82b22e4eaa10bcf8ee591e91abbfc587", + Author: "Zachary Rice", + Email: "zricer@protonmail.com", + Message: "Accidentally add a secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "1b6da43b82b22e4eaa10bcf8ee591e91abbfc587:main.go:aws-access-key:20", + }, + { + Description: "AWS Access Key", + StartLine: 9, + EndLine: 9, + StartColumn: 17, + EndColumn: 36, + Secret: "AKIALALEMEL33243OLIA", + Match: "AKIALALEMEL33243OLIA", + Line: "\n\taws_token := \"AKIALALEMEL33243OLIA\"", + File: "foo/foo.go", + Date: "2021-11-02T23:48:06Z", + Commit: "491504d5a31946ce75e22554cc34203d8e5ff3ca", + Author: "Zach Rice", + Email: "zricer@protonmail.com", + Message: "adding foo package with secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "491504d5a31946ce75e22554cc34203d8e5ff3ca:foo/foo.go:aws-access-key:9", + }, + }, + }, + { + source: filepath.Join(repoBasePath, "small"), + logOpts: "--all foo...", + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 9, + EndLine: 9, + StartColumn: 17, + EndColumn: 36, + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\taws_token := \"AKIALALEMEL33243OLIA\"", + Match: "AKIALALEMEL33243OLIA", + Date: "2021-11-02T23:48:06Z", + File: "foo/foo.go", + Commit: "491504d5a31946ce75e22554cc34203d8e5ff3ca", + Author: "Zach Rice", + Email: "zricer@protonmail.com", + Message: "adding foo package with secret", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "491504d5a31946ce75e22554cc34203d8e5ff3ca:foo/foo.go:aws-access-key:9", + }, + }, + }, + } + + err := moveDotGit("dotGit", ".git") + if err != nil { + t.Fatal(err) + } + defer func() { + if err := moveDotGit(".git", "dotGit"); err != nil { + t.Error(err) + } + }() + + for _, tt := range tests { + + viper.AddConfigPath(configPath) + viper.SetConfigName("simple") + viper.SetConfigType("toml") + err = viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, err := vc.Translate() + if err != nil { + t.Error(err) + } + detector := NewDetector(cfg) + findings, err := detector.DetectGit(tt.source, tt.logOpts, DetectType) + if err != nil { + t.Error(err) + } + + for _, f := range findings { + f.Match = "" // remove lines cause copying and pasting them has some wack formatting + } + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +// TestFromGit tests the FromGit function +func TestFromFiles(t *testing.T) { + tests := []struct { + cfgName string + source string + expectedFindings []report.Finding + }{ + { + source: filepath.Join(repoBasePath, "nogit"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 16, + EndColumn: 35, + Match: "AKIALALEMEL33243OLIA", + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\tawsToken := \"AKIALALEMEL33243OLIA\"", + File: "../testdata/repos/nogit/main.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "../testdata/repos/nogit/main.go:aws-access-key:20", + }, + }, + }, + { + source: filepath.Join(repoBasePath, "nogit", "main.go"), + cfgName: "simple", + expectedFindings: []report.Finding{ + { + Description: "AWS Access Key", + StartLine: 20, + EndLine: 20, + StartColumn: 16, + EndColumn: 35, + Match: "AKIALALEMEL33243OLIA", + Secret: "AKIALALEMEL33243OLIA", + Line: "\n\tawsToken := \"AKIALALEMEL33243OLIA\"", + File: "../testdata/repos/nogit/main.go", + RuleID: "aws-access-key", + Tags: []string{"key", "AWS"}, + Entropy: 3.0841837, + Fingerprint: "../testdata/repos/nogit/main.go:aws-access-key:20", + }, + }, + }, + } + + for _, tt := range tests { + viper.AddConfigPath(configPath) + viper.SetConfigName("simple") + viper.SetConfigType("toml") + err := viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + cfg, _ := vc.Translate() + detector := NewDetector(cfg) + findings, err := detector.DetectFiles(tt.source) + if err != nil { + t.Error(err) + } + + assert.ElementsMatch(t, tt.expectedFindings, findings) + } +} + +func moveDotGit(from, to string) error { + repoDirs, err := os.ReadDir("../testdata/repos") + if err != nil { + return err + } + for _, dir := range repoDirs { + if to == ".git" { + _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), "dotGit")) + if os.IsNotExist(err) { + // dont want to delete the only copy of .git accidentally + continue + } + os.RemoveAll(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), ".git")) + } + if !dir.IsDir() { + continue + } + _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from)) + if os.IsNotExist(err) { + continue + } + + err = os.Rename(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from), + fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), to)) + if err != nil { + return err + } + } + return nil +} diff --git a/detect/git/git.go b/detect/git/git.go new file mode 100644 index 000000000..944fd4925 --- /dev/null +++ b/detect/git/git.go @@ -0,0 +1,121 @@ +package git + +import ( + "bufio" + "io" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/rs/zerolog/log" +) + +var ErrEncountered bool + +// GitLog returns a channel of gitdiff.File objects from the +// git log -p command for the given source. +func GitLog(source string, logOpts string) (<-chan *gitdiff.File, error) { + sourceClean := filepath.Clean(source) + var cmd *exec.Cmd + if logOpts != "" { + args := []string{"-C", sourceClean, "log", "-p", "-U0"} + args = append(args, strings.Split(logOpts, " ")...) + cmd = exec.Command("git", args...) + } else { + cmd = exec.Command("git", "-C", sourceClean, "log", "-p", "-U0", + "--full-history", "--all") + } + + log.Debug().Msgf("executing: %s", cmd.String()) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + go listenForStdErr(stderr) + + if err := cmd.Start(); err != nil { + return nil, err + } + // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722 + time.Sleep(50 * time.Millisecond) + + return gitdiff.Parse(cmd, stdout) +} + +// GitDiff returns a channel of gitdiff.File objects from +// the git diff command for the given source. +func GitDiff(source string, staged bool) (<-chan *gitdiff.File, error) { + sourceClean := filepath.Clean(source) + var cmd *exec.Cmd + cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", ".") + if staged { + cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", + "--staged", ".") + } + log.Debug().Msgf("executing: %s", cmd.String()) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + go listenForStdErr(stderr) + + if err := cmd.Start(); err != nil { + return nil, err + } + // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722 + time.Sleep(50 * time.Millisecond) + + return gitdiff.Parse(cmd, stdout) +} + +// listenForStdErr listens for stderr output from git and prints it to stdout +// then exits with exit code 1 +func listenForStdErr(stderr io.ReadCloser) { + scanner := bufio.NewScanner(stderr) + for scanner.Scan() { + // if git throws one of the following errors: + // + // exhaustive rename detection was skipped due to too many files. + // you may want to set your diff.renameLimit variable to at least + // (some large number) and retry the command. + // + // inexact rename detection was skipped due to too many files. + // you may want to set your diff.renameLimit variable to at least + // (some large number) and retry the command. + // + // we skip exiting the program as git log -p/git diff will continue + // to send data to stdout and finish executing. This next bit of + // code prevents gitleaks from stopping mid scan if this error is + // encountered + if strings.Contains(scanner.Text(), + "exhaustive rename detection was skipped") || + strings.Contains(scanner.Text(), + "inexact rename detection was skipped") || + strings.Contains(scanner.Text(), + "you may want to set your diff.renameLimit") { + log.Warn().Msg(scanner.Text()) + } else { + log.Error().Msgf("[git] %s", scanner.Text()) + + // asynchronously set this error flag to true so that we can + // capture a log message and exit with a non-zero exit code + // This value should get set before the `git` command exits so it's + // safe-ish, although I know I know, bad practice. + ErrEncountered = true + } + } +} diff --git a/detect/git/git_test.go b/detect/git/git_test.go new file mode 100644 index 000000000..3a2ea9c35 --- /dev/null +++ b/detect/git/git_test.go @@ -0,0 +1,158 @@ +package git_test + +// TODO: commenting out this test for now because it's flaky. Alternatives to consider to get this working: +// -- use `git stash` instead of `restore()` + +// const repoBasePath = "../../testdata/repos/" + +// const expectPath = "../../testdata/expected/" + +// func TestGitLog(t *testing.T) { +// tests := []struct { +// source string +// logOpts string +// expected string +// }{ +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: filepath.Join(expectPath, "git", "small.txt"), +// }, +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: filepath.Join(expectPath, "git", "small-branch-foo.txt"), +// logOpts: "--all foo...", +// }, +// } + +// err := moveDotGit("dotGit", ".git") +// if err != nil { +// t.Fatal(err) +// } +// defer func() { +// if err = moveDotGit(".git", "dotGit"); err != nil { +// t.Fatal(err) +// } +// }() + +// for _, tt := range tests { +// files, err := git.GitLog(tt.source, tt.logOpts) +// if err != nil { +// t.Error(err) +// } + +// var diffSb strings.Builder +// for f := range files { +// for _, tf := range f.TextFragments { +// diffSb.WriteString(tf.Raw(gitdiff.OpAdd)) +// } +// } + +// expectedBytes, err := os.ReadFile(tt.expected) +// if err != nil { +// t.Error(err) +// } +// expected := string(expectedBytes) +// if expected != diffSb.String() { +// // write string builder to .got file using os.Create +// err = os.WriteFile(strings.Replace(tt.expected, ".txt", ".got.txt", 1), []byte(diffSb.String()), 0644) +// if err != nil { +// t.Error(err) +// } +// t.Error("expected: ", expected, "got: ", diffSb.String()) +// } +// } +// } + +// func TestGitDiff(t *testing.T) { +// tests := []struct { +// source string +// expected string +// additions string +// target string +// }{ +// { +// source: filepath.Join(repoBasePath, "small"), +// expected: "this line is added\nand another one", +// additions: "this line is added\nand another one", +// target: filepath.Join(repoBasePath, "small", "main.go"), +// }, +// } + +// err := moveDotGit("dotGit", ".git") +// if err != nil { +// t.Fatal(err) +// } +// defer func() { +// if err = moveDotGit(".git", "dotGit"); err != nil { +// t.Fatal(err) +// } +// }() + +// for _, tt := range tests { +// noChanges, err := os.ReadFile(tt.target) +// if err != nil { +// t.Error(err) +// } +// err = os.WriteFile(tt.target, []byte(tt.additions), 0644) +// if err != nil { +// restore(tt.target, noChanges, t) +// t.Error(err) +// } + +// files, err := git.GitDiff(tt.source, false) +// if err != nil { +// restore(tt.target, noChanges, t) +// t.Error(err) +// } + +// for f := range files { +// sb := strings.Builder{} +// for _, tf := range f.TextFragments { +// sb.WriteString(tf.Raw(gitdiff.OpAdd)) +// } +// if sb.String() != tt.expected { +// restore(tt.target, noChanges, t) +// t.Error("expected: ", tt.expected, "got: ", sb.String()) +// } +// } +// restore(tt.target, noChanges, t) +// } +// } + +// func restore(path string, data []byte, t *testing.T) { +// err := os.WriteFile(path, data, 0644) +// if err != nil { +// t.Fatal(err) +// } +// } + +// func moveDotGit(from, to string) error { +// repoDirs, err := os.ReadDir("../../testdata/repos") +// if err != nil { +// return err +// } +// for _, dir := range repoDirs { +// if to == ".git" { +// _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), "dotGit")) +// if os.IsNotExist(err) { +// // dont want to delete the only copy of .git accidentally +// continue +// } +// os.RemoveAll(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), ".git")) +// } +// if !dir.IsDir() { +// continue +// } +// _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from)) +// if os.IsNotExist(err) { +// continue +// } + +// err = os.Rename(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from), +// fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), to)) +// if err != nil { +// return err +// } +// } +// return nil +// } diff --git a/detect/location.go b/detect/location.go new file mode 100644 index 000000000..ac94d4159 --- /dev/null +++ b/detect/location.go @@ -0,0 +1,69 @@ +package detect + +// Location represents a location in a file +type Location struct { + startLine int + endLine int + startColumn int + endColumn int + startLineIndex int + endLineIndex int +} + +func location(fragment Fragment, matchIndex []int) Location { + var ( + prevNewLine int + location Location + lineSet bool + _lineNum int + ) + + start := matchIndex[0] + end := matchIndex[1] + + // default startLineIndex to 0 + location.startLineIndex = 0 + + for lineNum, pair := range fragment.newlineIndices { + _lineNum = lineNum + newLineByteIndex := pair[0] + if prevNewLine <= start && start < newLineByteIndex { + lineSet = true + location.startLine = lineNum + location.endLine = lineNum + location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1 + location.startLineIndex = prevNewLine + location.endLineIndex = newLineByteIndex + } + if prevNewLine < end && end <= newLineByteIndex { + location.endLine = lineNum + location.endColumn = (end - prevNewLine) + location.endLineIndex = newLineByteIndex + } + prevNewLine = pair[0] + } + + if !lineSet { + // if lines never get set then that means the secret is most likely + // on the last line of the diff output and the diff output does not have + // a newline + location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1 + location.endColumn = (end - prevNewLine) + location.startLine = _lineNum + 1 + location.endLine = _lineNum + 1 + + // search for new line byte index + i := 0 + for end+i < len(fragment.Raw) { + if fragment.Raw[end+i] == '\n' { + break + } + if fragment.Raw[end+i] == '\r' { + break + } + i++ + } + location.endLineIndex = end + i + } + return location +} diff --git a/detect/location_test.go b/detect/location_test.go new file mode 100644 index 000000000..d8c1a58c5 --- /dev/null +++ b/detect/location_test.go @@ -0,0 +1,60 @@ +package detect + +import ( + "testing" +) + +// TestGetLocation tests the getLocation function. +func TestGetLocation(t *testing.T) { + tests := []struct { + linePairs [][]int + start int + end int + wantLocation Location + }{ + { + linePairs: [][]int{ + {0, 39}, + {40, 55}, + {56, 57}, + }, + start: 35, + end: 38, + wantLocation: Location{ + startLine: 1, + startColumn: 36, + endLine: 1, + endColumn: 38, + startLineIndex: 0, + endLineIndex: 40, + }, + }, + { + linePairs: [][]int{ + {0, 39}, + {40, 55}, + {56, 57}, + }, + start: 40, + end: 44, + wantLocation: Location{ + startLine: 2, + startColumn: 1, + endLine: 2, + endColumn: 4, + startLineIndex: 40, + endLineIndex: 56, + }, + }, + } + + for _, test := range tests { + loc := location(Fragment{newlineIndices: test.linePairs}, []int{test.start, test.end}) + if loc != test.wantLocation { + t.Errorf("\nstartLine %d\nstartColumn: %d\nendLine: %d\nendColumn: %d\nstartLineIndex: %d\nendlineIndex %d", + loc.startLine, loc.startColumn, loc.endLine, loc.endColumn, loc.startLineIndex, loc.endLineIndex) + + t.Error("got", loc, "want", test.wantLocation) + } + } +} diff --git a/detect/utils.go b/detect/utils.go new file mode 100644 index 000000000..bea893f54 --- /dev/null +++ b/detect/utils.go @@ -0,0 +1,158 @@ +package detect + +import ( + // "encoding/json" + "fmt" + "math" + "strings" + "time" + + "github.com/charmbracelet/lipgloss" + + "github.com/zricethezav/gitleaks/v8/report" + + "github.com/gitleaks/go-gitdiff/gitdiff" + "github.com/rs/zerolog/log" +) + +// augmentGitFinding updates the start and end line numbers of a finding to include the +// delta from the git diff +func augmentGitFinding(finding report.Finding, textFragment *gitdiff.TextFragment, f *gitdiff.File) report.Finding { + if !strings.HasPrefix(finding.Match, "file detected") { + finding.StartLine += int(textFragment.NewPosition) + finding.EndLine += int(textFragment.NewPosition) + } + + if f.PatchHeader != nil { + finding.Commit = f.PatchHeader.SHA + finding.Message = f.PatchHeader.Message() + if f.PatchHeader.Author != nil { + finding.Author = f.PatchHeader.Author.Name + finding.Email = f.PatchHeader.Author.Email + } + finding.Date = f.PatchHeader.AuthorDate.UTC().Format(time.RFC3339) + } + return finding +} + +// shannonEntropy calculates the entropy of data using the formula defined here: +// https://en.wiktionary.org/wiki/Shannon_entropy +// Another way to think about what this is doing is calculating the number of bits +// needed to on average encode the data. So, the higher the entropy, the more random the data, the +// more bits needed to encode that data. +func shannonEntropy(data string) (entropy float64) { + if data == "" { + return 0 + } + + charCounts := make(map[rune]int) + for _, char := range data { + charCounts[char]++ + } + + invLength := 1.0 / float64(len(data)) + for _, count := range charCounts { + freq := float64(count) * invLength + entropy -= freq * math.Log2(freq) + } + + return entropy +} + +// filter will dedupe and redact findings +func filter(findings []report.Finding, redact bool) []report.Finding { + var retFindings []report.Finding + for _, f := range findings { + include := true + if strings.Contains(strings.ToLower(f.RuleID), "generic") { + for _, fPrime := range findings { + if f.StartLine == fPrime.StartLine && + f.Commit == fPrime.Commit && + f.RuleID != fPrime.RuleID && + strings.Contains(fPrime.Secret, f.Secret) && + !strings.Contains(strings.ToLower(fPrime.RuleID), "generic") { + + genericMatch := strings.Replace(f.Match, f.Secret, "REDACTED", -1) + betterMatch := strings.Replace(fPrime.Match, fPrime.Secret, "REDACTED", -1) + log.Trace().Msgf("skipping %s finding (%s), %s rule takes precendence (%s)", f.RuleID, genericMatch, fPrime.RuleID, betterMatch) + include = false + break + } + } + } + + if redact { + f.Redact() + } + if include { + retFindings = append(retFindings, f) + } + } + return retFindings +} + +func printFinding(f report.Finding) { + // trim all whitespace and tabs from the line + f.Line = strings.TrimSpace(f.Line) + // trim all whitespace and tabs from the secret + f.Secret = strings.TrimSpace(f.Secret) + // trim all whitespace and tabs from the match + f.Match = strings.TrimSpace(f.Match) + + matchInLineIDX := strings.Index(f.Line, f.Match) + secretInMatchIdx := strings.Index(f.Match, f.Secret) + + start := f.Line[0:matchInLineIDX] + startMatchIdx := 0 + if matchInLineIDX > 20 { + startMatchIdx = matchInLineIDX - 20 + start = "..." + f.Line[startMatchIdx:matchInLineIDX] + } + + matchBeginning := lipgloss.NewStyle().SetString(f.Match[0:secretInMatchIdx]).Foreground(lipgloss.Color("#f5d445")) + secret := lipgloss.NewStyle().SetString(f.Secret). + Bold(true). + Italic(true). + Foreground(lipgloss.Color("#f05c07")) + matchEnd := lipgloss.NewStyle().SetString(f.Match[secretInMatchIdx+len(f.Secret):]).Foreground(lipgloss.Color("#f5d445")) + lineEnd := f.Line[matchInLineIDX+len(f.Match):] + if len(f.Secret) > 100 { + secret = lipgloss.NewStyle().SetString(f.Secret[0:100] + "..."). + Bold(true). + Italic(true). + Foreground(lipgloss.Color("#f05c07")) + } + if len(lineEnd) > 20 { + lineEnd = lineEnd[0:20] + "..." + } + + finding := fmt.Sprintf("%s%s%s%s%s\n", strings.TrimPrefix(strings.TrimLeft(start, " "), "\n"), matchBeginning, secret, matchEnd, lineEnd) + fmt.Printf("%-12s %s", "Finding:", finding) + fmt.Printf("%-12s %s\n", "Secret:", secret) + fmt.Printf("%-12s %s\n", "RuleID:", f.RuleID) + fmt.Printf("%-12s %f\n", "Entropy:", f.Entropy) + fmt.Printf("%-12s %s\n", "File:", f.File) + fmt.Printf("%-12s %d\n", "Line:", f.StartLine) + if f.Commit == "" { + fmt.Printf("%-12s %s\n", "Fingerprint:", f.Fingerprint) + fmt.Println("") + return + } + fmt.Printf("%-12s %s\n", "Commit:", f.Commit) + fmt.Printf("%-12s %s\n", "Author:", f.Author) + fmt.Printf("%-12s %s\n", "Email:", f.Email) + fmt.Printf("%-12s %s\n", "Date:", f.Date) + fmt.Printf("%-12s %s\n", "Fingerprint:", f.Fingerprint) + fmt.Println("") +} + +func containsDigit(s string) bool { + for _, c := range s { + switch c { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return true + } + + } + return false +} diff --git a/examples/leaky-repo.toml b/examples/leaky-repo.toml deleted file mode 100644 index 62ef4d2d3..000000000 --- a/examples/leaky-repo.toml +++ /dev/null @@ -1,195 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS cred file info" - regex = '''(?i)(aws_access_key_id|aws_secret_access_key)(.{0,20})?=.[0-9a-zA-Z\/+]{20,40}''' - tags = ["AWS"] - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "Env Var" - regex = '''(?i)(apikey|secret|key|api|password|pass|pw|host)=[0-9a-zA-Z-_.{}]{4,120}''' - -[[rules]] - description = "Port" - regex = '''(?i)port(.{0,4})?[0-9]{1,10}''' - [rules.allowlist] - regexes = ['''(?i)port '''] - description = "ignore export " - - - -[[rules]] - description = "Email" - regex = '''[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}''' - tags = ["email"] - [rules.allowlist] - files = ['''(?i)bashrc'''] - description = "ignore bashrc emails" - - -[[rules]] - description = "Generic Credential" - regex = '''(?i)(dbpasswd|dbuser|dbname|dbhost|api_key|apikey|secret|key|api|password|user|guid|hostname|pw|auth)(.{0,20})?['|"]([0-9a-zA-Z-_\/+!{}/=]{4,120})['|"]''' - tags = ["key", "API", "generic"] - # ignore leaks with specific identifiers like slack and aws - [rules.allowlist] - description = "ignore slack, mailchimp, aws" - regexes = [ - '''xox[baprs]-([0-9a-zA-Z]{10,48})''', - '''(?i)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''', - '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - ] - -[[rules]] - description = "High Entropy" - regex = '''[0-9a-zA-Z-_!{}/=]{4,120}''' - file = '''(?i)(dump.sql|high-entropy-misc.txt)$''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "7.0" - [rules.allowlist] - description = "ignore ssh key and pems" - files = ['''(pem|ppk|env)$'''] - paths = ['''(.*)?ssh'''] - -[[rules]] - description = "Potential bash var" - regex='''(?i)(=)([0-9a-zA-Z-_!{}=]{4,120})''' - tags = ["key", "bash", "API", "generic"] - [[rules.Entropies]] - Min = "3.5" - Max = "4.5" - Group = "1" - -[[rules]] - description = "WP-Config" - regex='''define(.{0,20})?(DB_CHARSET|NONCE_SALT|LOGGED_IN_SALT|AUTH_SALT|NONCE_KEY|DB_HOST|DB_PASSWORD|AUTH_KEY|SECURE_AUTH_KEY|LOGGED_IN_KEY|DB_NAME|DB_USER)(.{0,20})?['|"].{10,120}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Files with keys and credentials" - file = '''(?i)(id_rsa|passwd|id_rsa.pub|pgpass|pem|key|shadow)''' - -# Global allowlist -[allowlist] - description = "image allowlists" - files = ['''(.*?)(jpg|gif|doc|pdf|bin)$'''] - diff --git a/examples/pre-commit.example b/examples/pre-commit.example deleted file mode 100644 index 005fae352..000000000 --- a/examples/pre-commit.example +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# This is an example of what adding gitleaks to a pre-commit hook would look like. - -gitleaksEnabled=$(git config --bool hooks.gitleaks) -cmd="/Users/zrice/go/src/github.com/zricethezav/gitleaks/gitleaks --verbose --redact --pretty" -if [ $gitleaksEnabled == "true" ]; then - $cmd - if [ $? -eq 1 ]; then -cat <<\EOF -Error: gitleaks has detected sensitive information in your changes. -If you know what you are doing you can disable this check using: - - git config hooks.gitleaks false - -EOF -exit 1 - fi -fi diff --git a/examples/regex_and_entropy_config.toml b/examples/regex_and_entropy_config.toml deleted file mode 100644 index c8718fa84..000000000 --- a/examples/regex_and_entropy_config.toml +++ /dev/null @@ -1,17 +0,0 @@ -# This config contains a single rule which defines a regex and a range of entropy values. If a rule has -# both regex and entropy then that rule uses BOTH the regex and entropy in combination when performing an scan. -# In other words, if a line of code has an entropy value that is within the range of the entropies defined and -# a regex match is found then that line of code contains a leak. - -# So, for this example if a line of code has an entropy value of 4.6 AND matches the regex below then we got a leak. - -[[rules]] - description = "entropy and regex" - regex = '''(?i)key(.{0,20})?['|"][0-9a-zA-Z]{16,45}['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "5.7" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" diff --git a/examples/simple_regex_and_allowlist_config.toml b/examples/simple_regex_and_allowlist_config.toml deleted file mode 100644 index e99eb49cc..000000000 --- a/examples/simple_regex_and_allowlist_config.toml +++ /dev/null @@ -1,13 +0,0 @@ -# This config contains a single rule that checks for AWS keys. However, it also contains a allowlist table -# where you can define one or more allowlists. What this means is that if you have an example AWS key as part of your -# code (in a test for example), then you can allowlist that specific key so gitleaks will not label it as a leak. -# If this line was present in a git history: `aws_access_key_id='AKIAIO5FODNN7EXAMPLE``, gitleaks would match this line -# with the rule below, but since we have a allowlist against that specific key, it would be ignored. - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - regexes = ['''AKIAIO5FODNN7EXAMPLE.*'''] - description = "ignore example aws key" diff --git a/examples/simple_regex_config.toml b/examples/simple_regex_config.toml deleted file mode 100644 index 1c167a737..000000000 --- a/examples/simple_regex_config.toml +++ /dev/null @@ -1,6 +0,0 @@ -# This is a simple gitleaks config that contains one rule which checks for AWS keys. - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/go.mod b/go.mod index 04d5600d2..036d897f1 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,47 @@ -module github.com/zricethezav/gitleaks/v6 +module github.com/zricethezav/gitleaks/v8 -go 1.14 +go 1.19 require ( - github.com/BurntSushi/toml v0.3.1 - github.com/go-git/go-billy/v5 v5.0.0 - github.com/go-git/go-git/v5 v5.1.0 - github.com/google/go-cmp v0.4.0 // indirect - github.com/google/go-github/v31 v31.0.0 - github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 - github.com/jessevdk/go-flags v1.4.0 - github.com/mattn/go-colorable v0.1.2 - github.com/sergi/go-diff v1.1.0 - github.com/sirupsen/logrus v1.4.2 - github.com/xanzy/go-gitlab v0.21.0 - golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + github.com/charmbracelet/lipgloss v0.5.0 + github.com/fatih/semgroup v1.2.0 + github.com/gitleaks/go-gitdiff v0.8.0 + github.com/h2non/filetype v1.1.3 + github.com/rs/zerolog v1.26.1 + github.com/spf13/cobra v1.2.1 + github.com/spf13/viper v1.8.1 + github.com/stretchr/testify v1.7.0 +) + +require ( + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect + github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb + github.com/magiconair/properties v1.8.5 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index e86abebe3..ad57b30f6 100644 --- a/go.sum +++ b/go.sum @@ -1,127 +1,631 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= -github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= -github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/semgroup v1.2.0 h1:h/OLXwEM+3NNyAdZEpMiH1OzfplU09i2qXPVThGZvyg= +github.com/fatih/semgroup v1.2.0/go.mod h1:1KAD4iIYfXjE4U13B48VM4z9QUwV5Tt8O4rS879kgm8= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gitleaks/go-gitdiff v0.8.0 h1:7aExTZm+K/M/EQKOyYcub8rIAdWK6ONxPGuRzxmWW+0= +github.com/gitleaks/go-gitdiff v0.8.0/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= -github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw= -github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= +github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb h1:w1g9wNDIE/pHSTmAaUhv4TZQuPBS6GV3mMz5hkgziIU= +github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8= +github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/xanzy/go-gitlab v0.21.0 h1:Ru55sR4TBoDNsAKwCOpzeaGtbiWj7xTksVmzBJbLu6c= -github.com/xanzy/go-gitlab v0.21.0/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ= +golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/hosts/github.go b/hosts/github.go deleted file mode 100644 index 9330b8243..000000000 --- a/hosts/github.go +++ /dev/null @@ -1,190 +0,0 @@ -package hosts - -import ( - "context" - "strconv" - "strings" - "sync" - - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/google/go-github/v31/github" - log "github.com/sirupsen/logrus" - "golang.org/x/oauth2" -) - -// Github wraps a github client and manager. This struct implements what the Host interface defines. -type Github struct { - client *github.Client - manager *manager.Manager - wg sync.WaitGroup -} - -// NewGithubClient accepts a manager struct and returns a Github host pointer which will be used to -// perform a github scan on an organization, user, or PR. -func NewGithubClient(m *manager.Manager) (*Github, error) { - var err error - ctx := context.Background() - token := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: options.GetAccessToken(m.Opts)}, - ) - - var githubClient *github.Client - httpClient := oauth2.NewClient(ctx, token) - - if m.Opts.BaseURL == "" { - githubClient = github.NewClient(httpClient) - } else { - githubClient, err = github.NewEnterpriseClient(m.Opts.BaseURL, m.Opts.BaseURL, httpClient) - } - - return &Github{ - manager: m, - client: githubClient, - }, err -} - -// Scan will scan a github user or organization's repos. -func (g *Github) Scan() { - ctx := context.Background() - listOptions := github.ListOptions{ - PerPage: 100, - Page: 1, - } - - var ( - githubRepos []*github.Repository - auth transport.AuthMethod - ) - - for { - var ( - _githubRepos []*github.Repository - resp *github.Response - err error - ) - if g.manager.Opts.User != "" { - _githubRepos, resp, err = g.client.Repositories.List(ctx, g.manager.Opts.User, - &github.RepositoryListOptions{ListOptions: listOptions}) - } else if g.manager.Opts.Organization != "" { - _githubRepos, resp, err = g.client.Repositories.ListByOrg(ctx, g.manager.Opts.Organization, - &github.RepositoryListByOrgOptions{ListOptions: listOptions}) - } else { - _githubRepos, resp, err = g.client.Repositories.List(ctx, "", - &github.RepositoryListOptions{ListOptions: listOptions}) - } - - for _, r := range _githubRepos { - if g.manager.Opts.ExcludeForks && r.GetFork() { - log.Debugf("excluding forked repo: %s", *r.Name) - continue - } - githubRepos = append(githubRepos, r) - } - - if resp == nil { - break - } - - if resp.LastPage != 0 { - log.Infof("gathering github repos... progress: page %d of %d", listOptions.Page, resp.LastPage) - } else { - log.Infof("gathering github repos... progress: page %d of %d", listOptions.Page, listOptions.Page) - } - - listOptions.Page = resp.NextPage - if err != nil || listOptions.Page == 0 { - break - } - } - - for _, repo := range githubRepos { - r := scan.NewRepo(g.manager) - - if g.manager.CloneOptions != nil { - auth = g.manager.CloneOptions.Auth - } - err := r.Clone(&git.CloneOptions{ - URL: *repo.CloneURL, - Auth: auth, - }) - r.Name = *repo.Name - if err != nil { - log.Warn("unable to clone via https and access token, attempting with ssh now") - auth, err := options.SSHAuth(g.manager.Opts) - if err != nil { - log.Warnf("unable to get ssh auth, skipping clone and scan for repo %s: %+v\n", *repo.CloneURL, err) - continue - } - err = r.Clone(&git.CloneOptions{ - URL: *repo.SSHURL, - Auth: auth, - }) - if err != nil { - log.Warnf("err cloning %s, skipping clone and scan: %+v\n", *repo.SSHURL, err) - continue - } - } - if err = r.Scan(); err != nil { - log.Warn(err) - } - } -} - -// ScanPR scan a single github PR -func (g *Github) ScanPR() { - ctx := context.Background() - splits := strings.Split(g.manager.Opts.PullRequest, "/") - owner := splits[len(splits)-4] - repoName := splits[len(splits)-3] - prNum, err := strconv.Atoi(splits[len(splits)-1]) - repo := scan.NewRepo(g.manager) - repo.Name = repoName - log.Infof("scanning pr %s\n", g.manager.Opts.PullRequest) - - if err != nil { - return - } - page := 1 - for { - commits, resp, err := g.client.PullRequests.ListCommits(ctx, owner, repoName, prNum, &github.ListOptions{ - PerPage: 100, Page: page}) - if err != nil { - return - } - for _, c := range commits { - c, _, err := g.client.Repositories.GetCommit(ctx, owner, repo.Name, *c.SHA) - if err != nil { - continue - } - commitObj := object.Commit{ - Hash: plumbing.NewHash(*c.SHA), - Author: object.Signature{ - Name: *c.Commit.Author.Name, - Email: *c.Commit.Author.Email, - When: *c.Commit.Author.Date, - }, - } - for _, f := range c.Files { - if f.Patch == nil { - continue - } - repo.CheckRules(&scan.Bundle{ - Content: *f.Patch, - FilePath: *f.Filename, - Commit: &commitObj, - }) - } - } - page = resp.NextPage - if resp.LastPage == 0 { - break - } - } -} diff --git a/hosts/gitlab.go b/hosts/gitlab.go deleted file mode 100644 index c4b003652..000000000 --- a/hosts/gitlab.go +++ /dev/null @@ -1,112 +0,0 @@ -package hosts - -import ( - "context" - "sync" - - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - log "github.com/sirupsen/logrus" - "github.com/xanzy/go-gitlab" -) - -// Gitlab wraps a gitlab client and manager. This struct implements what the Host interface defines. -type Gitlab struct { - client *gitlab.Client - manager *manager.Manager - ctx context.Context - wg sync.WaitGroup -} - -// NewGitlabClient accepts a manager struct and returns a Gitlab host pointer which will be used to -// perform a gitlab scan on an group or user. -func NewGitlabClient(m *manager.Manager) (*Gitlab, error) { - var err error - - gitlabClient := &Gitlab{ - manager: m, - ctx: context.Background(), - client: gitlab.NewClient(nil, options.GetAccessToken(m.Opts)), - } - - if m.Opts.BaseURL != "" { - err = gitlabClient.client.SetBaseURL(m.Opts.BaseURL) - } - - return gitlabClient, err -} - -// Scan will scan a github user or organization's repos. -func (g *Gitlab) Scan() { - var ( - projects []*gitlab.Project - resp *gitlab.Response - err error - ) - - page := 1 - listOpts := gitlab.ListOptions{ - PerPage: 100, - Page: page, - } - for { - var _projects []*gitlab.Project - if g.manager.Opts.User != "" { - glOpts := &gitlab.ListProjectsOptions{ - ListOptions: listOpts, - } - _projects, resp, err = g.client.Projects.ListUserProjects(g.manager.Opts.User, glOpts) - - } else if g.manager.Opts.Organization != "" { - glOpts := &gitlab.ListGroupProjectsOptions{ - ListOptions: listOpts, - } - _projects, resp, err = g.client.Groups.ListGroupProjects(g.manager.Opts.Organization, glOpts) - } - if err != nil { - log.Error(err) - } - - for _, p := range _projects { - if g.manager.Opts.ExcludeForks && p.ForkedFromProject != nil { - log.Debugf("excluding forked repo: %s", p.Name) - continue - } - projects = append(projects, p) - } - - if resp == nil { - break - } - if page >= resp.TotalPages { - // exit when we've seen all pages - break - } - page = resp.NextPage - } - - // iterate of gitlab projects - for _, p := range projects { - r := scan.NewRepo(g.manager) - cloneOpts := g.manager.CloneOptions - cloneOpts.URL = p.HTTPURLToRepo - err := r.Clone(cloneOpts) - if err != nil { - log.Error(err) - continue - } - // TODO handle clone retry with ssh like github host - r.Name = p.Name - - if err = r.Scan(); err != nil { - log.Error(err) - } - } -} - -// ScanPR TODO not implemented -func (g *Gitlab) ScanPR() { - log.Error("ScanPR is not implemented in Gitlab host yet...") -} diff --git a/hosts/host.go b/hosts/host.go deleted file mode 100644 index 3c03e4783..000000000 --- a/hosts/host.go +++ /dev/null @@ -1,53 +0,0 @@ -package hosts - -import ( - "strings" - - "github.com/zricethezav/gitleaks/v6/manager" -) - -const ( - _github int = iota + 1 - _gitlab -) - -// Host is an interface used for defining external git hosting providers like github and gitlab. -// TODO add bitbucket -type Host interface { - Scan() - ScanPR() -} - -// Run kicks off a host scan. This function accepts a manager and determines what host it should scan -func Run(m *manager.Manager) error { - var host Host - var err error - switch getHost(m.Opts.Host) { - case _github: - host, err = NewGithubClient(m) - case _gitlab: - host, err = NewGitlabClient(m) - default: - return nil - } - - if err != nil { - return err - } - - if m.Opts.PullRequest != "" { - host.ScanPR() - } else { - host.Scan() - } - return err -} - -func getHost(host string) int { - if strings.ToLower(host) == "github" { - return _github - } else if strings.ToLower(host) == "gitlab" { - return _gitlab - } - return -1 -} diff --git a/hosts/hosts_test.go b/hosts/hosts_test.go deleted file mode 100644 index c39389e47..000000000 --- a/hosts/hosts_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package hosts - -import ( - "flag" - "fmt" - "os" - "testing" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" -) - -var ( - integration = flag.Bool("integration", false, "run github/gitlab integration test") -) - -func TestGithub(t *testing.T) { - flag.Parse() - if !*integration { - fmt.Println("skipping github integration tests") - return - } - if os.Getenv("GITHUB_TOKEN") == "" { - t.Log("skipping github integration tests, need env var GITLAB_TOKEN") - return - } - - tests := []struct { - opts options.Options - desiredLeaks int - }{ - { - opts: options.Options{ - Host: "github", - User: "gitleakstest", - AccessToken: os.Getenv("GITHUB_TOKEN"), - }, - desiredLeaks: 2, - }, - { - opts: options.Options{ - Host: "github", - PullRequest: "https://github.com/gitleakstest/gronit/pull/1", - AccessToken: os.Getenv("GITHUB_TOKEN"), - }, - desiredLeaks: 4, - }, - } - - for _, test := range tests { - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - err = Run(m) - if err != nil { - t.Fatal(err) - } - - if test.desiredLeaks != len(m.GetLeaks()) { - t.Errorf("got %d leaks, want %d", len(m.GetLeaks()), test.desiredLeaks) - } - } -} - -func TestGitlab(t *testing.T) { - flag.Parse() - if !*integration { - fmt.Println("skipping gitlab integration tests") - return - } - if os.Getenv("GITLAB_TOKEN") == "" { - t.Log("skipping github integration tests, need env var GITLAB_TOKEN") - return - } - - tests := []struct { - opts options.Options - desiredLeaks int - }{ - { - opts: options.Options{ - Host: "gitlab", - User: "gitleakstest", - AccessToken: os.Getenv("GITLAB_TOKEN"), - }, - desiredLeaks: 2, - }, - } - - for _, test := range tests { - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - err = Run(m) - if err != nil { - t.Fatal(err) - } - - if test.desiredLeaks != len(m.GetLeaks()) { - t.Errorf("got %d leaks, want %d", len(m.GetLeaks()), test.desiredLeaks) - } - } -} diff --git a/main.go b/main.go index de1fcbeb1..3a7cf2e0e 100644 --- a/main.go +++ b/main.go @@ -1,97 +1,28 @@ package main import ( - "io/ioutil" "os" - "time" + "os/signal" - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/hosts" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - "github.com/zricethezav/gitleaks/v6/scan" - - "github.com/hako/durafmt" - log "github.com/sirupsen/logrus" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/zricethezav/gitleaks/v8/cmd" ) func main() { - opts, err := options.ParseOptions() - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - err = opts.Guard() - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - cfg, err := config.NewConfig(opts) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } - - m, err := manager.NewManager(opts, cfg) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } + // send all logs to stdout + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) - err = Run(m) - if err != nil { - log.Error(err) - os.Exit(options.ErrorEncountered) - } + // this block sets up a go routine to listen for an interrupt signal + // which will immediately exit gitleaks + stopChan := make(chan os.Signal, 1) + signal.Notify(stopChan, os.Interrupt) + go listenForInterrupt(stopChan) - leaks := m.GetLeaks() - metadata := m.GetMetadata() - - if len(m.GetLeaks()) != 0 { - if m.Opts.CheckUncommitted() { - log.Warnf("%d leaks detected in staged changes", len(leaks)) - } else { - log.Warnf("%d leaks detected. %d commits scanned in %s", len(leaks), - metadata.Commits, durafmt.Parse(time.Duration(metadata.ScanTime)*time.Nanosecond)) - } - os.Exit(options.LeaksPresent) - } else { - if m.Opts.CheckUncommitted() { - log.Infof("No leaks detected in staged changes") - } else { - log.Infof("No leaks detected. %d commits scanned in %s", - metadata.Commits, durafmt.Parse(time.Duration(metadata.ScanTime)*time.Nanosecond)) - } - os.Exit(options.Success) - } + cmd.Execute() } -// Run begins the program and contains some basic logic on how to continue with the scan. If any external git host -// options are set (like scanning a gitlab or github user) then a specific host client will be created and -// then Scan() and Report() will be called. Otherwise, gitleaks will create a new repo and an scan will proceed. -// If no options or the uncommitted option is set then a pre-commit scan will -// take place -- this is similar to running `git diff` on all the tracked files. -func Run(m *manager.Manager) error { - if m.Opts.Disk { - dir, err := ioutil.TempDir("", "gitleaks") - defer os.RemoveAll(dir) - if err != nil { - return err - } - m.CloneDir = dir - } - - var err error - if m.Opts.Host != "" { - err = hosts.Run(m) - } else { - err = scan.Run(m) - } - if err != nil { - return err - } - - return m.Report() +func listenForInterrupt(stopScan chan os.Signal) { + <-stopScan + log.Fatal().Msg("Interrupt signal received. Exiting...") } diff --git a/manager/manager.go b/manager/manager.go deleted file mode 100644 index a20177d88..000000000 --- a/manager/manager.go +++ /dev/null @@ -1,274 +0,0 @@ -package manager - -import ( - "crypto/sha1" - "encoding/hex" - "encoding/json" - "fmt" - "os" - "os/signal" - "runtime" - "strings" - "sync" - "text/tabwriter" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/go-git/go-git/v5" - "github.com/hako/durafmt" - "github.com/mattn/go-colorable" - log "github.com/sirupsen/logrus" -) - -const maxLineLen = 200 - -// Manager is a struct containing options and configs as well CloneOptions and CloneDir. -// This struct is passed into each NewRepo so we are not passing around the manager in func params. -type Manager struct { - Opts options.Options - Config config.Config - - CloneOptions *git.CloneOptions - CloneDir string - - leaks []Leak - leakChan chan Leak - leakWG *sync.WaitGroup - leakCache map[string]bool - - stopChan chan os.Signal - metadata Metadata - metaWG *sync.WaitGroup -} - -// Leak is a struct that contains information about some line of code that contains -// sensitive information as determined by the rules set in a gitleaks config -type Leak struct { - Line string `json:"line"` - LineNumber int `json:"lineNumber"` - Offender string `json:"offender"` - Commit string `json:"commit"` - Repo string `json:"repo"` - Rule string `json:"rule"` - Message string `json:"commitMessage"` - Author string `json:"author"` - Email string `json:"email"` - File string `json:"file"` - Date time.Time `json:"date"` - Tags string `json:"tags"` - Operation string `json:"operation"` - lookupHash string -} - -// ScanTime is a type used to determine total scan time -type ScanTime int64 - -// PatchTime is a type used to determine total patch time during an scan -type PatchTime int64 - -// CloneTime is a type used to determine total clone time -type CloneTime int64 - -// RegexTime is a type used to determine the time each rules' regex takes. This is especially useful -// if you notice that gitleaks is taking a long time. You can use --debug to see the output of the regexTime -// so you can determine which regex is not performing well. -type RegexTime struct { - Time int64 - Regex string -} - -// Metadata is a struct used to communicate metadata about an scan like timings and total commit counts. -type Metadata struct { - mux *sync.Mutex - data map[string]interface{} - - timings chan interface{} - - RegexTime map[string]int64 - Commits int - ScanTime int64 - patchTime int64 - cloneTime int64 -} - -func init() { - log.SetOutput(os.Stdout) - log.SetFormatter(&log.TextFormatter{ - ForceColors: true, - FullTimestamp: true, - }) - // Fix colors on Windows - if runtime.GOOS == "windows" { - log.SetOutput(colorable.NewColorableStdout()) - } -} - -// NewManager accepts options and returns a manager struct. The manager is a container for gitleaks configurations, -// options and channel receivers. -func NewManager(opts options.Options, cfg config.Config) (*Manager, error) { - cloneOpts, err := opts.CloneOptions() - if err != nil { - return nil, err - } - - m := &Manager{ - Opts: opts, - Config: cfg, - CloneOptions: cloneOpts, - - stopChan: make(chan os.Signal, 1), - leakChan: make(chan Leak), - leakWG: &sync.WaitGroup{}, - leakCache: make(map[string]bool), - metaWG: &sync.WaitGroup{}, - metadata: Metadata{ - RegexTime: make(map[string]int64), - timings: make(chan interface{}), - data: make(map[string]interface{}), - mux: new(sync.Mutex), - }, - } - - signal.Notify(m.stopChan, os.Interrupt) - - // start receiving leaks and metadata - go m.receiveLeaks() - go m.receiveMetadata() - go m.receiveInterrupt() - - return m, nil -} - -// GetLeaks returns all available leaks -func (manager *Manager) GetLeaks() []Leak { - // need to wait for any straggling leaks - manager.leakWG.Wait() - return manager.leaks -} - -// SendLeaks accepts a leak and is used by the scan pkg. This is the public function -// that allows other packages to send leaks to the manager. -func (manager *Manager) SendLeaks(l Leak) { - if len(l.Line) > maxLineLen { - l.Line = l.Line[0:maxLineLen-1] + "..." - } - if len(l.Offender) > maxLineLen { - l.Offender = l.Offender[0:maxLineLen-1] + "..." - } - h := sha1.New() - h.Write([]byte(l.Commit + l.Offender + l.File + l.Line + string(l.LineNumber))) - l.lookupHash = hex.EncodeToString(h.Sum(nil)) - if manager.Opts.Redact { - l.Line = strings.ReplaceAll(l.Line, l.Offender, "REDACTED") - l.Offender = "REDACTED" - } - manager.leakWG.Add(1) - manager.leakChan <- l -} - -func (manager *Manager) alreadySeen(leak Leak) bool { - if _, ok := manager.leakCache[leak.lookupHash]; ok { - return true - } - manager.leakCache[leak.lookupHash] = true - return false -} - -// receiveLeaks listens to leakChan for incoming leaks. If any are received, they are appended to the -// manager's leaks for future reporting. If the -v/--verbose option is set the leaks will marshaled into -// json and printed out. -func (manager *Manager) receiveLeaks() { - for leak := range manager.leakChan { - if manager.alreadySeen(leak) { - manager.leakWG.Done() - continue - } - manager.leaks = append(manager.leaks, leak) - if manager.Opts.Verbose { - var b []byte - if manager.Opts.PrettyPrint { - b, _ = json.MarshalIndent(leak, "", " ") - } else { - b, _ = json.Marshal(leak) - } - fmt.Println(string(b)) - } - manager.leakWG.Done() - } -} - -// GetMetadata returns the metadata. TODO this may not need to be private -func (manager *Manager) GetMetadata() Metadata { - manager.metaWG.Wait() - return manager.metadata -} - -// receiveMetadata is where the messages sent to the metadata channel get consumed. You can view metadata -// by running gitleaks with the --debug option set. This is extremely useful when trying to optimize regular -// expressions as that what gitleaks spends most of its cycles on. -func (manager *Manager) receiveMetadata() { - for t := range manager.metadata.timings { - switch ti := t.(type) { - case CloneTime: - manager.metadata.cloneTime += int64(ti) - case ScanTime: - manager.metadata.ScanTime += int64(ti) - case PatchTime: - manager.metadata.patchTime += int64(ti) - case RegexTime: - manager.metadata.RegexTime[ti.Regex] = manager.metadata.RegexTime[ti.Regex] + ti.Time - } - manager.metaWG.Done() - } -} - -// IncrementCommits increments total commits during an scan by i. -func (manager *Manager) IncrementCommits(i int) { - manager.metadata.mux.Lock() - manager.metadata.Commits += i - manager.metadata.mux.Unlock() -} - -// RecordTime accepts an interface and sends it to the manager's time channel -func (manager *Manager) RecordTime(t interface{}) { - manager.metaWG.Add(1) - manager.metadata.timings <- t -} - -// DebugOutput logs metadata and other messages that occurred during a gitleaks scan -func (manager *Manager) DebugOutput() { - log.Debugf("-------------------------\n") - log.Debugf("| Times and Commit Counts|\n") - log.Debugf("-------------------------\n") - fmt.Println("totalScanTime: ", durafmt.Parse(time.Duration(manager.metadata.ScanTime)*time.Nanosecond)) - fmt.Println("totalPatchTime: ", durafmt.Parse(time.Duration(manager.metadata.patchTime)*time.Nanosecond)) - fmt.Println("totalCloneTime: ", durafmt.Parse(time.Duration(manager.metadata.cloneTime)*time.Nanosecond)) - fmt.Println("totalCommits: ", manager.metadata.Commits) - - const padding = 6 - w := tabwriter.NewWriter(os.Stdout, 0, 0, padding, '.', 0) - - log.Debugf("--------------------------\n") - log.Debugf("| Individual Regexes Times |\n") - log.Debugf("--------------------------\n") - for k, v := range manager.metadata.RegexTime { - _, _ = fmt.Fprintf(w, "%s\t%s\n", k, durafmt.Parse(time.Duration(v)*time.Nanosecond)) - } - _ = w.Flush() - -} - - -func (manager *Manager) receiveInterrupt() { - <-manager.stopChan - if manager.Opts.Report != "" { - err := manager.Report() - if err != nil { - log.Error(err) - } - } - log.Info("gitleaks received interrupt, stopping scan") - os.Exit(options.ErrorEncountered) -} diff --git a/manager/manager_test.go b/manager/manager_test.go deleted file mode 100644 index 73613df06..000000000 --- a/manager/manager_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package manager - -import ( - "crypto/rand" - "fmt" - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/options" - "io" - "testing" -) - -// TODO -// add more substantial tests... but since literally every pkg uses manager -// these tests are kind of redundant -func TestSendReceiveLeaks(t *testing.T) { - - tests := []struct { - leaksToAdd int - goRoutines int - }{ - { - leaksToAdd: 10, - }, - { - leaksToAdd: 1000, - }, - } - for _, test := range tests { - opts := options.Options{} - cfg, _ := config.NewConfig(opts) - m, _ := NewManager(opts, cfg) - - for i := 0; i < test.leaksToAdd; i++ { - // we are testing the sync of sending/receiving leaks so we need - // the hash generation in sendLeaks to be unique for each iteration - // so I'm just setting the offender string as a uuid - m.SendLeaks(Leak{Offender: newUUID()}) - } - got := m.GetLeaks() - if len(got) != test.leaksToAdd { - t.Errorf("got %d, wanted %d leaks", len(got), test.leaksToAdd) - } - } -} - -func TestSendReceiveMeta(t *testing.T) { - tests := []struct { - scanTime int64 - patchTime int64 - cloneTime int64 - regexTime int64 - iterations int - }{ - { - scanTime: 1000, - patchTime: 1000, - cloneTime: 1000, - regexTime: 1000, - iterations: 100, - }, - } - for _, test := range tests { - opts := options.Options{} - cfg, _ := config.NewConfig(opts) - m, _ := NewManager(opts, cfg) - - for i := 0; i < test.iterations; i++ { - m.RecordTime(ScanTime(test.scanTime)) - m.RecordTime(PatchTime(test.patchTime)) - m.RecordTime(CloneTime(test.cloneTime)) - m.RecordTime(RegexTime{ - Regex: "regex", - Time: test.regexTime, - }) - m.RecordTime(RegexTime{ - Regex: "regex2", - Time: test.regexTime, - }) - } - md := m.GetMetadata() - if md.cloneTime != test.cloneTime*int64(test.iterations) { - t.Errorf("clone time mismatch, got %d, wanted %d", - md.cloneTime, test.cloneTime*int64(test.iterations)) - } - if md.ScanTime != test.scanTime*int64(test.iterations) { - t.Errorf("scan time mismatch, got %d, wanted %d", - md.ScanTime, test.scanTime*int64(test.iterations)) - } - if md.patchTime != test.patchTime*int64(test.iterations) { - t.Errorf("clone time mismatch, got %d, wanted %d", - md.patchTime, test.patchTime*int64(test.iterations)) - } - } -} - -// newUUID generates a random UUID according to RFC 4122 -// Ripped from https://play.golang.org/p/4FkNSiUDMg -func newUUID() string { - uuid := make([]byte, 16) - io.ReadFull(rand.Reader, uuid) - // variant bits; see section 4.1.1 - uuid[8] = uuid[8]&^0xc0 | 0x80 - // version 4 (pseudo-random); see section 4.1.3 - uuid[6] = uuid[6]&^0xf0 | 0x40 - return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]) -} diff --git a/manager/report.go b/manager/report.go deleted file mode 100644 index 2895ca7ef..000000000 --- a/manager/report.go +++ /dev/null @@ -1,78 +0,0 @@ -package manager - -import ( - "encoding/csv" - "encoding/json" - "os" - "time" - - "github.com/zricethezav/gitleaks/v6/version" - - log "github.com/sirupsen/logrus" -) - -// Report saves gitleaks leaks to a json specified by --report={report.json} -func (manager *Manager) Report() error { - close(manager.leakChan) - close(manager.metadata.timings) - - if log.IsLevelEnabled(log.DebugLevel) { - manager.DebugOutput() - } - - if manager.Opts.Report != "" { - if len(manager.GetLeaks()) == 0 { - log.Infof("no leaks found, skipping writing report") - return nil - } - file, err := os.Create(manager.Opts.Report) - if err != nil { - return err - } - - switch manager.Opts.ReportFormat { - case "json": - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - err = encoder.Encode(manager.leaks) - if err != nil { - return err - } - case "csv": - w := csv.NewWriter(file) - _ = w.Write([]string{"repo", "line", "commit", "offender", "rule", "tags", "commitMsg", "author", "email", "file", "date"}) - for _, leak := range manager.GetLeaks() { - w.Write([]string{leak.Repo, leak.Line, leak.Commit, leak.Offender, leak.Rule, leak.Tags, leak.Message, leak.Author, leak.Email, leak.File, leak.Date.Format(time.RFC3339)}) - } - w.Flush() - case "sarif": - s := Sarif{ - Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", - Version: "2.1.0", - Runs: []Runs{ - { - Tool: Tool{ - Driver: Driver{ - Name: "Gitleaks", - SemanticVersion: version.Version, - Rules: manager.configToRules(), - }, - }, - Results: manager.leaksToResults(), - }, - }, - } - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - err = encoder.Encode(s) - if err != nil { - return err - } - } - _ = file.Close() - - log.Infof("report written to %s", manager.Opts.Report) - } - return nil -} - diff --git a/manager/sarif.go b/manager/sarif.go deleted file mode 100644 index f4d056e66..000000000 --- a/manager/sarif.go +++ /dev/null @@ -1,153 +0,0 @@ -package manager - -import ( - "fmt" - "time" -) - -//Sarif ... -type Sarif struct { - Schema string `json:"$schema"` - Version string `json:"version"` - Runs []Runs `json:"runs"` -} - -//ShortDescription ... -type ShortDescription struct { - Text string `json:"text"` -} - -//FullDescription ... -type FullDescription struct { - Text string `json:"text"` -} - -//Rules ... -type Rules struct { - ID string `json:"id"` - Name string `json:"name"` -} - -//Driver ... -type Driver struct { - Name string `json:"name"` - SemanticVersion string `json:"semanticVersion"` - Rules []Rules `json:"rules"` -} - -//Tool ... -type Tool struct { - Driver Driver `json:"driver"` -} - -//Message ... -type Message struct { - Text string `json:"text"` -} - -//ArtifactLocation ... -type ArtifactLocation struct { - URI string `json:"uri"` -} - -//Region ... -type Region struct { - StartLine int `json:"startLine"` - Snippet Snippet `json:"snippet"` -} - -//Snippet ... -type Snippet struct { - Text string `json:"text"` -} - -//PhysicalLocation ... -type PhysicalLocation struct { - ArtifactLocation ArtifactLocation `json:"artifactLocation"` - Region Region `json:"region"` -} - -//Locations ... -type Locations struct { - PhysicalLocation PhysicalLocation `json:"physicalLocation"` -} - -//Results ... -type Results struct { - Message Message `json:"message"` - Properties ResultProperties `json:"properties"` - Locations []Locations `json:"locations"` -} - -//ResultProperties ... -type ResultProperties struct { - Commit string `json:"commit"` - Offender string `json:"offender"` - Date time.Time `json:"date"` - Author string `json:"author"` - Email string `json:"email"` - CommitMessage string `json:"commitMessage"` - Operation string `json:"gitOperation"` - Repo string `json:"repo"` -} - -//Runs ... -type Runs struct { - Tool Tool `json:"tool"` - Results []Results `json:"results"` -} - -func (manager *Manager) configToRules() []Rules { - var rules []Rules - for _, rule := range manager.Config.Rules { - rules = append(rules, Rules{ - ID: rule.Description, - Name: rule.Description, - }) - } - return rules -} - -func (manager *Manager) leaksToResults() []Results { - var results []Results - for _, leak := range manager.leaks { - results = append(results, Results{ - Message: Message{ - Text: fmt.Sprintf("%s secret detected", leak.Rule), - }, - Properties: ResultProperties{ - Commit: leak.Commit, - Offender: leak.Offender, - Date: leak.Date, - Author: leak.Author, - Email: leak.Email, - CommitMessage: leak.Message, - Operation: leak.Operation, - Repo: leak.Repo, - }, - Locations: leakToLocation(leak), - }) - } - - return results -} - -func leakToLocation(leak Leak) []Locations { - return []Locations{ - { - PhysicalLocation: - PhysicalLocation{ - ArtifactLocation: ArtifactLocation{ - URI: leak.File, - }, - Region: Region{ - StartLine: leak.LineNumber, - Snippet: Snippet{ - Text: leak.Line, - }, - }, - }, - }, - } -} - diff --git a/options/options.go b/options/options.go deleted file mode 100644 index e2ed557d2..000000000 --- a/options/options.go +++ /dev/null @@ -1,257 +0,0 @@ -package options - -import ( - "fmt" - "io/ioutil" - "os" - "os/user" - "strings" - - "github.com/zricethezav/gitleaks/v6/version" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" - "github.com/jessevdk/go-flags" - log "github.com/sirupsen/logrus" -) - -// No leaks or early exit due to invalid options -// This block defines the exit codes. Success -const ( - // No leaks or early exit due to invalid options - Success = 0 - LeaksPresent = 1 - ErrorEncountered = 2 - donateMessage = "👋 maintaining gitleaks takes a lot of work so consider sponsoring me or donating a little something\n❤️ https://github.com/sponsors/zricethezav\n💸 https://www.paypal.me/zricethezav\n₿ btc:3GndEzRZa6rJ8ZpkLureUcc5TDHMYfpDxn" -) - -// Options stores values of command line options -type Options struct { - Verbose bool `short:"v" long:"verbose" description:"Show verbose output from scan"` - Repo string `short:"r" long:"repo" description:"Target repository"` - Config string `long:"config" description:"config path"` - Disk bool `long:"disk" description:"Clones repo(s) to disk"` - Version bool `long:"version" description:"version number"` - Username string `long:"username" description:"Username for git repo"` - Password string `long:"password" description:"Password for git repo"` - AccessToken string `long:"access-token" description:"Access token for git repo"` - FilesAtCommit string `long:"files-at-commit" description:"sha of commit to scan all files at commit"` - Threads int `long:"threads" description:"Maximum number of threads gitleaks spawns"` - SSH string `long:"ssh-key" description:"path to ssh key used for auth"` - Uncommited bool `long:"uncommitted" description:"run gitleaks on uncommitted code"` - RepoPath string `long:"repo-path" description:"Path to repo"` - OwnerPath string `long:"owner-path" description:"Path to owner directory (repos discovered)"` - Branch string `long:"branch" description:"Branch to scan"` - Report string `long:"report" description:"path to write json leaks file"` - ReportFormat string `long:"report-format" default:"json" description:"json, csv, sarif"` - Redact bool `long:"redact" description:"redact secrets from log messages and leaks"` - Debug bool `long:"debug" description:"log debug messages"` - RepoConfig bool `long:"repo-config" description:"Load config from target repo. Config file must be \".gitleaks.toml\" or \"gitleaks.toml\""` - PrettyPrint bool `long:"pretty" description:"Pretty print json if leaks are present"` - - // Commit Options - Commit string `long:"commit" description:"sha of commit to scan or \"latest\" to scan the last commit of the repository"` - Commits string `long:"commits" description:"comma separated list of a commits to scan"` - CommitsFile string `long:"commits-file" description:"file of new line separated list of a commits to scan"` - CommitFrom string `long:"commit-from" description:"Commit to start scan from"` - CommitTo string `long:"commit-to" description:"Commit to stop scan"` - CommitSince string `long:"commit-since" description:"Scan commits more recent than a specific date. Ex: '2006-01-02' or '2006-01-02T15:04:05-0700' format."` - CommitUntil string `long:"commit-until" description:"Scan commits older than a specific date. Ex: '2006-01-02' or '2006-01-02T15:04:05-0700' format."` - - Timeout string `long:"timeout" description:"Time allowed per scan. Ex: 10us, 30s, 1m, 1h10m1s"` - Depth int `long:"depth" description:"Number of commits to scan"` - Deletion bool `long:"include-deletion" description:"Scan for patch deletions in addition to patch additions"` - - // Hosts - Host string `long:"host" description:"git hosting service like gitlab or github. Supported hosts include: Github, Gitlab"` - BaseURL string `long:"baseurl" description:"Base URL for API requests. Defaults to the public GitLab or GitHub API, but can be set to a domain endpoint to use with a self hosted server."` - Organization string `long:"org" description:"organization to scan"` - User string `long:"user" description:"user to scan"` - PullRequest string `long:"pr" description:"pull/merge request url"` - ExcludeForks bool `long:"exclude-forks" description:"scan excludes forks"` -} - -// ParseOptions is responsible for parsing options passed in by cli. An Options struct -// is returned if successful. This struct is passed around the program -// and will determine how the program executes. If err, an err message or help message -// will be displayed and the program will exit with code 0. -func ParseOptions() (Options, error) { - var opts Options - parser := flags.NewParser(&opts, flags.Default) - _, err := parser.Parse() - - if err != nil { - if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type != flags.ErrHelp { - parser.WriteHelp(os.Stdout) - } - fmt.Println(donateMessage) - os.Exit(0) - } - - if opts.Version { - if version.Version == "" { - fmt.Println("Gitleaks uses LDFLAGS to pull most recent version. Build with 'make build' for version") - } else { - fmt.Printf("%s\n", version.Version) - } - os.Exit(Success) - } - - if opts.Debug { - log.SetLevel(log.DebugLevel) - } - - return opts, nil -} - -// Guard checks to makes sure there are no invalid options set. -// If invalid sets of options are present, a descriptive error will return -// else nil is returned -func (opts Options) Guard() error { - if !oneOrNoneSet(opts.Repo, opts.OwnerPath, opts.RepoPath, opts.Host) { - return fmt.Errorf("only one target option must can be set. target options: repo, owner-path, repo-path, host") - } - if !oneOrNoneSet(opts.Organization, opts.User, opts.PullRequest) { - return fmt.Errorf("only one target option must can be set. target options: repo, owner-path, repo-path, host") - } - if !oneOrNoneSet(opts.AccessToken, opts.Password) { - log.Warn("both access-token and password are set. Only password will be attempted") - } - - return nil -} - -func oneOrNoneSet(optStr ...string) bool { - c := 0 - for _, s := range optStr { - if s != "" { - c++ - } - } - if c <= 1 { - return true - } - return false -} - -// CloneOptions returns a git.cloneOptions pointer. The authentication method -// is determined by what is passed in via command-Line options. If No -// Username/PW or AccessToken is available and the repo target is not using the -// git protocol then the repo must be a available via no auth. -func (opts Options) CloneOptions() (*git.CloneOptions, error) { - progress := ioutil.Discard - if opts.Verbose { - progress = os.Stdout - } - - if strings.HasPrefix(opts.Repo, "git") { - // using git protocol so needs ssh auth - auth, err := SSHAuth(opts) - if err != nil { - return nil, err - } - return &git.CloneOptions{ - URL: opts.Repo, - Auth: auth, - Progress: progress, - }, nil - } - if opts.Password != "" && opts.Username != "" { - // auth using username and password - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: opts.Username, - Password: opts.Password, - }, - Progress: progress, - }, nil - } - if opts.AccessToken != "" { - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: "gitleaks_user", - Password: opts.AccessToken, - }, - Progress: progress, - }, nil - } - if os.Getenv("GITLEAKS_ACCESS_TOKEN") != "" { - return &git.CloneOptions{ - URL: opts.Repo, - Auth: &http.BasicAuth{ - Username: "gitleaks_user", - Password: os.Getenv("GITLEAKS_ACCESS_TOKEN"), - }, - Progress: progress, - }, nil - } - - // No Auth, publicly available - return &git.CloneOptions{ - URL: opts.Repo, - Progress: progress, - }, nil -} - -// SSHAuth tried to generate ssh public keys based on what was passed via cli. If no -// path was passed via cli then this will attempt to retrieve keys from the default -// location for ssh keys, $HOME/.ssh/id_rsa. This function is only called if the -// repo url using the git:// protocol. -func SSHAuth(opts Options) (*ssh.PublicKeys, error) { - if opts.SSH != "" { - return ssh.NewPublicKeysFromFile("git", opts.SSH, "") - } - c, err := user.Current() - if err != nil { - return nil, err - } - defaultPath := fmt.Sprintf("%s/.ssh/id_rsa", c.HomeDir) - return ssh.NewPublicKeysFromFile("git", defaultPath, "") -} - -// OpenLocal checks what options are set, if no remote targets are set -// then return true -func (opts Options) OpenLocal() bool { - if opts.Uncommited || opts.RepoPath != "" || opts.Repo == "" { - return true - } - return false -} - -// CheckUncommitted returns a boolean that indicates whether or not gitleaks should check unstaged pre-commit changes -// or if gitleaks should check the entire git history -func (opts Options) CheckUncommitted() bool { - // check to make sure no remote shit is set - if opts.Uncommited { - return true - } - if opts == (Options{}) { - return true - } - if opts.Repo != "" { - return false - } - if opts.RepoPath != "" { - return false - } - if opts.OwnerPath != "" { - return false - } - if opts.Host != "" { - return false - } - return true -} - -// GetAccessToken accepts options and returns a string which is the access token to a git host. -// Setting this option or environment var is necessary if performing an scan with any of the git hosting providers -// in the host pkg. The access token set by cli options takes precedence over env vars. -func GetAccessToken(opts Options) string { - if opts.AccessToken != "" { - return opts.AccessToken - } - return os.Getenv("GITLEAKS_ACCESS_TOKEN") -} diff --git a/options/options_test.go b/options/options_test.go deleted file mode 100644 index 0684d0596..000000000 --- a/options/options_test.go +++ /dev/null @@ -1 +0,0 @@ -package options diff --git a/report/constants.go b/report/constants.go new file mode 100644 index 000000000..7772950c0 --- /dev/null +++ b/report/constants.go @@ -0,0 +1,4 @@ +package report + +const version = "v8.0.0" +const driver = "gitleaks" diff --git a/report/csv.go b/report/csv.go new file mode 100644 index 000000000..e36cbaa2d --- /dev/null +++ b/report/csv.go @@ -0,0 +1,57 @@ +package report + +import ( + "encoding/csv" + "io" + "strconv" +) + +// writeCsv writes the list of findings to a writeCloser. +func writeCsv(f []Finding, w io.WriteCloser) error { + if len(f) == 0 { + return nil + } + defer w.Close() + cw := csv.NewWriter(w) + err := cw.Write([]string{"RuleID", + "Commit", + "File", + "Secret", + "Match", + "StartLine", + "EndLine", + "StartColumn", + "EndColumn", + "Author", + "Message", + "Date", + "Email", + "Fingerprint", + }) + if err != nil { + return err + } + for _, f := range f { + err = cw.Write([]string{f.RuleID, + f.Commit, + f.File, + f.Secret, + f.Match, + strconv.Itoa(f.StartLine), + strconv.Itoa(f.EndLine), + strconv.Itoa(f.StartColumn), + strconv.Itoa(f.EndColumn), + f.Author, + f.Message, + f.Date, + f.Email, + f.Fingerprint, + }) + if err != nil { + return err + } + } + + cw.Flush() + return cw.Error() +} diff --git a/report/csv_test.go b/report/csv_test.go new file mode 100644 index 000000000..c4dd4ec70 --- /dev/null +++ b/report/csv_test.go @@ -0,0 +1,85 @@ +package report + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestWriteCSV(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + }{ + { + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "csv_simple.csv"), + findings: []Finding{ + { + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Fingerprint: "fingerprint", + }, + }}, + { + + wantEmpty: true, + testReportName: "empty", + expected: filepath.Join(expectPath, "report", "this_should_not_exist.csv"), + findings: []Finding{}}, + } + + for _, test := range tests { + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".csv")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = writeCsv(test.findings, tmpfile) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".csv", ".got.csv", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/report/finding.go b/report/finding.go new file mode 100644 index 000000000..885edf711 --- /dev/null +++ b/report/finding.go @@ -0,0 +1,50 @@ +package report + +import ( + "strings" +) + +// Finding contains information about strings that +// have been captured by a tree-sitter query. +type Finding struct { + Description string + StartLine int + EndLine int + StartColumn int + EndColumn int + + Line string `json:"-"` + + Match string + + // Secret contains the full content of what is matched in + // the tree-sitter query. + Secret string + + // File is the name of the file containing the finding + File string + + Commit string + + // Entropy is the shannon entropy of Value + Entropy float32 + + Author string + Email string + Date string + Message string + Tags []string + + // Rule is the name of the rule that was matched + RuleID string + + // unique identifer + Fingerprint string +} + +// Redact removes sensitive information from a finding. +func (f *Finding) Redact() { + f.Line = strings.Replace(f.Line, f.Secret, "REDACTED", -1) + f.Match = strings.Replace(f.Match, f.Secret, "REDACTED", -1) + f.Secret = "REDACTED" +} diff --git a/report/finding_test.go b/report/finding_test.go new file mode 100644 index 000000000..8cfc2c859 --- /dev/null +++ b/report/finding_test.go @@ -0,0 +1,27 @@ +package report + +import "testing" + +func TestRedact(t *testing.T) { + tests := []struct { + findings []Finding + redact bool + }{ + { + redact: true, + findings: []Finding{ + { + Secret: "line containing secret", + Match: "secret", + }, + }}, + } + for _, test := range tests { + for _, f := range test.findings { + f.Redact() + if f.Secret != "REDACTED" { + t.Error("redact not redacting: ", f.Secret) + } + } + } +} diff --git a/report/json.go b/report/json.go new file mode 100644 index 000000000..424cb9c2f --- /dev/null +++ b/report/json.go @@ -0,0 +1,15 @@ +package report + +import ( + "encoding/json" + "io" +) + +func writeJson(findings []Finding, w io.WriteCloser) error { + if len(findings) == 0 { + findings = []Finding{} + } + encoder := json.NewEncoder(w) + encoder.SetIndent("", " ") + return encoder.Encode(findings) +} diff --git a/report/json_test.go b/report/json_test.go new file mode 100644 index 000000000..d20cf86bf --- /dev/null +++ b/report/json_test.go @@ -0,0 +1,88 @@ +package report + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestWriteJSON(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + }{ + { + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "json_simple.json"), + findings: []Finding{ + { + + Description: "", + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Tags: []string{}, + }, + }}, + { + + testReportName: "empty", + expected: filepath.Join(expectPath, "report", "empty.json"), + findings: []Finding{}}, + } + + for _, test := range tests { + // create tmp file using os.TempDir() + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".json")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = writeJson(test.findings, tmpfile) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + os.Remove(tmpfile.Name()) + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".json", ".got.json", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/report/report.go b/report/report.go new file mode 100644 index 000000000..c085c53b0 --- /dev/null +++ b/report/report.go @@ -0,0 +1,32 @@ +package report + +import ( + "os" + "strings" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + // https://cwe.mitre.org/data/definitions/798.html + CWE = "CWE-798" + CWE_DESCRIPTION = "Use of Hard-coded Credentials" +) + +func Write(findings []Finding, cfg config.Config, ext string, reportPath string) error { + file, err := os.Create(reportPath) + if err != nil { + return err + } + ext = strings.ToLower(ext) + switch ext { + case ".json", "json": + err = writeJson(findings, file) + case ".csv", "csv": + err = writeCsv(findings, file) + case ".sarif", "sarif": + err = writeSarif(cfg, findings, file) + } + + return err +} diff --git a/report/report_test.go b/report/report_test.go new file mode 100644 index 000000000..ae0b84db2 --- /dev/null +++ b/report/report_test.go @@ -0,0 +1,111 @@ +package report + +import ( + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/zricethezav/gitleaks/v8/config" +) + +const ( + expectPath = "../testdata/expected/" + tmpPath = "../testdata/tmp" +) + +func TestReport(t *testing.T) { + tests := []struct { + findings []Finding + ext string + wantEmpty bool + }{ + { + ext: "json", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: ".json", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: ".jsonj", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + wantEmpty: true, + }, + { + ext: ".csv", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: "csv", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + { + ext: "CSV", + findings: []Finding{ + { + RuleID: "test-rule", + }, + }, + }, + // { + // ext: "SARIF", + // findings: []Finding{ + // { + // RuleID: "test-rule", + // }, + // }, + // }, + } + + for i, test := range tests { + tmpfile, err := os.Create(filepath.Join(tmpPath, strconv.Itoa(i)+test.ext)) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + err = Write(test.findings, config.Config{}, test.ext, tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + os.Remove(tmpfile.Name()) + + if len(got) == 0 && !test.wantEmpty { + t.Errorf("got empty file with extension " + test.ext) + } + + if test.wantEmpty { + if len(got) > 0 { + t.Errorf("Expected empty file, got %s", got) + } + continue + } + } +} diff --git a/report/sarif.go b/report/sarif.go new file mode 100644 index 000000000..d1df25896 --- /dev/null +++ b/report/sarif.go @@ -0,0 +1,209 @@ +package report + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/zricethezav/gitleaks/v8/config" +) + +func writeSarif(cfg config.Config, findings []Finding, w io.WriteCloser) error { + sarif := Sarif{ + Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", + Version: "2.1.0", + Runs: getRuns(cfg, findings), + } + + encoder := json.NewEncoder(w) + encoder.SetIndent("", " ") + return encoder.Encode(sarif) +} + +func getRuns(cfg config.Config, findings []Finding) []Runs { + return []Runs{ + { + Tool: getTool(cfg), + Results: getResults(findings), + }, + } +} + +func getTool(cfg config.Config) Tool { + tool := Tool{ + Driver: Driver{ + Name: driver, + SemanticVersion: version, + Rules: getRules(cfg), + }, + } + + // if this tool has no rules, ensure that it is represented as [] instead of null/nil + if hasEmptyRules(tool) { + tool.Driver.Rules = make([]Rules, 0) + } + + return tool +} + +func hasEmptyRules(tool Tool) bool { + return len(tool.Driver.Rules) == 0 +} + +func getRules(cfg config.Config) []Rules { + // TODO for _, rule := range cfg.Rules { + var rules []Rules + for _, rule := range cfg.OrderedRules() { + shortDescription := ShortDescription{ + Text: rule.Description, + } + if rule.Regex != nil { + shortDescription = ShortDescription{ + Text: rule.Regex.String(), + } + } else if rule.Path != nil { + shortDescription = ShortDescription{ + Text: rule.Path.String(), + } + } + rules = append(rules, Rules{ + ID: rule.RuleID, + Name: rule.Description, + Description: shortDescription, + }) + } + return rules +} + +func messageText(f Finding) string { + if f.Commit == "" { + return fmt.Sprintf("%s has detected secret for file %s.", f.RuleID, f.File) + } + + return fmt.Sprintf("%s has detected secret for file %s at commit %s.", f.RuleID, f.File, f.Commit) + +} + +func getResults(findings []Finding) []Results { + results := []Results{} + for _, f := range findings { + r := Results{ + Message: Message{ + Text: messageText(f), + }, + RuleId: f.RuleID, + Locations: getLocation(f), + // This information goes in partial fingerprings until revision + // data can be added somewhere else + PartialFingerPrints: PartialFingerPrints{ + CommitSha: f.Commit, + Email: f.Email, + CommitMessage: f.Message, + Date: f.Date, + Author: f.Author, + }, + } + results = append(results, r) + } + return results +} + +func getLocation(f Finding) []Locations { + return []Locations{ + { + PhysicalLocation: PhysicalLocation{ + ArtifactLocation: ArtifactLocation{ + URI: f.File, + }, + Region: Region{ + StartLine: f.StartLine, + EndLine: f.EndLine, + StartColumn: f.StartColumn, + EndColumn: f.EndColumn, + Snippet: Snippet{ + Text: f.Secret, + }, + }, + }, + }, + } +} + +type PartialFingerPrints struct { + CommitSha string `json:"commitSha"` + Email string `json:"email"` + Author string `json:"author"` + Date string `json:"date"` + CommitMessage string `json:"commitMessage"` +} + +type Sarif struct { + Schema string `json:"$schema"` + Version string `json:"version"` + Runs []Runs `json:"runs"` +} + +type ShortDescription struct { + Text string `json:"text"` +} + +type FullDescription struct { + Text string `json:"text"` +} + +type Rules struct { + ID string `json:"id"` + Name string `json:"name"` + Description ShortDescription `json:"shortDescription"` +} + +type Driver struct { + Name string `json:"name"` + SemanticVersion string `json:"semanticVersion"` + Rules []Rules `json:"rules"` +} + +type Tool struct { + Driver Driver `json:"driver"` +} + +type Message struct { + Text string `json:"text"` +} + +type ArtifactLocation struct { + URI string `json:"uri"` +} + +type Region struct { + StartLine int `json:"startLine"` + StartColumn int `json:"startColumn"` + EndLine int `json:"endLine"` + EndColumn int `json:"endColumn"` + Snippet Snippet `json:"snippet"` +} + +type Snippet struct { + Text string `json:"text"` +} + +type PhysicalLocation struct { + ArtifactLocation ArtifactLocation `json:"artifactLocation"` + Region Region `json:"region"` +} + +type Locations struct { + PhysicalLocation PhysicalLocation `json:"physicalLocation"` +} + +type Results struct { + Message Message `json:"message"` + RuleId string `json:"ruleId"` + Locations []Locations `json:"locations"` + PartialFingerPrints `json:"partialFingerprints"` +} + +type Runs struct { + Tool Tool `json:"tool"` + Results []Results `json:"results"` +} diff --git a/report/sarif_test.go b/report/sarif_test.go new file mode 100644 index 000000000..3418fb99b --- /dev/null +++ b/report/sarif_test.go @@ -0,0 +1,111 @@ +package report + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/spf13/viper" + "github.com/zricethezav/gitleaks/v8/config" +) + +const configPath = "../testdata/config/" + +func TestWriteSarif(t *testing.T) { + tests := []struct { + findings []Finding + testReportName string + expected string + wantEmpty bool + cfgName string + }{ + { + cfgName: "simple", + testReportName: "simple", + expected: filepath.Join(expectPath, "report", "sarif_simple.sarif"), + findings: []Finding{ + { + + Description: "A test rule", + RuleID: "test-rule", + Match: "line containing secret", + Secret: "a secret", + StartLine: 1, + EndLine: 2, + StartColumn: 1, + EndColumn: 2, + Message: "opps", + File: "auth.py", + Commit: "0000000000000000", + Author: "John Doe", + Email: "johndoe@gmail.com", + Date: "10-19-2003", + Tags: []string{}, + }, + }}, + } + + for _, test := range tests { + // create tmp file using os.TempDir() + tmpfile, err := os.Create(filepath.Join(tmpPath, test.testReportName+".json")) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + viper.Reset() + viper.AddConfigPath(configPath) + viper.SetConfigName(test.cfgName) + viper.SetConfigType("toml") + err = viper.ReadInConfig() + if err != nil { + t.Error(err) + } + + var vc config.ViperConfig + err = viper.Unmarshal(&vc) + if err != nil { + t.Error(err) + } + + cfg, err := vc.Translate() + if err != nil { + t.Error(err) + } + err = writeSarif(cfg, test.findings, tmpfile) + fmt.Println(cfg) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + got, err := os.ReadFile(tmpfile.Name()) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + if test.wantEmpty { + if len(got) > 0 { + os.Remove(tmpfile.Name()) + t.Errorf("Expected empty file, got %s", got) + } + os.Remove(tmpfile.Name()) + continue + } + want, err := os.ReadFile(test.expected) + if err != nil { + os.Remove(tmpfile.Name()) + t.Error(err) + } + + if string(got) != string(want) { + err = os.WriteFile(strings.Replace(test.expected, ".sarif", ".got.sarif", 1), got, 0644) + if err != nil { + t.Error(err) + } + t.Errorf("got %s, want %s", string(got), string(want)) + } + + os.Remove(tmpfile.Name()) + } +} diff --git a/scan/repo.go b/scan/repo.go deleted file mode 100644 index 9dcb0646e..000000000 --- a/scan/repo.go +++ /dev/null @@ -1,304 +0,0 @@ -package scan - -import ( - "context" - "crypto/md5" - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "runtime" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - - "github.com/BurntSushi/toml" - "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/storage/memory" - log "github.com/sirupsen/logrus" -) - -// Repo wraps a *git.Repository object in addition to a manager object and the name of the repo. -// Commits are inspected from the *git.Repository object. If a Commit is found then we send it -// via the manager LeakChan where the manager receives and keeps track of all leaks. -type Repo struct { - *git.Repository - - // config is used when the --repo-config option is set. - // This allows users to load up configs specific to their repos. - // Imagine the scenario where you are doing an scan of a large organization - // and you want certain repos to look for specific rules. If those specific repos - // have a gitleaks.toml or .gitleaks.toml config then those configs will be used specifically - // for those repo scans. - config config.Config - - // ctx is used to signal timeouts to running goroutines - ctx context.Context - cancel context.CancelFunc - - Name string - Manager *manager.Manager -} - -// NewRepo initializes and returns a Repo struct. -func NewRepo(m *manager.Manager) *Repo { - return &Repo{ - Manager: m, - config: m.Config, - ctx: context.Background(), - } -} - -// Run accepts a manager and begins an scan based on the options/configs set in the manager. -func Run(m *manager.Manager) error { - if m.Opts.OwnerPath != "" { - files, err := ioutil.ReadDir(m.Opts.OwnerPath) - if err != nil { - return err - } - for _, f := range files { - if !f.IsDir() { - continue - } - m.Opts.RepoPath = fmt.Sprintf("%s/%s", m.Opts.OwnerPath, f.Name()) - if err := runHelper(NewRepo(m)); err != nil { - log.Warnf("%s is not a git repo, skipping", f.Name()) - } - } - return nil - } - - return runHelper(NewRepo(m)) -} - -func runHelper(r *Repo) error { - // Ignore allowlisted repos - for _, allowListedRepo := range r.Manager.Config.Allowlist.Repos { - if RegexMatched(r.Manager.Opts.RepoPath, allowListedRepo) { - return nil - } - if RegexMatched(r.Manager.Opts.Repo, allowListedRepo) { - return nil - } - } - if r.Manager.Opts.OpenLocal() { - r.Name = path.Base(r.Manager.Opts.RepoPath) - if err := r.Open(); err != nil { - return err - } - - // Check if we are checking uncommitted files. This is the default behavior - // for a "$ gitleaks" command with no options set - if r.Manager.Opts.CheckUncommitted() { - if err := r.scanUncommitted(); err != nil { - return err - } - return nil - } - } else { - if err := r.Clone(nil); err != nil { - return err - } - } - return r.Scan() -} - -// Clone will clone a repo and return a Repo struct which contains a go-git repo. The clone method -// is determined by the clone options set in Manager.metadata.cloneOptions -func (repo *Repo) Clone(cloneOption *git.CloneOptions) error { - var ( - repository *git.Repository - err error - ) - if cloneOption == nil { - cloneOption = repo.Manager.CloneOptions - } - - log.Infof("cloning... %s", cloneOption.URL) - start := time.Now() - - if repo.Manager.CloneDir != "" { - clonePath := fmt.Sprintf("%s/%x", repo.Manager.CloneDir, md5.Sum([]byte(time.Now().String()))) - repository, err = git.PlainClone(clonePath, false, cloneOption) - } else { - repository, err = git.Clone(memory.NewStorage(), nil, cloneOption) - } - if err != nil { - return err - } - repo.Name = filepath.Base(repo.Manager.Opts.Repo) - repo.Repository = repository - repo.Manager.RecordTime(manager.CloneTime(howLong(start))) - - return nil -} - -// howManyThreads will return a number 1-GOMAXPROCS which is the number -// of goroutines that will spawn during gitleaks execution -func howManyThreads(threads int) int { - maxThreads := runtime.GOMAXPROCS(0) - if threads == 0 { - return 1 - } else if threads > maxThreads { - log.Warnf("%d threads set too high, setting to system max, %d", threads, maxThreads) - return maxThreads - } - return threads -} - -// getLogOptions determines what log options are used when iterating through commits. -// It is similar to `git log {branch}`. Default behavior is to log ALL branches so -// gitleaks gets the full git history. -func getLogOptions(repo *Repo) (*git.LogOptions, error) { - var logOpts git.LogOptions - const dateformat string = "2006-01-02" - const timeformat string = "2006-01-02T15:04:05-0700" - if repo.Manager.Opts.CommitFrom != "" { - logOpts.From = plumbing.NewHash(repo.Manager.Opts.CommitFrom) - } - if repo.Manager.Opts.CommitSince != "" { - if t, err := time.Parse(timeformat, repo.Manager.Opts.CommitSince); err == nil { - logOpts.Since = &t - } else if t, err := time.Parse(dateformat, repo.Manager.Opts.CommitSince); err == nil { - logOpts.Since = &t - } else { - return nil, err - } - } - if repo.Manager.Opts.CommitUntil != "" { - if t, err := time.Parse(timeformat, repo.Manager.Opts.CommitUntil); err == nil { - logOpts.Until = &t - } else if t, err := time.Parse(dateformat, repo.Manager.Opts.CommitUntil); err == nil { - logOpts.Until = &t - } else { - return nil, err - } - } - if repo.Manager.Opts.Branch != "" { - refs, err := repo.Storer.IterReferences() - if err != nil { - return nil, err - } - err = refs.ForEach(func(ref *plumbing.Reference) error { - if ref.Name().IsTag() { - return nil - } - // check heads first - if ref.Name().String() == "refs/heads/"+repo.Manager.Opts.Branch { - logOpts = git.LogOptions{ - From: ref.Hash(), - } - return nil - } else if ref.Name().String() == "refs/remotes/origin/"+repo.Manager.Opts.Branch { - logOpts = git.LogOptions{ - From: ref.Hash(), - } - return nil - } - return nil - }) - if err != nil { - return nil, err - } - - if logOpts.From.IsZero() { - return nil, fmt.Errorf("could not find branch %s", repo.Manager.Opts.Branch) - } - return &logOpts, nil - } - if !logOpts.From.IsZero() || logOpts.Since != nil || logOpts.Until != nil { - return &logOpts, nil - } - return &git.LogOptions{All: true}, nil -} - -// howLong accepts a time.Time object which is subtracted from time.Now() and -// converted to nanoseconds which is returned -func howLong(t time.Time) int64 { - return time.Now().Sub(t).Nanoseconds() -} - -// Open opens a local repo either from repo-path or $PWD -func (repo *Repo) Open() error { - if repo.Manager.Opts.RepoPath != "" { - // open git repo from repo path - repository, err := git.PlainOpen(repo.Manager.Opts.RepoPath) - if err != nil { - return err - } - repo.Repository = repository - } else { - // open git repo from PWD - dir, err := os.Getwd() - if err != nil { - return err - } - repository, err := git.PlainOpen(dir) - if err != nil { - return err - } - repo.Repository = repository - repo.Name = path.Base(dir) - } - return nil -} - -func (repo *Repo) loadRepoConfig() (config.Config, error) { - wt, err := repo.Repository.Worktree() - if err != nil { - return config.Config{}, err - } - var f billy.File - f, _ = wt.Filesystem.Open(".gitleaks.toml") - if f == nil { - f, err = wt.Filesystem.Open("gitleaks.toml") - if err != nil { - return config.Config{}, fmt.Errorf("problem loading repo config: %v", err) - } - } - defer f.Close() - var tomlLoader config.TomlLoader - _, err = toml.DecodeReader(f, &tomlLoader) - if err != nil { - return config.Config{}, err - } - - return tomlLoader.Parse() -} - -// timeoutReached returns true if the timeout deadline has been met. This function should be used -// at the top of loops and before potentially long running goroutines (like checking inefficient regexes) -func (repo *Repo) timeoutReached() bool { - if repo.ctx.Err() == context.DeadlineExceeded { - return true - } - return false -} - -// setupTimeout parses the --timeout option and assigns a context with timeout to the manager -// which will exit early if the timeout has been met. -func (repo *Repo) setupTimeout() error { - if repo.Manager.Opts.Timeout == "" { - return nil - } - timeout, err := time.ParseDuration(repo.Manager.Opts.Timeout) - if err != nil { - return err - } - - repo.ctx, repo.cancel = context.WithTimeout(context.Background(), timeout) - - go func() { - select { - case <-repo.ctx.Done(): - if repo.timeoutReached() { - log.Warnf("Timeout deadline (%s) exceeded for %s", timeout.String(), repo.Name) - } - } - }() - return nil -} diff --git a/scan/rule.go b/scan/rule.go deleted file mode 100644 index 28cc0f896..000000000 --- a/scan/rule.go +++ /dev/null @@ -1,395 +0,0 @@ -package scan - -import ( - "bufio" - "fmt" - "io" - "math" - "path/filepath" - "regexp" - "strconv" - "strings" - "time" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - - fdiff "github.com/go-git/go-git/v5/plumbing/format/diff" - "github.com/go-git/go-git/v5/plumbing/object" - log "github.com/sirupsen/logrus" -) - -const ( - diffAddPrefix = "+" - diffAddFilePrefix = "+++ b" - diffAddFilePrefixSlash = "+++ b/" - diffLineSignature = " @@" - diffLineSignaturePrefix = "@@ " - defaultLineNumber = -1 -) - -// CheckRules accepts bundle and checks each rule defined in the config against the bundle's content. -func (repo *Repo) CheckRules(bundle *Bundle) { - filename := filepath.Base(bundle.FilePath) - path := filepath.Dir(bundle.FilePath) - - bundle.lineLookup = make(map[string]bool) - - // We want to check if there is a allowlist for this file - if len(repo.config.Allowlist.Files) != 0 { - for _, reFileName := range repo.config.Allowlist.Files { - if RegexMatched(filename, reFileName) { - log.Debugf("allowlisted file found, skipping scan of file: %s", filename) - return - } - } - } - - // We want to check if there is a allowlist for this path - if len(repo.config.Allowlist.Paths) != 0 { - for _, reFilePath := range repo.config.Allowlist.Paths { - if RegexMatched(path, reFilePath) { - log.Debugf("file in allowlisted path found, skipping scan of file: %s", filename) - return - } - } - } - - for _, rule := range repo.config.Rules { - start := time.Now() - - // For each rule we want to check filename allowlists - if isAllowListed(filename, rule.AllowList.Files) || isAllowListed(path, rule.AllowList.Paths) { - continue - } - - // If it has fileNameRegex and it doesnt match we continue to next rule - if ruleContainFileRegex(rule) && !RegexMatched(filename, rule.File) { - continue - } - - // If it has filePathRegex and it doesnt match we continue to next rule - if ruleContainPathRegex(rule) && !RegexMatched(path, rule.Path) { - continue - } - - // If it doesnt contain a Content regex then it is a filename regex match - if !ruleContainRegex(rule) { - repo.Manager.SendLeaks(manager.Leak{ - LineNumber: defaultLineNumber, - Line: "N/A", - Offender: "Filename/path offender: " + filename, - Commit: bundle.Commit.Hash.String(), - Repo: repo.Name, - Message: bundle.Commit.Message, - Rule: rule.Description, - Author: bundle.Commit.Author.Name, - Email: bundle.Commit.Author.Email, - Date: bundle.Commit.Author.When, - Tags: strings.Join(rule.Tags, ", "), - File: filename, - Operation: diffOpToString(bundle.Operation), - }) - } else { - //otherwise we check if it matches Content regex - locs := rule.Regex.FindAllIndex([]byte(bundle.Content), -1) - if len(locs) != 0 { - for _, loc := range locs { - start := loc[0] - end := loc[1] - for start != 0 && bundle.Content[start] != '\n' { - start-- - } - - if bundle.Content[start] == '\n' { - start++ - } - - for end < len(bundle.Content)-1 && bundle.Content[end] != '\n' { - end++ - } - - line := bundle.Content[start:end] - offender := bundle.Content[loc[0]:loc[1]] - groups := rule.Regex.FindStringSubmatch(offender) - - if isAllowListed(line, append(rule.AllowList.Regexes, repo.config.Allowlist.Regexes...)) { - continue - } - - if len(rule.Entropies) != 0 && !trippedEntropy(groups, rule) { - continue - } - - leak := manager.Leak{ - LineNumber: defaultLineNumber, - Line: line, - Offender: offender, - Commit: bundle.Commit.Hash.String(), - Repo: repo.Name, - Message: bundle.Commit.Message, - Rule: rule.Description, - Author: bundle.Commit.Author.Name, - Email: bundle.Commit.Author.Email, - Date: bundle.Commit.Author.When, - Tags: strings.Join(rule.Tags, ", "), - File: bundle.FilePath, - Operation: diffOpToString(bundle.Operation), - } - - // only search for line numbers on non-deletions - if bundle.Operation != fdiff.Delete { - extractAndInjectLineNumber(&leak, bundle, repo) - } - - repo.Manager.SendLeaks(leak) - } - } - } - - repo.Manager.RecordTime(manager.RegexTime{ - Time: howLong(start), - Regex: rule.Regex.String(), - }) - } -} - -// RegexMatched matched an interface to a regular expression. The interface f can -// be a string type or go-git *object.File type. -func RegexMatched(f interface{}, re *regexp.Regexp) bool { - if re == nil { - return false - } - switch f.(type) { - case nil: - return false - case string: - if re.FindString(f.(string)) != "" { - return true - } - return false - case *object.File: - if re.FindString(f.(*object.File).Name) != "" { - return true - } - return false - } - return false -} - -// diffOpToString converts a fdiff.Operation to a string -func diffOpToString(operation fdiff.Operation) string { - switch operation { - case fdiff.Add: - return "addition" - case fdiff.Equal: - return "equal" - default: - return "deletion" - } -} - -// extractAndInjectLine accepts a leak, bundle, and repo which it uses to do a reverse search in order to extract -// the line number of a historic or present leak. The function is only called when the git operation is an addition -// or none, it does not get called when the git operation is deletion. -func extractAndInjectLineNumber(leak *manager.Leak, bundle *Bundle, repo *Repo) { - var err error - - switch bundle.scanType { - case patchScan: - if bundle.Patch == "" { - return - } - - // This is needed as some patches generate strings that are larger than - // scanners max size (MaxScanTokenSize = 64 * 1024) - // https://github.com/zricethezav/gitleaks/issues/413 - buf := make([]byte, len(bundle.Patch)) - scanner := bufio.NewScanner(strings.NewReader(bundle.Patch)) - scanner.Buffer(buf, len(bundle.Patch)) - scanner.Split(bufio.ScanLines) - - currFile := "" - currLine := 0 - currStartDiffLine := 0 - - for scanner.Scan() { - txt := scanner.Text() - if strings.HasPrefix(txt, diffAddFilePrefix) { - currStartDiffLine = 1 - currLine = 0 - currFile = strings.Split(txt, diffAddFilePrefixSlash)[1] - - // next line contains diff line information so lets scan it here - scanner.Scan() - - txt := scanner.Text() - i := strings.Index(txt, diffAddPrefix) - pairs := strings.Split(strings.Split(txt[i+1:], diffLineSignature)[0], ",") - currStartDiffLine, err = strconv.Atoi(pairs[0]) - if err != nil { - log.Debug(err) - return - } - continue - } else if strings.HasPrefix(txt, diffAddPrefix) && strings.Contains(txt, leak.Line) && leak.File == currFile { - potentialLine := currLine + currStartDiffLine - if _, ok := bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, potentialLine, currFile)]; !ok { - bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, potentialLine, currFile)] = true - leak.LineNumber = potentialLine - return - } - } else if strings.HasPrefix(txt, diffLineSignaturePrefix) && currStartDiffLine != 0 { - // This logic is used for when there are multiple leaks of the same offender within the same patch - i := strings.Index(txt, diffAddPrefix) - pairs := strings.Split(strings.Split(txt[i+1:], diffLineSignature)[0], ",") - currStartDiffLine, err = strconv.Atoi(pairs[0]) - if err != nil { - log.Debug(err) - return - } - currLine = 0 - if !strings.HasSuffix(txt, diffLineSignature) { - currLine = -1 - } - } - currLine++ - } - case commitScan: - if bundle.Commit == nil { - return - } - f, err := bundle.Commit.File(bundle.FilePath) - if err != nil { - log.Error(err) - return - } - r, err := f.Reader() - if err != nil { - log.Error(err) - return - } - leak.LineNumber = extractLineHelper(r, bundle, leak) - case uncommittedScan: - wt, err := repo.Worktree() - if err != nil { - log.Error(err) - return - } - f, err := wt.Filesystem.Open(leak.File) - if err != nil { - log.Error(err) - return - } - leak.LineNumber = extractLineHelper(f, bundle, leak) - } -} - -// extractLineHelper consolidates code for checking the leak line against the contents of a reader to find the -// line number of the leak. -func extractLineHelper(r io.Reader, bundle *Bundle, leak *manager.Leak) int { - scanner := bufio.NewScanner(r) - lineNumber := 1 - for scanner.Scan() { - if leak.Line == scanner.Text() { - if _, ok := bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, lineNumber, bundle.FilePath)]; !ok { - bundle.lineLookup[fmt.Sprintf("%s%d%s", leak.Line, lineNumber, bundle.FilePath)] = true - return lineNumber - } - } - lineNumber++ - } - return -1 -} - -// trippedEntropy checks if a given capture group or offender falls in between entropy ranges -// supplied by a custom gitleaks configuration. Gitleaks do not check entropy by default. -func trippedEntropy(groups []string, rule config.Rule) bool { - for _, e := range rule.Entropies { - if len(groups) > e.Group { - entropy := shannonEntropy(groups[e.Group]) - if entropy >= e.Min && entropy <= e.Max { - return true - } - } - } - return false -} - -// shannonEntropy calculates the entropy of data using the formula defined here: -// https://en.wiktionary.org/wiki/Shannon_entropy -// Another way to think about what this is doing is calculating the number of bits -// needed to on average encode the data. So, the higher the entropy, the more random the data, the -// more bits needed to encode that data. -func shannonEntropy(data string) (entropy float64) { - if data == "" { - return 0 - } - - charCounts := make(map[rune]int) - for _, char := range data { - charCounts[char]++ - } - - invLength := 1.0 / float64(len(data)) - for _, count := range charCounts { - freq := float64(count) * invLength - entropy -= freq * math.Log2(freq) - } - - return entropy -} - -// Checks if the given rule has a regex -func ruleContainRegex(rule config.Rule) bool { - if rule.Regex == nil { - return false - } - if rule.Regex.String() == "" { - return false - } - return true -} - -// Checks if the given rule has a file name regex -func ruleContainFileRegex(rule config.Rule) bool { - if rule.File == nil { - return false - } - if rule.File.String() == "" { - return false - } - return true -} - -// Checks if the given rule has a file path regex -func ruleContainPathRegex(rule config.Rule) bool { - if rule.Path == nil { - return false - } - if rule.Path.String() == "" { - return false - } - return true -} - -func isCommitAllowListed(commitHash string, allowlistedCommits []string) bool { - for _, hash := range allowlistedCommits { - if commitHash == hash { - return true - } - } - return false -} - -func isAllowListed(target string, allowList []*regexp.Regexp) bool { - if len(allowList) != 0 { - for _, re := range allowList { - if re.FindString(target) != "" { - return true - } - } - } - return false - -} diff --git a/scan/scan.go b/scan/scan.go deleted file mode 100644 index 0bad8b2d4..000000000 --- a/scan/scan.go +++ /dev/null @@ -1,493 +0,0 @@ -package scan - -import ( - "bufio" - "bytes" - "fmt" - "io" - "os" - "strings" - "sync" - "time" - - "github.com/zricethezav/gitleaks/v6/manager" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - fdiff "github.com/go-git/go-git/v5/plumbing/format/diff" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/sergi/go-diff/diffmatchpatch" - log "github.com/sirupsen/logrus" -) - -// Bundle contains various git information for scans. -type Bundle struct { - Commit *object.Commit - Patch string - Content string - FilePath string - Operation fdiff.Operation - - reader io.Reader - lineLookup map[string]bool - scanType int -} - -// commitScanner is a function signature for scanning commits. There is some -// redundant work needed by scanning all files at a commit (--files-at-commit=) and scanning -// the patches generated by a commit (--commit=). The function scanCommit wraps that redundant work -// and accepts a commitScanner for the different logic needed between the two cases described above. -type commitScanner func(c *object.Commit, repo *Repo) error - -const ( - // We need to differentiate between scans as the logic for line searching is different between - // scanning patches, commits, and uncommitted files. - patchScan int = iota + 1 - uncommittedScan - commitScan -) - -// Scan is responsible for scanning the entire history (default behavior) of a -// git repo. Options that can change the behavior of this function include: --Commit, --depth, --branch. -// See options/options.go for an explanation on these options. -func (repo *Repo) Scan() error { - if err := repo.setupTimeout(); err != nil { - return err - } - if repo.cancel != nil { - defer repo.cancel() - } - - if repo.Repository == nil { - return fmt.Errorf("%s repo is empty", repo.Name) - } - - // load up alternative config if possible, if not use manager's config - if repo.Manager.Opts.RepoConfig { - cfg, err := repo.loadRepoConfig() - if err != nil { - return err - } - repo.config = cfg - } - - scanTimeStart := time.Now() - - // See https://github.com/zricethezav/gitleaks/issues/326 - // Scan commit patches, all files at a commit, or a range of commits - if repo.Manager.Opts.Commit != "" { - return scanCommit(repo.Manager.Opts.Commit, repo, scanCommitPatches) - } else if repo.Manager.Opts.FilesAtCommit != "" { - return scanCommit(repo.Manager.Opts.FilesAtCommit, repo, scanFilesAtCommit) - } else if repo.Manager.Opts.Commits != "" { - commits := strings.Split(repo.Manager.Opts.Commits, ",") - for _, c := range commits { - err := scanCommit(c, repo, scanCommitPatches) - if err != nil { - return err - } - } - return nil - } else if repo.Manager.Opts.CommitsFile != "" { - file, err := os.Open(repo.Manager.Opts.CommitsFile) - if err != nil { - return err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - err := scanCommit(scanner.Text(), repo, scanCommitPatches) - if err != nil { - return err - } - } - return nil - } - - logOpts, err := getLogOptions(repo) - if err != nil { - return err - } - cIter, err := repo.Log(logOpts) - if err != nil { - return err - } - - cc := 0 - semaphore := make(chan bool, howManyThreads(repo.Manager.Opts.Threads)) - wg := sync.WaitGroup{} - err = cIter.ForEach(func(c *object.Commit) error { - if c == nil || repo.timeoutReached() || repo.depthReached(cc) { - return storer.ErrStop - } - - // Check if Commit is allowlisted - if isCommitAllowListed(c.Hash.String(), repo.config.Allowlist.Commits) { - return nil - } - - // Check if at root - if len(c.ParentHashes) == 0 { - cc++ - err = scanFilesAtCommit(c, repo) - if err != nil { - return err - } - return nil - } - - // increase Commit counter - cc++ - - // inspect first parent only as all other parents will be eventually reached - // (they exist as the tip of other branches, etc) - // See https://github.com/zricethezav/gitleaks/issues/413 for details - parent, err := c.Parent(0) - if err != nil { - return err - } - - defer func() { - if err := recover(); err != nil { - // sometimes the Patch generation will fail due to a known bug in - // sergi's go-diff: https://github.com/sergi/go-diff/issues/89. - // Once a fix has been merged I will remove this recover. - return - } - }() - if repo.timeoutReached() { - return nil - } - if parent == nil { - // shouldn't reach this point but just in case - return nil - } - - start := time.Now() - patch, err := parent.Patch(c) - if err != nil { - log.Errorf("could not generate Patch") - } - repo.Manager.RecordTime(manager.PatchTime(howLong(start))) - - wg.Add(1) - semaphore <- true - go func(c *object.Commit, patch *object.Patch) { - defer func() { - <-semaphore - wg.Done() - }() - scanPatch(patch, c, repo) - }(c, patch) - - if c.Hash.String() == repo.Manager.Opts.CommitTo { - return storer.ErrStop - } - return nil - }) - - wg.Wait() - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - repo.Manager.IncrementCommits(cc) - return nil -} - -// scanEmpty scans an empty repo without any commits. See https://github.com/zricethezav/gitleaks/issues/352 -func (repo *Repo) scanEmpty() error { - scanTimeStart := time.Now() - wt, err := repo.Worktree() - if err != nil { - return err - } - - status, err := wt.Status() - if err != nil { - return err - } - for fn := range status { - workTreeBuf := bytes.NewBuffer(nil) - workTreeFile, err := wt.Filesystem.Open(fn) - if err != nil { - continue - } - if _, err := io.Copy(workTreeBuf, workTreeFile); err != nil { - return err - } - repo.CheckRules(&Bundle{ - Content: workTreeBuf.String(), - FilePath: workTreeFile.Name(), - Commit: emptyCommit(), - scanType: uncommittedScan, - }) - } - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - return nil -} - -// scanUncommitted will do a `git diff` and scan changed files that are being tracked. This is useful functionality -// for a pre-Commit hook so you can make sure your code does not have any leaks before committing. -func (repo *Repo) scanUncommitted() error { - // load up alternative config if possible, if not use manager's config - if repo.Manager.Opts.RepoConfig { - cfg, err := repo.loadRepoConfig() - if err != nil { - return err - } - repo.config = cfg - } - - if err := repo.setupTimeout(); err != nil { - return err - } - - r, err := repo.Head() - if err == plumbing.ErrReferenceNotFound { - // possibly an empty repo, or maybe its not, either way lets scan all the files in the directory - return repo.scanEmpty() - } else if err != nil { - return err - } - - scanTimeStart := time.Now() - - c, err := repo.CommitObject(r.Hash()) - if err != nil { - return err - } - // Staged change so the Commit details do not yet exist. Insert empty defaults. - c.Hash = plumbing.Hash{} - c.Message = "***STAGED CHANGES***" - c.Author.Name = "" - c.Author.Email = "" - c.Author.When = time.Unix(0, 0).UTC() - - prevTree, err := c.Tree() - if err != nil { - return err - } - wt, err := repo.Worktree() - if err != nil { - return err - } - - status, err := wt.Status() - for fn, state := range status { - var ( - prevFileContents string - currFileContents string - filename string - ) - - if state.Staging != git.Untracked { - if state.Staging == git.Deleted { - // file in staging has been deleted, aka it is not on the filesystem - // so the contents of the file are "" - currFileContents = "" - } else { - workTreeBuf := bytes.NewBuffer(nil) - workTreeFile, err := wt.Filesystem.Open(fn) - if err != nil { - continue - } - if _, err := io.Copy(workTreeBuf, workTreeFile); err != nil { - return err - } - currFileContents = workTreeBuf.String() - filename = workTreeFile.Name() - } - - // get files at HEAD state - prevFile, err := prevTree.File(fn) - if err != nil { - prevFileContents = "" - - } else { - prevFileContents, err = prevFile.Contents() - if err != nil { - return err - } - if filename == "" { - filename = prevFile.Name - } - } - - dmp := diffmatchpatch.New() - diffs := dmp.DiffCleanupSemantic(dmp.DiffMain(prevFileContents, currFileContents, false)) - var diffContents string - for _, d := range diffs { - if d.Type == diffmatchpatch.DiffInsert { - diffContents += fmt.Sprintf("%s\n", d.Text) - } - } - repo.CheckRules(&Bundle{ - Content: diffContents, - FilePath: filename, - Commit: c, - scanType: uncommittedScan, - }) - } - } - - if err != nil { - return err - } - repo.Manager.RecordTime(manager.ScanTime(howLong(scanTimeStart))) - return nil -} - -// scan accepts a Patch, Commit, and repo. If the patches contains files that are -// binary, then gitleaks will skip scanning that file OR if a file is matched on -// allowlisted files set in the configuration. If a global rule for files is defined and a filename -// matches said global rule, then a leak is sent to the manager. -// After that, file chunks are created which are then inspected by InspectString() -func scanPatch(patch *object.Patch, c *object.Commit, repo *Repo) { - bundle := Bundle{ - Commit: c, - Patch: patch.String(), - scanType: patchScan, - } - for _, f := range patch.FilePatches() { - if repo.timeoutReached() { - return - } - if f.IsBinary() { - continue - } - for _, chunk := range f.Chunks() { - if chunk.Type() == fdiff.Add || (repo.Manager.Opts.Deletion && chunk.Type() == fdiff.Delete) { - bundle.Content = chunk.Content() - bundle.Operation = chunk.Type() - - // get filepath - from, to := f.Files() - if from != nil { - bundle.FilePath = from.Path() - } else if to != nil { - bundle.FilePath = to.Path() - } else { - bundle.FilePath = "???" - } - repo.CheckRules(&bundle) - } - } - } -} - -// scanCommit accepts a Commit hash, repo, and commit scanning function. A new Commit -// object will be created from the hash which will be passed into either scanCommitPatches -// or scanFilesAtCommit depending on the options set. -func scanCommit(commit string, repo *Repo, f commitScanner) error { - if commit == "latest" { - ref, err := repo.Repository.Head() - if err != nil { - return err - } - commit = ref.Hash().String() - } - repo.Manager.IncrementCommits(1) - h := plumbing.NewHash(commit) - c, err := repo.CommitObject(h) - if err != nil { - return err - } - return f(c, repo) -} - -// scanCommitPatches accepts a Commit object and a repo. This function is only called when the --Commit= -// option has been set. That option tells gitleaks to look only at a single Commit and check the contents -// of said Commit. Similar to scan(), if the files contained in the Commit are a binaries or if they are -// allowlisted then those files will be skipped. -func scanCommitPatches(c *object.Commit, repo *Repo) error { - if len(c.ParentHashes) == 0 { - err := scanFilesAtCommit(c, repo) - if err != nil { - return err - } - } - - return c.Parents().ForEach(func(parent *object.Commit) error { - defer func() { - if err := recover(); err != nil { - // sometimes the Patch generation will fail due to a known bug in - // sergi's go-diff: https://github.com/sergi/go-diff/issues/89. - // Once a fix has been merged I will remove this recover. - return - } - }() - if repo.timeoutReached() { - return nil - } - if parent == nil { - return nil - } - start := time.Now() - patch, err := parent.Patch(c) - if err != nil { - return fmt.Errorf("could not generate Patch") - } - repo.Manager.RecordTime(manager.PatchTime(howLong(start))) - - scanPatch(patch, c, repo) - - return nil - }) -} - -// scanFilesAtCommit accepts a Commit object and a repo. This function is only called when the --files-at-Commit= -// option has been set. That option tells gitleaks to look only at ALL the files at a Commit and check the contents -// of said Commit. Similar to scan(), if the files contained in the Commit are a binaries or if they are -// allowlisted then those files will be skipped. -func scanFilesAtCommit(c *object.Commit, repo *Repo) error { - fIter, err := c.Files() - if err != nil { - return err - } - - err = fIter.ForEach(func(f *object.File) error { - bin, err := f.IsBinary() - if bin || repo.timeoutReached() { - return nil - } else if err != nil { - return err - } - - content, err := f.Contents() - if err != nil { - return err - } - - repo.CheckRules(&Bundle{ - Content: content, - FilePath: f.Name, - Commit: c, - scanType: commitScan, - Operation: fdiff.Add, - }) - return nil - }) - return err -} - -// depthReached checks if i meets the depth (--depth=) if set -func (repo *Repo) depthReached(i int) bool { - if repo.Manager.Opts.Depth != 0 && repo.Manager.Opts.Depth == i { - log.Warnf("Exceeded depth limit (%d)", i) - return true - } - return false -} - -// emptyCommit generates an empty commit used for scanning uncommitted changes -func emptyCommit() *object.Commit { - return &object.Commit{ - Hash: plumbing.Hash{}, - Message: "***STAGED CHANGES***", - Author: object.Signature{ - Name: "", - Email: "", - When: time.Unix(0, 0).UTC(), - }, - } -} diff --git a/scan/scan_test.go b/scan/scan_test.go deleted file mode 100644 index 210c035fa..000000000 --- a/scan/scan_test.go +++ /dev/null @@ -1,628 +0,0 @@ -package scan - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "reflect" - "runtime" - "sort" - "testing" - - "github.com/zricethezav/gitleaks/v6/config" - "github.com/zricethezav/gitleaks/v6/manager" - "github.com/zricethezav/gitleaks/v6/options" - - "github.com/sergi/go-diff/diffmatchpatch" -) - -const testRepoBase = "../test_data/test_repos/" - -func TestScan(t *testing.T) { - moveDotGit("dotGit", ".git") - defer moveDotGit(".git", "dotGit") - tests := []struct { - description string - opts options.Options - wantPath string - wantErr error - emptyRepo bool - wantEmpty bool - }{ - { - description: "test local repo one aws leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test local repo one aws leak threaded", - opts: options.Options{ - Threads: runtime.GOMAXPROCS(0), - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test non existent repo", - opts: options.Options{ - RepoPath: "../test_data/test_repos/no_repo_here", - ReportFormat: "json", - }, - emptyRepo: true, - }, - { - description: "test local repo one aws leak allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - ReportFormat: "json", - Config: "../test_data/test_configs/aws_key_allowlist_python_files.toml", - }, - wantEmpty: true, - }, - { - description: "test local repo two leaks", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_two_leaks.json", - }, - { - description: "test local repo two leaks from Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_from.json.got", - ReportFormat: "json", - CommitFrom: "996865bb912f3bc45898a370a13aadb315014b55", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_from.json", - }, - { - description: "test local repo two leaks to Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_to.json.got", - ReportFormat: "json", - CommitTo: "996865bb912f3bc45898a370a13aadb315014b55", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_to.json", - }, - { - description: "test local repo two leaks to from Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_to_from.json.got", - ReportFormat: "json", - CommitFrom: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a", - CommitTo: "51f6dcf6b89b93f4075ba92c400b075631a6cc93", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_to_from.json", - }, - { - description: "test local repo two leaks list Commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_commit_range.json.got", - ReportFormat: "json", - Commits: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a,996865bb912f3bc45898a370a13aadb315014b55,17471a5fda722a9e423f1a0d3f0d267ea009d41c,51f6dcf6b89b93f4075ba92c400b075631a6cc93,b10b3e2cb320a8c211fda94c4567299d37de7776", - }, - wantPath: "../test_data/test_local_repo_two_leaks_commit_range.json", - }, - { - description: "test local repo two leaks file list commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_file_commit_range.json.got", - ReportFormat: "json", - CommitsFile: "../test_data/test_options/test_local_repo_commits.txt", - }, - wantPath: "../test_data/test_local_repo_two_leaks_file_commit_range.json", - }, - { - description: "test local repo two leaks globally allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Config: "../test_data/test_configs/aws_key_global_allowlist_file.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo two leaks allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Config: "../test_data/test_configs/aws_key_allowlist_files.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo three leaks dev branch", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_3", - Report: "../test_data/test_local_repo_three_leaks.json.got", - Config: "../test_data/test_configs/aws_key.toml", - Branch: "dev", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_three_leaks.json", - }, - { - description: "test local repo branch does not exist", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_3", - Branch: "nobranch", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak single Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_commit.json.got", - Commit: "6557c92612d3b35979bd426d429255b3bf9fab74", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_commit.json", - }, - { - description: "test local repo one aws leak AND leak on python files", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json.got", - Config: "../test_data/test_configs/aws_key_file_regex.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json", - }, - { - description: "test owner path", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_owner_aws_leak.json", - }, - { - description: "test owner path allowlist repo", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak_allowlist_repo.json.got", - ReportFormat: "json", - Config: "../test_data/test_configs/aws_key_local_owner_allowlist_repo.toml", - }, - wantPath: "../test_data/test_local_owner_aws_leak_allowlist_repo.json", - }, - { - description: "test entropy and regex", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_regex_entropy.json.got", - Config: "../test_data/test_configs/regex_entropy.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_regex_entropy.json", - }, - { - description: "test local repo four entropy alternative config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_4", - Report: "../test_data/test_local_repo_four_alt_config_entropy.json.got", - RepoConfig: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_four_alt_config_entropy.json", - }, - { - description: "test local repo four entropy alternative config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_regex_allowlist.json.got", - Config: "../test_data/test_configs/aws_key_aws_allowlisted.toml", - ReportFormat: "json", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak timeout", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - Timeout: "10ns", - }, - wantEmpty: true, - }, - { - description: "test local repo one aws leak long timeout", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak.json.got", - ReportFormat: "json", - Timeout: "2m", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak.json", - }, - { - description: "test owner path depth=2", - opts: options.Options{ - OwnerPath: "../test_data/test_repos/", - Report: "../test_data/test_local_owner_aws_leak_depth_2.json.got", - ReportFormat: "json", - Depth: 2, - }, - wantPath: "../test_data/test_local_owner_aws_leak_depth_2.json", - }, - { - description: "test local repo five files at Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_files_at_commit.json.got", - FilesAtCommit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_five_files_at_commit.json", - }, - { - description: "test local repo five files at latest Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_files_at_latest_commit.json.got", - FilesAtCommit: "latest", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_five_files_at_commit.json", - }, - { - description: "test local repo five at Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_commit.json.got", - Commit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - ReportFormat: "json", - Config: "../test_data/test_configs/generic.toml", - }, - wantPath: "../test_data/test_local_repo_five_commit.json", - }, - { - description: "test local repo five at latest Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_5", - Report: "../test_data/test_local_repo_five_at_latest_commit.json.got", - Commit: "latest", - ReportFormat: "json", - Config: "../test_data/test_configs/generic.toml", - }, - wantPath: "../test_data/test_local_repo_five_at_latest_commit.json", - }, - { - description: "test local repo six filename", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filename.json.got", - Config: "../test_data/test_configs/regex_filename.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filename.json", - }, - { - description: "test local repo six filepath", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filepath.json.got", - Config: "../test_data/test_configs/regex_filepath.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filepath.json", - }, - { - description: "test local repo six filename and filepath", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_filepath_filename.json.got", - Config: "../test_data/test_configs/regex_filepath_filename.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_filepath_filename.json", - }, - { - description: "test local repo six path globally allowlisted", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_path_globally_allowlisted.json.got", - Config: "../test_data/test_configs/aws_key_global_allowlist_path.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_six_path_globally_allowlisted.json", - }, - { - description: "test local repo six leaks since date", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_leaks_since_date.json.got", - ReportFormat: "json", - CommitSince: "2019-10-25", - }, - wantPath: "../test_data/test_local_repo_six_leaks_since_date.json", - }, - { - description: "test local repo two leaks until date", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_6", - Report: "../test_data/test_local_repo_six_leaks_until_date.json.got", - ReportFormat: "json", - CommitUntil: "2019-10-25", - }, - wantPath: "../test_data/test_local_repo_six_leaks_until_date.json", - }, - { - description: "test local repo four leaks timerange Commit", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_4", - Report: "../test_data/test_local_repo_four_leaks_commit_timerange.json.got", - ReportFormat: "json", - CommitSince: "2019-10-25T13:01:27-0400", - CommitUntil: "2019-10-25T13:12:32-0400", - }, - wantPath: "../test_data/test_local_repo_four_leaks_commit_timerange.json", - }, - { - description: "test local repo two allowlist Commit config", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_allowlist_commits.json.got", - Config: "../test_data/test_configs/allowlist_commit.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_two_allowlist_commits.json", - }, - { - description: "test local repo two deletion", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_2", - Report: "../test_data/test_local_repo_two_leaks_deletion.json.got", - ReportFormat: "json", - Deletion: true, - }, - wantPath: "../test_data/test_local_repo_two_leaks_deletion.json", - }, - { - description: "test local repo eight (merges)", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_8", - Report: "../test_data/test_local_repo_eight.json.got", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_eight.json", - }, - { - description: "test local repo nine", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_9", - Report: "../test_data/test_local_repo_nine_aws_leak.json.got", - Config: "../test_data/test_configs/large_with_global_allowlist_regex.toml", - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_nine_aws_leak.json", - }, - } - - for _, test := range tests { - fmt.Println(test.description) - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - - err = Run(m) - - if test.wantErr != nil { - if err == nil { - t.Errorf("did not receive wantErr: %v", test.wantErr) - } - if err.Error() != test.wantErr.Error() { - t.Errorf("wantErr does not equal err received: %v", err.Error()) - } - continue - } - - err = m.Report() - if err != nil { - t.Error(err) - } - - if test.wantEmpty { - if len(m.GetLeaks()) != 0 { - t.Errorf("wanted no leaks but got some instead: %+v", m.GetLeaks()) - } - continue - } - - if test.wantPath != "" { - err := fileCheck(test.wantPath, test.opts.Report) - if err != nil { - t.Error(err) - } - } - } -} - -func TestScanUncommited(t *testing.T) { - moveDotGit("dotGit", ".git") - defer moveDotGit(".git", "dotGit") - tests := []struct { - description string - opts options.Options - wantPath string - wantErr error - emptyRepo bool - wantEmpty bool - fileToChange string - addition string - }{ - { - description: "test scan local one leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Report: "../test_data/test_local_repo_one_aws_leak_uncommitted.json.got", - Uncommited: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_one_aws_leak_uncommitted.json", - fileToChange: "server.test.py", - addition: " aws_access_key_id='AKIAIO5FODNN7DXAMPLE'\n\n", - }, - { - description: "test scan local no leak", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_1", - Uncommited: true, - ReportFormat: "json", - }, - wantEmpty: true, - fileToChange: "server.test.py", - addition: "nothing bad", - }, - { - description: "test scan repo with no commits", - opts: options.Options{ - RepoPath: "../test_data/test_repos/test_repo_7", - Report: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json.got", - Uncommited: true, - ReportFormat: "json", - }, - wantPath: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json", - }, - } - for _, test := range tests { - var ( - old []byte - err error - ) - fmt.Println(test.description) - if test.fileToChange != "" { - old, err = ioutil.ReadFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange)) - if err != nil { - t.Error(err) - } - altered, err := os.OpenFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange), - os.O_WRONLY|os.O_APPEND, 0644) - if err != nil { - t.Error(err) - } - - _, err = altered.WriteString(test.addition) - if err != nil { - t.Error(err) - } - - } - - cfg, err := config.NewConfig(test.opts) - if err != nil { - t.Error(err) - } - m, err := manager.NewManager(test.opts, cfg) - if err != nil { - t.Error(err) - } - - if err := Run(m); err != nil { - t.Error(err) - } - - if err := m.Report(); err != nil { - t.Error(err) - } - - if test.fileToChange != "" { - err = ioutil.WriteFile(fmt.Sprintf("%s/%s", test.opts.RepoPath, test.fileToChange), old, 0) - if err != nil { - t.Error(err) - } - } - - if test.wantEmpty { - continue - } - - if test.wantPath != "" { - err := fileCheck(test.wantPath, test.opts.Report) - if err != nil { - t.Error(err) - } - } - } -} - -func fileCheck(wantPath, gotPath string) error { - var ( - gotLeaks []manager.Leak - wantLeaks []manager.Leak - ) - want, err := ioutil.ReadFile(wantPath) - if err != nil { - return err - } - - got, err := ioutil.ReadFile(gotPath) - if err != nil { - return err - } - - err = json.Unmarshal(got, &gotLeaks) - if err != nil { - return err - } - - err = json.Unmarshal(want, &wantLeaks) - if err != nil { - return nil - } - - sort.Slice(gotLeaks, func(i, j int) bool { return (gotLeaks)[i].Commit < (gotLeaks)[j].Commit }) - sort.Slice(wantLeaks, func(i, j int) bool { return (wantLeaks)[i].Commit < (wantLeaks)[j].Commit }) - - if !reflect.DeepEqual(gotLeaks, wantLeaks) { - dmp := diffmatchpatch.New() - diffs := dmp.DiffMain(string(want), string(got), false) - return fmt.Errorf("%s does not equal %s: %s", wantPath, gotPath, dmp.DiffPrettyText(diffs)) - } - if err := os.Remove(gotPath); err != nil { - return err - } - return nil -} - -func moveDotGit(from, to string) error { - repoDirs, err := ioutil.ReadDir("../test_data/test_repos") - if err != nil { - return err - } - for _, dir := range repoDirs { - if !dir.IsDir() { - continue - } - err = os.Rename(fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), from), - fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), to)) - if err != nil { - return err - } - } - return nil -} diff --git a/scripts/pre-commit.py b/scripts/pre-commit.py new file mode 100644 index 000000000..64d48d595 --- /dev/null +++ b/scripts/pre-commit.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +"""Helper script to be used as a pre-commit hook.""" +import os +import sys +import subprocess + + +def gitleaksEnabled(): + """Determine if the pre-commit hook for gitleaks is enabled.""" + out = subprocess.getoutput("git config --bool hooks.gitleaks") + if out == "false": + return False + return True + + +if gitleaksEnabled(): + exitCode = os.WEXITSTATUS(os.system('gitleaks protect -v --staged')) + if exitCode == 1: + print('''Warning: gitleaks has detected sensitive information in your changes. +To disable the gitleaks precommit hook run the following command: + + git config hooks.gitleaks false +''') + sys.exit(1) +else: + print('gitleaks precommit disabled\ + (enable with `git config hooks.gitleaks true`)') diff --git a/test_data/test_configs/allowlist_commit.toml b/test_data/test_configs/allowlist_commit.toml deleted file mode 100644 index 9ee75ea2e..000000000 --- a/test_data/test_configs/allowlist_commit.toml +++ /dev/null @@ -1,13 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - - -[allowlist] - commits = [ - "b10b3e2cb320a8c211fda94c4567299d37de7776", - "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "996865bb912f3bc45898a370a13aadb315014b55" - ] - diff --git a/test_data/test_configs/aws_key.toml b/test_data/test_configs/aws_key.toml deleted file mode 100644 index a781099bc..000000000 --- a/test_data/test_configs/aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/aws_key_allowlist_files.toml b/test_data/test_configs/aws_key_allowlist_files.toml deleted file mode 100644 index 5dc6608e4..000000000 --- a/test_data/test_configs/aws_key_allowlist_files.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore sample regex md files" - files = ['''(.*)?md$'''] - regexes = ['''ignore$'''] diff --git a/test_data/test_configs/aws_key_allowlist_python_files.toml b/test_data/test_configs/aws_key_allowlist_python_files.toml deleted file mode 100644 index c33012029..000000000 --- a/test_data/test_configs/aws_key_allowlist_python_files.toml +++ /dev/null @@ -1,7 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore python files" - files = ['''(.*)?py$'''] diff --git a/test_data/test_configs/aws_key_aws_allowlisted.toml b/test_data/test_configs/aws_key_aws_allowlisted.toml deleted file mode 100644 index e8d7cf6d7..000000000 --- a/test_data/test_configs/aws_key_aws_allowlisted.toml +++ /dev/null @@ -1,7 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore aws key" - regexes = ['''AKIAIO5FODNN7EXAMPLE.*'''] diff --git a/test_data/test_configs/aws_key_file_regex.toml b/test_data/test_configs/aws_key_file_regex.toml deleted file mode 100644 index 5af8aa2ea..000000000 --- a/test_data/test_configs/aws_key_file_regex.toml +++ /dev/null @@ -1,14 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -## this is an example of a rule that won't work -[[rules]] - description = "Python files" - fileRegex = "(?i)*.py" diff --git a/test_data/test_configs/aws_key_global_allowlist_file.toml b/test_data/test_configs/aws_key_global_allowlist_file.toml deleted file mode 100644 index 35f7b65d6..000000000 --- a/test_data/test_configs/aws_key_global_allowlist_file.toml +++ /dev/null @@ -1,10 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[allowlist] - description = "ignore md files" - files = [ - '''(.*)?md$''' - ] \ No newline at end of file diff --git a/test_data/test_configs/aws_key_global_allowlist_path.toml b/test_data/test_configs/aws_key_global_allowlist_path.toml deleted file mode 100644 index 9b2fd0877..000000000 --- a/test_data/test_configs/aws_key_global_allowlist_path.toml +++ /dev/null @@ -1,10 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[allowlist] - description = "ignore config folders" - paths = [ - '''config(uration)?''' - ] \ No newline at end of file diff --git a/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml b/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml deleted file mode 100644 index 93877130f..000000000 --- a/test_data/test_configs/aws_key_local_owner_allowlist_repo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [allowlist] - description = "allowlist repo" - repos = [ - '''test_repo_1''' - ] diff --git a/test_data/test_configs/bad_aws_key.toml b/test_data/test_configs/bad_aws_key.toml deleted file mode 100644 index 15d691cc9..000000000 --- a/test_data/test_configs/bad_aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/bad_aws_key_file_regex.toml b/test_data/test_configs/bad_aws_key_file_regex.toml deleted file mode 100644 index 624d1a71b..000000000 --- a/test_data/test_configs/bad_aws_key_file_regex.toml +++ /dev/null @@ -1,13 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - -[Global] - file = '''?????????????''' - diff --git a/test_data/test_configs/bad_entropy_1.toml b/test_data/test_configs/bad_entropy_1.toml deleted file mode 100644 index 36aba7cb8..000000000 --- a/test_data/test_configs/bad_entropy_1.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "4.1" - diff --git a/test_data/test_configs/bad_entropy_2.toml b/test_data/test_configs/bad_entropy_2.toml deleted file mode 100644 index adae692da..000000000 --- a/test_data/test_configs/bad_entropy_2.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.3" - Max = "x" - diff --git a/test_data/test_configs/bad_entropy_3.toml b/test_data/test_configs/bad_entropy_3.toml deleted file mode 100644 index e063ec52e..000000000 --- a/test_data/test_configs/bad_entropy_3.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "x" - Max = "4.1" - diff --git a/test_data/test_configs/bad_entropy_4.toml b/test_data/test_configs/bad_entropy_4.toml deleted file mode 100644 index 2b8e189d8..000000000 --- a/test_data/test_configs/bad_entropy_4.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8" - Group = "x" - diff --git a/test_data/test_configs/bad_entropy_5.toml b/test_data/test_configs/bad_entropy_5.toml deleted file mode 100644 index 6e99b792f..000000000 --- a/test_data/test_configs/bad_entropy_5.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "-2" - diff --git a/test_data/test_configs/bad_entropy_6.toml b/test_data/test_configs/bad_entropy_6.toml deleted file mode 100644 index b6601fc70..000000000 --- a/test_data/test_configs/bad_entropy_6.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "2" - diff --git a/test_data/test_configs/bad_entropy_7.toml b/test_data/test_configs/bad_entropy_7.toml deleted file mode 100644 index ff72eccba..000000000 --- a/test_data/test_configs/bad_entropy_7.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "1.0" - Max = "8.5" - Group = "0" - diff --git a/test_data/test_configs/bad_regex_aws_key.toml b/test_data/test_configs/bad_regex_aws_key.toml deleted file mode 100644 index 47ebe941a..000000000 --- a/test_data/test_configs/bad_regex_aws_key.toml +++ /dev/null @@ -1,9 +0,0 @@ -[[rules]] - description = "AWS Secret Key" - regex = '''$$$???$$$??$?$?$''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/entropy.toml b/test_data/test_configs/entropy.toml deleted file mode 100644 index f3b4ffdbf..000000000 --- a/test_data/test_configs/entropy.toml +++ /dev/null @@ -1,11 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{40,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "4.7" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" - diff --git a/test_data/test_configs/generic.toml b/test_data/test_configs/generic.toml deleted file mode 100644 index 22884cd94..000000000 --- a/test_data/test_configs/generic.toml +++ /dev/null @@ -1,4 +0,0 @@ -[[rules]] - description = "Generic Credential" - regex = '''(?i)(api_key|apikey|secret|password|pass|pw|key)(.{0,20})?[0-9a-zA-Z]{16,45}''' - tags = ["key", "API", "generic"] \ No newline at end of file diff --git a/test_data/test_configs/large.toml b/test_data/test_configs/large.toml deleted file mode 100644 index 78c3a50ca..000000000 --- a/test_data/test_configs/large.toml +++ /dev/null @@ -1,148 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - -[[rules]] - description = "Generic API key" - regex = '''(?i)(api_key|apikey)(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Generic Secret" - regex = '''(?i)secret(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "Secret", "generic"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore common jenkins functions" - regexes = [ - '''allowlistme''' - ] - files = [ - '''(.*)?Jenkinsfile$''' - ] - -# Global rules. This instructs gitleaks to ignore all .pem files or if a message with -[[rules]] - description = "Files with keys and credentials" - file = '''(.*?)(pem)''' - -[allowlist] - description = "File allowlists" - files = [ - '''(.*?)(jpg|gif)$''', - '''(.*?)(doc|pdf|bin)$''' - ] - diff --git a/test_data/test_configs/large_with_global_allowlist_regex.toml b/test_data/test_configs/large_with_global_allowlist_regex.toml deleted file mode 100644 index 1d63f47da..000000000 --- a/test_data/test_configs/large_with_global_allowlist_regex.toml +++ /dev/null @@ -1,151 +0,0 @@ -title = "gitleaks config" - -[[rules]] - description = "AWS Secret Key" - regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' - tags = ["key", "AWS"] - -[[rules]] - description = "AWS MWS key" - regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' - tags = ["key", "AWS", "MWS"] - -[[rules]] - description = "Facebook Secret Key" - regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Facebook Client ID" - regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' - tags = ["key", "Facebook"] - -[[rules]] - description = "Twitter Secret Key" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' - tags = ["key", "Twitter"] - -[[rules]] - description = "Twitter Client ID" - regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' - tags = ["client", "Twitter"] - -[[rules]] - description = "Github" - regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' - tags = ["key", "Github"] - -[[rules]] - description = "LinkedIn Client ID" - regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' - tags = ["client", "LinkedIn"] - -[[rules]] - description = "LinkedIn Secret Key" - regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' - tags = ["secret", "LinkedIn"] - -[[rules]] - description = "Slack" - regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' - tags = ["key", "Slack"] - -[[rules]] - description = "EC" - regex = '''-----BEGIN EC PRIVATE KEY-----''' - tags = ["key", "EC"] - -[[rules]] - description = "Generic API key" - regex = '''(?i)(api_key|apikey)(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "API", "generic"] - -[[rules]] - description = "Generic Secret" - regex = '''(?i)secret(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' - tags = ["key", "Secret", "generic"] - -[[rules]] - description = "Google API key" - regex = '''AIza[0-9A-Za-z\\-_]{35}''' - tags = ["key", "Google"] - - -[[rules]] - description = "Heroku API key" - regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' - tags = ["key", "Heroku"] - -[[rules]] - description = "MailChimp API key" - regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' - tags = ["key", "Mailchimp"] - -[[rules]] - description = "Mailgun API key" - regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' - tags = ["key", "Mailgun"] - -[[rules]] - description = "PayPal Braintree access token" - regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' - tags = ["key", "Paypal"] - -[[rules]] - description = "Picatic API key" - regex = '''sk_live_[0-9a-z]{32}''' - tags = ["key", "Picatic"] - -[[rules]] - description = "Slack Webhook" - regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' - tags = ["key", "slack"] - -[[rules]] - description = "Stripe API key" - regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' - tags = ["key", "Stripe"] - -[[rules]] - description = "Square access token" - regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' - tags = ["key", "square"] - -[[rules]] - description = "Square OAuth secret" - regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' - tags = ["key", "square"] - -[[rules]] - description = "Twilio API key" - regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' - tags = ["key", "twilio"] - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - tags = ["key", "AWS"] - [rules.allowlist] - description = "ignore common jenkins functions" - regexes = [ - '''allowlistme''' - ] - files = [ - '''(.*)?Jenkinsfile$''' - ] - -[[rules]] - description = "Files with keys and credentials" - file = '''(.*?)(pem)''' - -# Global allowlist -[allowlist] - description = "global allowlists" - files = [ - '''(.*?)(jpg|gif)$''', - '''(.*?)(doc|pdf|bin)$''' - ] - regexes = [ - '''(.*?)gitleaks:allow''' - ] - diff --git a/test_data/test_configs/regex_entropy.toml b/test_data/test_configs/regex_entropy.toml deleted file mode 100644 index 2cac46ee1..000000000 --- a/test_data/test_configs/regex_entropy.toml +++ /dev/null @@ -1,14 +0,0 @@ -[[rules]] - description = "entropy and regex" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "4.5" - Max = "4.7" - Group = "1" - [[rules.Entropies]] - Min = "5.5" - Max = "6.3" - Group = "1" - - diff --git a/test_data/test_configs/regex_filename.toml b/test_data/test_configs/regex_filename.toml deleted file mode 100644 index a9b9cd2f8..000000000 --- a/test_data/test_configs/regex_filename.toml +++ /dev/null @@ -1,6 +0,0 @@ - -[[rules]] - description = "Generic password" - regex = '''(?i)(password|token).{0,20}?\s*[:|=]\s*?(?-i)([0-9a-zA-Z\/+]{4,40})''' - file = '''.*\.ya?ml''' - tags = ["key", "Yml", "Yaml"] diff --git a/test_data/test_configs/regex_filepath.toml b/test_data/test_configs/regex_filepath.toml deleted file mode 100644 index 0d5ce04e5..000000000 --- a/test_data/test_configs/regex_filepath.toml +++ /dev/null @@ -1,6 +0,0 @@ - -[[rules]] - description = "AWS Manager ID" - regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' - path = '''config(guration)?''' - tags = ["key", "AWS"] diff --git a/test_data/test_configs/regex_filepath_filename.toml b/test_data/test_configs/regex_filepath_filename.toml deleted file mode 100644 index d4ab0bbd8..000000000 --- a/test_data/test_configs/regex_filepath_filename.toml +++ /dev/null @@ -1,7 +0,0 @@ - -[[rules]] - description = "Generic password" - regex = '''(?i)(password|token).{0,20}?\s*[:|=]\s*?(?-i)([0-9a-zA-Z\/+]{4,40})''' - file = '''.*\.properties''' - path = '''config(guration)?''' - tags = ["key", "Yml", "Yaml"] diff --git a/test_data/test_entropy.json b/test_data/test_entropy.json deleted file mode 100644 index 4c418cbd4..000000000 --- a/test_data/test_entropy.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "offender": "Entropy range [{P1:4.5 P2:4.7} {P1:5.5 P2:6.3}]", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "entropy", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "entropy" - } -] diff --git a/test_data/test_local_owner_aws_leak.json b/test_data/test_local_owner_aws_leak.json deleted file mode 100644 index e5fbaf14a..000000000 --- a/test_data/test_local_owner_aws_leak.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "1f2a4abc47dabf991e6af6f9770867ce0ac1f360", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:07:34-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_owner_aws_leak_allowlist_repo.json b/test_data/test_local_owner_aws_leak_allowlist_repo.json deleted file mode 100644 index 112f031f0..000000000 --- a/test_data/test_local_owner_aws_leak_allowlist_repo.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "1f2a4abc47dabf991e6af6f9770867ce0ac1f360", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:07:34-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_owner_aws_leak_depth_2.json b/test_data/test_local_owner_aws_leak_depth_2.json deleted file mode 100644 index 42be9a684..000000000 --- a/test_data/test_local_owner_aws_leak_depth_2.json +++ /dev/null @@ -1,107 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "const AWSKEY = \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 4, - "offender": "AKIALALEMEL33243OLIA", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "ca71fcdeda15f25f0cc661d90e8785c255925c27", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "introduce more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:08:04-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE', #gitleaks:allow", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "8d1fb60d2d80f0590f191ed5ace1e45ef780909a", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "gitleaks allow secret\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "server.test.py", - "date": "2020-08-12T13:36:20-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_eight.json b/test_data/test_local_repo_eight.json deleted file mode 100644 index 66673c606..000000000 --- a/test_data/test_local_repo_eight.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "748f11eaf2c38c3cf0ac6a22e44208777e79fa6f", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Merge pull request #1 from zricethezav/additional-secret-branch\n\nUpdate dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:44:48-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 2, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "ce7e8177bbf8a172c06b6a1e370a374d5c19f660", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "dummy.txt w/ text", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:39:11-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 6, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "9267bc86ec1497471cbc6f3308f3527f7ef34b9d", - "repo": "test_repo_8", - "rule": "AWS Manager ID", - "commitMessage": "Update dummy.txt", - "author": "Zachary Rice", - "email": "zricer@protonmail.com", - "file": "dummy.txt", - "date": "2020-07-25T14:41:11-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_at_latest_commit.json b/test_data/test_local_repo_five_at_latest_commit.json deleted file mode 100644 index ce5cf8b33..000000000 --- a/test_data/test_local_repo_five_at_latest_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "more_secrets = '99432bfewaf823ec3294e231'", - "lineNumber": 7, - "offender": "secrets = '99432bfewaf823ec3294e231", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "Generic Credential", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, API, generic", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_commit.json b/test_data/test_local_repo_five_commit.json deleted file mode 100644 index ce5cf8b33..000000000 --- a/test_data/test_local_repo_five_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "more_secrets = '99432bfewaf823ec3294e231'", - "lineNumber": 7, - "offender": "secrets = '99432bfewaf823ec3294e231", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "Generic Credential", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, API, generic", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_files_at_commit.json b/test_data/test_local_repo_five_files_at_commit.json deleted file mode 100644 index 16168a820..000000000 --- a/test_data/test_local_repo_five_files_at_commit.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_five_files_at_latest_commit.json b/test_data/test_local_repo_five_files_at_latest_commit.json deleted file mode 100644 index 16168a820..000000000 --- a/test_data/test_local_repo_five_files_at_latest_commit.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPLE'", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "aws_access_key_id='AKIAIO5FODNN7EXAMPL2'", - "lineNumber": 4, - "offender": "AKIAIO5FODNN7EXAMPL2", - "commit": "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0", - "repo": "test_repo_5", - "rule": "AWS Manager ID", - "commitMessage": "even more secrets\n", - "author": "Zach Rice", - "email": "zrice@gitlab.com", - "file": "secrets.py", - "date": "2020-02-01T10:30:22-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_four_alt_config_entropy.json b/test_data/test_local_repo_four_alt_config_entropy.json deleted file mode 100644 index 6fe84f27d..000000000 --- a/test_data/test_local_repo_four_alt_config_entropy.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "const AWSSECRET = \"99432bfewaf823ec3294e231\"", - "lineNumber": 5, - "offender": "\"99432bfewaf823ec3294e231\"", - "commit": "84ac4e80d4dbf2c968b64e9d4005f5079795bb81", - "repo": "test_repo_4", - "rule": "entropy", - "commitMessage": "more secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:54:08-04:00", - "tags": "entropy", - "operation": "addition" - }, - { - "line": " const AWSSECRET = \"99432bfewaf823ec3294e231\"", - "lineNumber": 6, - "offender": "\"99432bfewaf823ec3294e231\"", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_4", - "rule": "entropy", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "entropy", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_four_leaks_commit_timerange.json b/test_data/test_local_repo_four_leaks_commit_timerange.json deleted file mode 100644 index e7fac1c55..000000000 --- a/test_data/test_local_repo_four_leaks_commit_timerange.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_4", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_4", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_nine_aws_leak.json b/test_data/test_local_repo_nine_aws_leak.json deleted file mode 100644 index ab418b8d9..000000000 --- a/test_data/test_local_repo_nine_aws_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_9", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak.json b/test_data/test_local_repo_one_aws_leak.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_and_file_leak.json b/test_data/test_local_repo_one_aws_leak_and_file_leak.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak_and_file_leak.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_commit.json b/test_data/test_local_repo_one_aws_leak_commit.json deleted file mode 100644 index 80d1ba9ec..000000000 --- a/test_data/test_local_repo_one_aws_leak_commit.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_one_aws_leak_uncommitted.json b/test_data/test_local_repo_one_aws_leak_uncommitted.json deleted file mode 100644 index 620df24aa..000000000 --- a/test_data/test_local_repo_one_aws_leak_uncommitted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7DXAMPLE'", - "lineNumber": 10, - "offender": "AKIAIO5FODNN7DXAMPLE", - "commit": "0000000000000000000000000000000000000000", - "repo": "test_repo_1", - "rule": "AWS Manager ID", - "commitMessage": "***STAGED CHANGES***", - "author": "", - "email": "", - "file": "server.test.py", - "date": "1970-01-01T00:00:00Z", - "tags": "key, AWS", - "operation": "equal" - } -] diff --git a/test_data/test_local_repo_seven_aws_leak_uncommitted.json b/test_data/test_local_repo_seven_aws_leak_uncommitted.json deleted file mode 100644 index b7d1965f7..000000000 --- a/test_data/test_local_repo_seven_aws_leak_uncommitted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "AKIAIO5FODNN7EXAMPLE", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "0000000000000000000000000000000000000000", - "repo": "test_repo_7", - "rule": "AWS Manager ID", - "commitMessage": "***STAGED CHANGES***", - "author": "", - "email": "", - "file": "file", - "date": "1970-01-01T00:00:00Z", - "tags": "key, AWS", - "operation": "equal" - } -] diff --git a/test_data/test_local_repo_six.json b/test_data/test_local_repo_six.json deleted file mode 100644 index 8c0cf9d72..000000000 --- a/test_data/test_local_repo_six.json +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "line": "api_token: exampleSecretPassword", - "lineNumber": 3, - "offender": "token: exampleSecretPassword", - "commit": "e7bf376f855ae9bc6e3bb27b5f9d65c57eba799d", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "More secrets\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/config.yaml", - "date": "2020-02-19T04:08:26-05:00", - "tags": "key, Yml, Yaml" - }, - { - "line": "db_password_token: exampleSecretPassword", - "lineNumber": 3, - "offender": "password_token: exampleSecretPassword", - "commit": "e7bf376f855ae9bc6e3bb27b5f9d65c57eba799d", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "More secrets\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/config.yaml", - "date": "2020-02-19T04:08:26-05:00", - "tags": "key, Yml, Yaml" - }, - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 1, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "95cf0237f8cdfc0686a29df08260d8635f46c9b0", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "AWS Key in properties\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-19T04:04:15-05:00", - "tags": "key, AWS" - } -] diff --git a/test_data/test_local_repo_six_filename.json b/test_data/test_local_repo_six_filename.json deleted file mode 100644 index 00f633ada..000000000 --- a/test_data/test_local_repo_six_filename.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "api_token: exampleSecretPassword", - "lineNumber": 2, - "offender": "token: exampleSecretPassword", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "application.yaml", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - }, - { - "line": "db_password: verySecretProductionPassword", - "lineNumber": 3, - "offender": "password: verySecretProductionPassword", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "application.yaml", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_filepath.json b/test_data/test_local_repo_six_filepath.json deleted file mode 100644 index 31ffd8857..000000000 --- a/test_data/test_local_repo_six_filepath.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_filepath_filename.json b/test_data/test_local_repo_six_filepath_filename.json deleted file mode 100644 index 242da22c1..000000000 --- a/test_data/test_local_repo_six_filepath_filename.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "apiToken=d41d8cd98f00b204e9800998ecf8427e", - "lineNumber": 2, - "offender": "Token=d41d8cd98f00b204e9800998ecf8427e", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "Generic password", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, Yml, Yaml", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_leaks_since_date.json b/test_data/test_local_repo_six_leaks_since_date.json deleted file mode 100644 index 31ffd8857..000000000 --- a/test_data/test_local_repo_six_leaks_since_date.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "aws_access_key_id=AKIAIO5FODNN7EXAMPLE", - "lineNumber": 3, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "98b6c7cb3fb29a5993c4c95c56a2dc53050b9247", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "Adding some secrets in config folder\n\n", - "author": "Noel Algora", - "email": "noealgigu@gmail.com", - "file": "config/application.properties", - "date": "2020-02-24T14:13:15-05:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_leaks_until_date.json b/test_data/test_local_repo_six_leaks_until_date.json deleted file mode 100644 index 9cd7bc61f..000000000 --- a/test_data/test_local_repo_six_leaks_until_date.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_six_path_globally_allowlisted.json b/test_data/test_local_repo_six_path_globally_allowlisted.json deleted file mode 100644 index 9cd7bc61f..000000000 --- a/test_data/test_local_repo_six_path_globally_allowlisted.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_access_key_id='AKIAIO5FODNN7EXAMPLE',", - "lineNumber": 5, - "offender": "AKIAIO5FODNN7EXAMPLE", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_6", - "rule": "AWS Manager ID", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_three_leaks.json b/test_data/test_local_repo_three_leaks.json deleted file mode 100644 index 745242b8a..000000000 --- a/test_data/test_local_repo_three_leaks.json +++ /dev/null @@ -1,62 +0,0 @@ -[ - { - "line": "AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 6, - "offender": "AKIALALEMEL33243OLIA", - "commit": "deea550dd6c7acaf0e59432600593533984a2125", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "dev branch\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:35:03-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_3", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_allowlist_commits.json b/test_data/test_local_repo_two_allowlist_commits.json deleted file mode 100644 index 9e315f6d0..000000000 --- a/test_data/test_local_repo_two_allowlist_commits.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks.json b/test_data/test_local_repo_two_leaks.json deleted file mode 100644 index 39eedddeb..000000000 --- a/test_data/test_local_repo_two_leaks.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_from.json b/test_data/test_local_repo_two_leaks_commit_from.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_commit_from.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_range.json b/test_data/test_local_repo_two_leaks_commit_range.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_commit_range.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_to.json b/test_data/test_local_repo_two_leaks_commit_to.json deleted file mode 100644 index 9e315f6d0..000000000 --- a/test_data/test_local_repo_two_leaks_commit_to.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_commit_to_from.json b/test_data/test_local_repo_two_leaks_commit_to_from.json deleted file mode 100644 index aa4e907d9..000000000 --- a/test_data/test_local_repo_two_leaks_commit_to_from.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_deletion.json b/test_data/test_local_repo_two_leaks_deletion.json deleted file mode 100644 index 57b396e4d..000000000 --- a/test_data/test_local_repo_two_leaks_deletion.json +++ /dev/null @@ -1,92 +0,0 @@ -[ - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIB", - "commit": "f61cd8587b7ac1d75a89a0c9af870a2f24c60263", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "rm secrets again\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:32-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": " const AWSKEY = \"AKIALALEMEL33243OLIBE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIB", - "commit": "b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding another one\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:12:08-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIA", - "commit": "996865bb912f3bc45898a370a13aadb315014b55", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "committing pem\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:07:41-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": -1, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "deletion" - }, - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_local_repo_two_leaks_file_commit_range.json b/test_data/test_local_repo_two_leaks_file_commit_range.json deleted file mode 100644 index 657373a1b..000000000 --- a/test_data/test_local_repo_two_leaks_file_commit_range.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "line": "Here's an AWS secret: \"AKIALALEMEL33243OLIAE\"", - "lineNumber": 5, - "offender": "AKIALALEMEL33243OLIA", - "commit": "17471a5fda722a9e423f1a0d3f0d267ea009d41c", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "wait this is actually adding an aws secret\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T13:01:27-04:00", - "tags": "key, AWS", - "operation": "addition" - }, - { - "line": "Here's an AWS secret: AKIALALEMEL33243OLIAE", - "lineNumber": 3, - "offender": "AKIALALEMEL33243OLIA", - "commit": "b10b3e2cb320a8c211fda94c4567299d37de7776", - "repo": "test_repo_2", - "rule": "AWS Manager ID", - "commitMessage": "adding aws key\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "secrets.md", - "date": "2019-10-25T12:58:39-04:00", - "tags": "key, AWS", - "operation": "addition" - } -] diff --git a/test_data/test_options/test_local_repo_commits.txt b/test_data/test_options/test_local_repo_commits.txt deleted file mode 100644 index b3b16ca01..000000000 --- a/test_data/test_options/test_local_repo_commits.txt +++ /dev/null @@ -1,5 +0,0 @@ -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a -996865bb912f3bc45898a370a13aadb315014b55 -17471a5fda722a9e423f1a0d3f0d267ea009d41c -51f6dcf6b89b93f4075ba92c400b075631a6cc93 -b10b3e2cb320a8c211fda94c4567299d37de7776 diff --git a/test_data/test_regex_entropy.json b/test_data/test_regex_entropy.json deleted file mode 100644 index 8f20b73b4..000000000 --- a/test_data/test_regex_entropy.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "line": " aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE'", - "lineNumber": 6, - "offender": "'ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE'", - "commit": "6557c92612d3b35979bd426d429255b3bf9fab74", - "repo": "test_repo_1", - "rule": "entropy and regex", - "commitMessage": "commit 1 with secrets\n", - "author": "zach rice", - "email": "zricer@protonmail.com", - "file": "server.test.py", - "date": "2019-10-24T09:29:27-04:00", - "tags": "entropy", - "operation": "addition" - } -] diff --git a/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 60c9e47f1..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -comment diff --git a/test_data/test_repos/test_repo_1/dotGit/HEAD b/test_data/test_repos/test_repo_1/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_1/dotGit/config b/test_data/test_repos/test_repo_1/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_1/dotGit/index b/test_data/test_repos/test_repo_1/dotGit/index deleted file mode 100644 index 3a76f3781306faf5612017bf18a4b4bdb9f927bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126 zcmZ?q402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDOjZ4IRR{C1x%{mHH#@5g+ zbo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMvV+aXybp=vv47!F223)+E Yjk-r?-kftzqvgflt1p>^C*RQm00RUlX8-^I diff --git a/test_data/test_repos/test_repo_1/dotGit/logs/HEAD b/test_data/test_repos/test_repo_1/dotGit/logs/HEAD deleted file mode 100644 index cb19a50e8..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/logs/HEAD +++ /dev/null @@ -1,2 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment diff --git a/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master deleted file mode 100644 index cb19a50e8..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,2 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_1/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d44974fe535cf2b75e37623bbcbb69492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 784 zcmV+r1MmEJ0fm%bZ__Xo#d)Ql;*wT$f0~2=FMx^!V~k0Rp|!kC3^%!H46Yq)XJZo| zp5r*BV@x3RA+>$)J@TEv_h8VmBU2=u-N+i_&7nWUB7FlBnQo z;i(obtRTM6+Gm_lWt1|PF=MD&a#SOYUZ;s6i0y;Mj+|+2!5PsUA)yDXHLY!oW0ELk zh)by3w6Te%pbC*kQDX<75>mO?gCK2mdd=35^TM}og3wK#kXpw1yNCh5}#@E#BmA2D{Is0Jr6u8;P>SuxKWin#wA&o+sPkKhfO+F^O^9$C0QsInxPc^d&q2y+I05 zU@Ct(v OU4)Rel7nBha@t(wn|DV5 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_1/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1d8cca5c8246d0dd18fc408854cbe069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmV;50CoR(0ZYosPf{>6GGlP@402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv sV+aXybp=vv47!F223)+Ejk-r?-kftzqvgflt1p>^C*RQm066(7zoF4W0{{R3 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_1/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899e55860a4eb9fd52adc3deaa74d41f11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmV+!0p|XA0acJ&P6IIvMfuJuF6pQOL0Wamv=Q^!XXiH1wk zg=vZz}Pal`Ndeue!ODiC}gn+foU}Oq=ooe=^kN1UoO^YsFL< f<^bLNA~fc6c>uNl!{+PhK{s#uTfL|spbC+Vc>jt5 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_1/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa77fbc9e56902bc61148d32e42a70755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmV-T0J8sh0ZYosPf{>9W(dv8OUzA8Q7B3+$S=+;$uFw3R!B|BEKw-Q$ShV!%gjkt jP)|uMPA9Zjg diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_1/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3fabd74203f9f743d042f0cde0bc711f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmbBdhdwu^tQ1~wf8p^i(s0T zT2HqeOm$Cvty?mYbnd$p&zYJo)?BWL&a|~$Qhra_#ehHSSqI*Q-)@t3iM59A1KYt+VIRAuu?D5!oHdRkh=Z9l z4cA<$LrKOpU}jv3N|`|>qIcFqRj{m1r**9L8Xu$a!_IUIWNYV39ByH(eJ>{UqF597 z79A#4MEf0o26rK4{f4$2quwNfp^adhJk7qHf6nMt@57C7ZGztf9DKb}Y9MfuE!LUp zg2m!6Q|jU9;N;*x|CEB6n3=%31P63|h2F*$dLErh!J*m}qN?<2W-9tl*$bGj!zCY&NHlkQ(qMTiioLj@689l+~EN1AUr50RZ8Gd&+}$MZK3M99|M`{3Ice zX4u^@n%_}DbSwje%cj&AR@i`ni>=(lzX2VJjGjCN+>u+Y{zR{g!ofM6$)kXg3j~)& z2y6^kC)apPpy2J&qAo2R$pFH=hF<=}`InF{anG)ilLWz;Y%yeKBIKhGT-2UUUmQ~Q q!FR5FQcf<#NDkKR$-^;CUj~4gyfU=L3Y_JaCR(NFf%*+dC9pC^&}bt7 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_1/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0e62b9a281faba25dcfc481559bbccbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmV;00DAv;0iBIo3c@fD0R7G>_5w=MY#s#>uac}=5->*66``lMf+z56U|<;PtyKXN z<3R>9@XXH6ehKWRlrY{Hqsthr=bSYfqOb%)uhL6OAFw4VFe)*ew=c%^IlA;mOZ9%D n-Y#HVF!N-C4{+3|wc72z6#gsz)nMRVrNGKGSXT7`Tx&jrpjJOP diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_1/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee533384e5be65d132e80b92e8d46ca29a11c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 946 zcmV;j15NyR0d16FYurW)DX-B86r5$B= zb>|DAzrF9QbPg{4cBh@4dFP#Hw(6v!%OAe~@w>xU=auv4u`LdZLt1&_C({odQ!DaF zu?}uXl!P`MT(hHXYZAFgrjjv#ub67-dzTX1B{JNau47BpjuvZ|=CcKDU24e-nXn#v z_9-rj9@>4CR>scaGC$$U9O}z29E4&rX+*syaX{fXI=?34$qYk~AvlwmdXCYonOuV$ zn!%ueijGMJN+>f)ggyj32(dR6T1+iE(LT>8;8Q<;X`G%3Er!75baSyR3fGW!6nIk( zCPb#PoK5-l-Rft$Ik&ty_hZ-5o15dy0%d)1VAjU@n65RX;4X4;a7cIFC1<)>)fHLS zG&DzQZ`==QM=3CqRDW}wzU4W3tr}Vr+j2Uh5@XQF=kljT;|lb7*U(PJY=(A&xyTkH z@a5|L?cE(|m)dir$Vj19Yz+L&#t3qbye#r1+%d6s?s_U-i*MW--B%)Awl6MU#GPvO zKiIke=>$%O36+>Ehp;U8iEFyNIew#Yw?Sg0p);wG&=ZEL4P$!jZI-%EskCovY=Pjv`|ME^ofp-m4V*`;On-CztfNx^uqk1Yp2qt`B-L`|aoqrcB1thQ$a2WgOi4qWGyAfflt zVW^QVFHRzzk1^zJPvP{8qVsjeQJsjNM-zB20PC9oMvEmw0i|lqsO9L^9(!je zY0KgO!HFh1GRtLIo4Q3nSt??s_-=>adRBrvn0LLR@(Ug9q5oPO5Z&MYwYtB*zSX8n zOD7+w{O8lhixc`v+nUPyRBgPN7pull-oE|#?)P7ccOgi)q7|MXEKY{Ts&_A0Csl$q zeo)eDY*}s8bpQwA`-sQm#ky=IJWhihSoA#cSW@=z$7sE|wjb73&%sOtf!|_U`Ki U?AIJ_Y5s+)Q~BHc07G9gA$trp-T(jq diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_1/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66e206a72124d32206debad73e240f4ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2176 zcmV-`2!Ho@0hL($Z`;Tb?yursF{h}tlCB;Yhx@e zWu`QQ*14r9WUSEE&`Rai8XM-g{#7lQ)WrG?_S= zrZ!efQMwx=buJBUg&|n<5xN)>Hlo2IE?8<&r5o7HdcCzP8Y)e)tnH4r8(I0s{N7pD zXw8=Tg`)@?4m6^y3rS|9wgz6^l2v=Zs5(!>8bGoeVM)Nrq5#^}4v*~jG=-(S13YX)b+asTv%x-_+*qY|(Q_}l>|bvkKJ9O zV414;J*kXJVPL|P=%qn^(Cc3~mOfy(KjA&jm5aR$DiQjkaCu?y-Z>1kan73jcW>v- z4Sj({=|<7BzbvT#3MtbtXFYX;JA%#g&051a`XQ$U_DQnZ9R-t)X>j`H$A7;&ygUle zOS5JVKaLU`v<+@$-0PzC`#f?Xj}`st`>G$*4FBALK7zth)SSM(-t5Eh-QnbWG086f zI-(iN_lD?P$Ioa!;=5Zib&=cQ?0q#G2YB;K_X_Qc7`rTFNyApowI1Re%5BmJPlu-S-w@gZX7}VUNY|J!p%~zQ8b~{{FV5o-6iqm;FEd@c#Vu z+0~0z=Sgyb9v7Rkn<e(vSGPS7bphRB9JIo>9+PAH{DF!_N<5*-I0 zGC5Cc-feF&)VOBBT_M`)<{mgXkioA`H=NZvvHQR9>rZf<9jG#;05qjEZe%(^FMt z`MS|!iIEg9lfjQKFRspCzM1(qz{+8mIocn=@Mx@c47DPxyQepn` zam*($YbN?9ALc-I3?>LXvLVPGH{B)xfIMA%@L=Na^v9HFe_T+Hs|8e*=UGn zzY#Tf>=}*I81jZVc}9pGPDUGFfuY&052Yr8Kp_4h?SY|!55+j6xuggg3hwuMAds3& zCV%)1S?X5In0ENY{|~NNieCz7=I@eDS?2Bn2(e68$ya3f5k65eg|_xf&;3h&pRgr- z(fPUu?$7)7G75I(mJZ_C9mycq731su$E%z4W}ExdCQ{(pGsnp@Q0qWps)P_04HBQ z|HC7^tE_NB(qb)>=MOf%;09gR4JLM!ZYHt+VJ95+;(6wS_a=9&Z%Bk#IthP{KtfB@ z1!VR(WI8*)V<6@h7T=rK1+#bv#yfU8by$ED^}uByyy||BiACVsr7(%(-~Rym!v%V@ C_Bz%8 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_1/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d69460c86bbcd9b032b9c98776f077f08c21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmV;?051P{0Zorji^4Dv#XaX!4D`?yMX<7Z@=$I4!@4ShsHc)<1`XB(GQp+aeq&W| zPH$j-@4YE2TS78SS`lOxjP-Dl4nbKYP>zs{*Ro=vDjg(@p|su(de8MsK$w^Zako(s zEZ#5zd#BBrLGq_jx5;p%?CnMd340AG|G1D!5p!{+y3ja|)1PI!+;X&yJ} zSKao%?;|PMw46E3I-@`pk$3#=?z@ktMXna~=G)o%H{Dm$MJA^@jk-~n-boUl_ejwG9Hm0@1DYyih6^T#^<>(>4_*6~%F=+bqv% zA;|ebh?&IE*y{WgVxx3sR8dWczOQI05?GdM&r-KdOv=+ zy}$YJ3!{%$7LklPB2LjZH;$J@X>kHb-R!QVE$}#iF=2FlcF`EpYdEh|Nn0+>$UViX zwEbIdHb_r>pgWA<|InCv=kyj~UDI114<39l*Mnx~Cs1b=C0P`NQD=hDSoyfT_5N?~ zwc$<~o-^ES99SMY@=>A+k_s~DNd<9;Hii0K#KyjYM-BBD3+m7Q z=2PEfAv4Hwr;Gb>d@u{(rA}30?rUfB-koT zO&|M?$2Rz#+S$s2kQ=_j#L=iCe0jm@bRbzB%b|n3`SSR@)wF=qRx11g-ang&8#_4I zfxutNFNpXgN*wJWw(A-eY}f1uDCz8s{J8gsQLjKcdv)>Yn$XpcQ(0nqy0|`@A!>gI zg$1}p-usP7AH~B&v8*tQX4>c=%kJ8;&Ha-bTV9ZZz{%4|NO5ADagEh{tvzWxc`6V{Li;sv-@2XT6gZMlA$rl^Ro&wj)x3Z;J5!cXqFz&@9#O z+{cX@FfO5g4^nNRX;6Jq3HdJ{D@y3MebZsZ?WpgMTF%`Bx0kBcP4`14Go4~~by{{F J{R5J=dNhq_Y9s&v diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_1/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404ead93e87747db7463148dcfc4406264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57 zcmbOuDK-kgbrAKuAb%2QHA^dN)z?r`Std5O*i(wxzt< z<8Q{(x!A$u)AQBhdezymA|n=J0q+5Dr+sn=CdLg=pKW5`2))6618flb=)GldaRiS< zdPHEo!2sR95OhjzpEUOdh8#WULR4N`cM`V;qmKfb9Za0uy0{kP*0O;RgZjc8fmriI zpa;ebmT0nJEV$Vt$CRyRJW;_8PzgFP)wsklU8HRR&W@HU!nwG`b(P|}99}$jdTOu^ zk70`_=&qE)#?m48J>)X-$4Qk|l>GZ%c^YLaL<^&3MMe?wl*C+K*}clt!8Zn-Acho3~C3mIU^)2m!&xD{|}q*hdbH4$sh3|egWDEqwx$qkTC!N diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_1/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546046fd8e97c51aa441fc04770e35a2e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 529 zcmV+s0`C2I0ezC&Zqq;zhPjQO;>U@|L2;~bfdHwI3PI2tDpB`}kZNs@?N#kvcX!=# z2=C6U-H3n?H&HU4`43;5);h(@S1+E7pT?Skk)oml@JP|ZH;b? z6poIOAq#i~p&UDEKGm&vW|blO>cmsBW?kzC?#HW?^Wh1I$B^(nm;@^%yre|R5M9N$ zKKBxaM_js}_*E|z4qj1X%WxI&<+bt?#?%|6#HM~vLt={uxbsp!cg=(5Nq|o`L@x9z%<+64vz diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_1/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be8055a643e766f4891228035eb86c109..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmV;P0Ac@l0ZYosPf{>6F=cS^402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv zV+aXybp=wA42B8@T>m~x@=YnSt7xg(`Qg?o(Y06pUwMDDPPCEZ!SShDS_fbL%zb99 MyDotZ0RKTY9%ztF9RL6T diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_1/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ced73ec5db532487582e5971988714a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37 tcmbGp0iBLZ3Iib!1+(@PeSrkOqYWYCDy_E6KpY1#n>l?Jt4f_zRr-(&nB2tcWwxwjtMI6+5AFw#*6Y53jY@%`KF=nfmIn>TY z6AKoK-U@n;wRJcttiG%-=fA$O& IAAFxjc?OwAqyPW_ diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_1/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077bbfa5593abd0ed2b1ae93b259fa6873e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1646 zcmV-!29f!A0hL$pPa8Q9y|0_UV!A|1QjsieKinx4t`+@poGL&qy`EGka(11>Wn(Y4 zmo%dEZ@)M8E&+OXYWV<(?HSL!dGkC>N;9D+PagmJ%f^GOb~c+RomJA7olfl}Id4_& zx5MY9uv+Pvi{JK-_QvDGO6tekoz4b5*CfA)MO8|g8*@%Bx2p2w4JqyA%nC2*gYfx$ zAvBKn=iXOtoMlsy%LxodGv(*?WTZ^CY>s6ET4Ir~!+u;PWkGdCh4eD_hy;GLT$0cQ zEli=N3j0%4N;m3kVDEU|#G)Kk!a3{;x|G%_qp6?Q)=KTm6+IdR7lOQ6NQ6sTXyasV zbm8D;YV1OI&(;nO7!f@S7N+)9?Oh1Y7x+e^EMo-Z=fcxmTuPcq$r;~7=#S;jzoE`J^?*lbON|e_I-R&M|l^WeCK{N-)9&O;#KtHc^Lz z_iq{?3`s2}Sn_jV!S&h16N3Ow+M#F9-@g7U5NB^L^Yf5a;0?3IGAY_hbvkOg zc0oHkT(7H6vcb{7vAQBx>I{#?{-7 z$$dJcop01zxRvYC*RRxV7V_0>sdO*od)E+YeNg(z?F%>XKUp}t*j)N{fiMVkH>j**~Dz6w<}!v2o)vr&f3Qit))@^y({QNGu)>Xg)f+@;!Ld-G=wv`s0lpSv z>OS}x{FyTQXg4%aC@=I1*SMet6Iq%iEoBd|2p5_QZ4YKGq(k4`>ghndxzIDPBzAJ7 z*#zCclrY!mRBwfL3hF|AFe|q*^ro1C+HAkJ(1uC_UlzeA=Lg`@2A?=KB=X!qPL-R7 z9^GuBtGT&D5^1oVU_I8RKzb~n zDYUaJT*}8vwP3-GPNKx|a?pqd5M8cDEU)_epw^(mnY0U-axl}{!lUJ$g@6i(EWRQ{ zSC<}g-DHiW9D&UY*ap$65)}6>ISJ5d{uy(B|a|=I<(ygYb;woa0dQ8v>} zO7C_cRv<1((o_nBW%=6-OAX*-`j|4P>1kZP1z*@Q9!@@{kQOrypJLG)CB=;~JD9Vh za5@bEyY%$*6gOSt7Xn5272YjRp#k>~s2egt_&^7oX_oPwdlq%6P$-GUEeu@&M^REY z+oq>&|L$I+?W1mfXrAjaio3w;UZAYLwi*ordPf5NgisRXejR|kpp-!l{r^8VDUDh} zY2tN2x=rE76@qGw(ZQ`vS(CF*Csz>92+L<@^jUR2Lp&1Kh2pki`scgDgYo$9ci2n1 z?Lpv|wi|&e5YXhBSkC|}PTsXXI{FXmqa(HskaKwq{NCI#+y$|RyS1PGHry@n_7$>! zlRb-b65h`!;k&dI`n_w0yI0a$W3Rvaj;t41-OLMyd(@PeM8XI%dI%+kut06_u8$rL z2=fFhUQlpZU}WR8BGujf&;!L9K3T>J>}aXvnmfHA~895N^u zUv9?2=H&feLzR+9lULz+VD}4g&T0{-&c^P37%eq_U&=yl+r9R!^gQ9s}_z*mGRDfe|FR8MI5D-!W%Pk>Ts5{we}yZ9Ch+baCPBo&IV<}Vil s|FdAcmITIy*&-ctJ8*Q3bZv4c#&{z)pIwE^!@F{gK(9Oh0QinDkobiyOaK4? diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_1/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4610280c50c51ee98c9c92925d129f44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0V^p=O;s>4VlXr?Ff%bxC{8UZOD)nXNi8nXE2w0c7i6TmS?aFJbAA2S R+-k1pH>Wz?0RWT25#mb?7wrH5 diff --git a/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_1/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAHLv`dZ}8Ito;$ ztzsJ-+wyk$??b$tCodiPA|6oxB$0tPFF(FGHMuCYq*yOE1*nXH0chT5t*`yt!1RHe zeNgj!(abaL+1SzK(6yFZYkz3=$4^Jy`#x)YW#B?H3}{|RkgF?@l4LMaFyM-fX;*ns pQI~mc&&gNb=eE?&bWF{g)VkK={NcR 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again diff --git a/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master deleted file mode 100644 index 95800b46f..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,8 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_2/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901d664638bb2f6f321a850d8dd1d31705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmV-70LcG%0V^p=O;s?qU@$Z=Ff%bxC{9f-N-ZhY%S~ahy|pnd7G-oh0FfcPQQOL`WFHTJ^N-ZhY%S~ZWu?>!Gc{~00Azsdt zmkxaq52$~V2vrDCrB{%e%OL9Taq=G3EmO`um=sx6xt@j5g8dDODzI706#d?0B~AEu VLjF;})9u!6*GyJ60sxb_GE!YvGHw6> diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_2/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e1584537fe3054161ef01357ec82e4cd80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3391 zcmV-F4Z!kv0d1LEkKD!)h4buR(byLy!0bSB5ZlR%u~s5@9ZL=*A%-8DWY4fQB%9`C z$Kzk0?^HKucjfrO#tzBux|}+7s$6xca$o)Zo3H-l_~&CArr^%{mv>!STspX=jl*%~ zM^~q{Ylat#Ym$qD^Mm{F{`TuvJ6ElXp4)dz8{EOqOPCjTTraar14jf`b*Vn_O~bhl zp>b2_xkGm`3qA#odc$vL`QZlKtAaf_#0hK9X=>bkd8$MCwh41RMPB0& z*=m=Jogc#9-4B>Ehn?&FrQ+{@Jz!l;?5fFkd-okd!EwbCThb6*<1dPv{Qc13L-=hB zQw&4RD=ptDgl1anAMEy-50=(1n?vKuX~nC}^k<>ouG~33>H^Q)Ax-46Pkk7c{TE*- z%lG89uGeY82D|uY-z}CJyqCenSxZbDeCL+Q$3gzjX<8z_{v6y8Lc;;CUcPiKZ<3Fk zXu_<>)u|_E3#q}~>-WmPUlvYtZ{s{i!0|r#=HlkXFYCN_A21Y~FanfJ?se+YB5ex9z0Wb4t-_vsAyzD*86%&^K6l=JkS_~{V*-F`{w2DB}v9N6^zPs#gY3=2hMj~ zuLOo1_&VtZ40-LlNQj5%9g*wpU_h8{tuFnv&%a!dxW8^mQNDU5i0aVV2 z0{80*dIQyK_VO@SQ!y2iN`@RlhV232U; z8`3koW;J*Fi^EMSYBRX@Qy}#Bc2W6UyvU2`44FJJn6QXX3$c&byam3A57Br8fHW)Q zREUTeX5b4d`3m2BT4_ws2mOl--vgo8b>x1I_Pbh@?@r21>00Imp^W5pEBNy0IHh%H zc97pWKvhtXSX6nNQz`x>LpgWQ+$Kd_TN~~DQn&Kf8o?52ITZ4&V`akJrv&JpT0*UO zH=ks*^@VGOTKWqW(fVlwod&c^@R^hk!Xt5>$#nyV0WKq0Wohp0Ar+fF1t0ZlkcU=e z2wjw9S3y|8sJ;6hNDmb63=%}dg$=0+;y~`i0{qskzd_EW7Jne@3i=TS!G3j3rSGg4 zEo$7xYr;yOd#GX2pjipSXGu9AEhrQuM#OV5(##w zsd7MJ(7^*34JVN;IiGr^PGfL?_FWagb%he3kpDvA3Tjjdl(Y`pRk-I-DWiu8%8M_#of4G}>^!mOc2d@Dz zzqwam|Bd{==s|QkE6SI&sy1Nq0F|B4Zd)MB+54NUZQjwIgcqwhMWcXKG0V-k*m(`? zL{TaC23snFuMsRtSk|+J5I73AQaWK?cANb85{R9nNO7SwYPBI4xKq7KIC{WY0!}s| zFsT0WLQZ*n#p>had&6ahkG{noxhnVUNdvIxlFK8O^msG#Svs;skR1F+GM+r6xk@hc zGjf>-WWS9vK`sH-r;sGswnKOkspaR08I)-gf#01<0KpV(mVtz=`W1v+v|DE>ZdyH> zEPoVdaj+p{OKk`}hLroEC-SPa|9ZXBBKUNXm!IHsH;)#w5|_KEexJ5a^&|95HSkb>znXykqq_c@BVUSB+X$q$*4p zOAu9S`y)NwNG(t!g>#gm78X&B8LrM0#O3x7d8H81;W@$GxbG78-{Wyw>Ae=kY->%Q zpx0&**;`v=ygoUcq_7(Q`|qZCWmKWqifN)nA6om;@OV`|Rkz9&H~5E(dvp8ho5D-w zm3Ma^+>ZebL3(Q;^0NT#-7k>pX+XnH5&_NwjZI;B_fDsN(#*ci9oV=5L7<~7rS_g> z(cNUa*|~q>+r|Cu%V&|H*M|CZBVZ7E*MmIZaoIx9aNANl@u+le&)nUE|Cc$p-rD+~Vr2uooy4Q-p|X_xe^d zz(5|4G&y~kx);SU6Hpw`d$aReL%ALq*CgNkEa;i0cq_`37+3}fsZitF^hr1aL}zI- z>S&n|U)CkDPFf4hs{pozO0zQFntSMU7|qUNt&kay7bS3w7z;C42T68?gsSUT>O~s_ z-j)9>T&M$16ygMh@0r-NClN{N=8~0-H#7xVY@hZnV=tPh9`?%XmFh7ul3~AS(6{;r zkotqBzaeB-U|_=MY2khK<;x9TIni5>mu=VLQZP4+-~-SRGA1a2Ua_opwb7IU{H?nq zXOd#-0Yh#`6f&)WngpGVae^H0QFH9IXrZd)B2e?vs@#_YaaH{Uu{5f!ffQ9zG9|M$k$zyvqzUAOk1i8%u9{CRM&(l!k>~)#6bFcnNMy2Qxfz(`CL>My@b?LuN&9d+d-WEfe3#m6DDhr)9 zbiIn>BeYMG;=swsN^zbtp$h&yK61~v+A4%#={&YG>i&7vp$Iap*4he; ziF%OEVi5s<7kF4n82w~~*tl}!Rny*3N0Aw}MmlKGT&8)O;dm(`3Usf@KCU~3OYvOf zmn5{kwv3`!R?()YR17^N!_LmO3b!UKZ%z7H9{^r=4DXu`u!e)B!%1UScp-`_GhGc? zDP}2;by_rSxh)jIXdf;c>%XzqT*{=BhO7sksi=DBsH_qRxJnaGqMbsIoRGPho)#{c8~Zg1$d!c{7F?&f_$_vS@YN>)5A~7BH0&Q{-`8Cz(e8gP2ZWwWs1I zZkC8(=f)wA^?-I;+Ot7gK`?!nCk|X?2hIpX{ctHquu9Nsz!qpW_eoZhKC*`$wUMu@ zDATg!)PesN@L<0W8uBv>nEThxA$Ix$rI~#Nb<(*wf)?Z$mLi$j(P7ue;^bJP*avR8RNwIj@o#j%v_>1(gB5J(6lBvSXi zbRgp{y`=<%DU)@R)i@i6&KU{Xo2;D#ik55$5qTkX=a!BRX3927wqfzX>pY_~fj!BL z7>2fbVk_dc;zwU=gBQyRtw@6F>qG7L-fFMM&Sm?Sy8pmr93j!NIQYU*qlP;s_Vll? jdh)o}*K)!DOMmdT{Q<{VjvMd+{5;`I(o$D%3@=j8^c7ts diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 b/test_data/test_repos/test_repo_2/dotGit/objects/20/ef26716304570775cb395f37cb2d626bbd0a82 deleted file mode 100644 index b211c238fe8f7231b80fb95cc625489782c3b990..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfweO;QrM~8tP2Bd-Znt>6WfIs{Aze5CCM?A?I;%CGr3O diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_2/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e1886164d1f5dacceb63dd67ee51647b8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0ZYosPf{>3W>8jERtU++ELKR%%t=*9$xkg-$jdKLNY2kINzBYsNX)BL RC{9f-N-Zho0sxw35Zm6}7+U}U diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_2/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafaadedfa175d39bd014335720be7c5c9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmV-k0HObQ0ZYosPg1ZjW>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya zR^a0DNG(cLFIGs*Q*aCqhKgG$IC^_J`Z)Ty`nviU8ylGz`}=r0x^i&=03ZAtQ+cr{ Ag8%>k diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 b/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 deleted file mode 100644 index 4258020ff..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/51/f6dcf6b89b93f4075ba92c400b075631a6cc93 +++ /dev/null @@ -1,3 +0,0 @@ -xA -1 E]Ҥf -"^%M#8Su{zv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e b/test_data/test_repos/test_repo_2/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e deleted file mode 100644 index f1090fb35cd847048797eabe87866c168e898d94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdjXJbc`L)Thvt^J|dA3q&+@B6Ir6##I|BXT`bBTWDR diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 b/test_data/test_repos/test_repo_2/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 deleted file mode 100644 index d93d42c3b9f9046d0473a91d5e3d49f4d6b247ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmbPBjN{}9oiLBnXFNka&YjoxJaa}nOyk^n-%t%dUp+5f&9Dbd J4ECIS3jsy?6iEO8 diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c b/test_data/test_repos/test_repo_2/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c deleted file mode 100644 index 1fe46e5225a209e5e0bce46298b1fe7cdeef9c93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwc&nWEpDtfUG5PRKtBc)H!X?V8ETMgVrLBY08lBv}9e diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e b/test_data/test_repos/test_repo_2/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e deleted file mode 100644 index d944898203cf71b47a5c469a2298f55a79daad42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwd@_SVLS>ZM3~|dEKPd e2Us5niDpM|#R<`z_FNAAD>h{>!+ZgTA~=5#yE$?I diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_2/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f932750dc7f93506d0eb4a1c4f26866240a74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmV-K0K5Nq0ZYosPf{>7W>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya aR^Z}FOb3eUDCFfUmBFU z?4iZ(z&VF$Nd;nB2}0iLoVEfbKM4wj7u5nyz!8`pdTq5e7h@5H n#H;O3hW)3bIp56mt(B4}e5CgrJAo8XC`kfa_WOSTR;Vcc+zLL8 diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_2/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c3a7bf4c0c1cae10c3216b710b085c72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmV-J0KETr0ZYosPf{>7WKdRCRtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya ZR^a0D%U8(FFG^L&POU8F0st#)6CKCE976yA diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_2/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f113240b82f367789ed77ddde86fef0fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmV;V09*ff0iBLPY6CG00CV;$^nn&zvg|d4kgsTEZL>7H4vs@;Uf=W!Jq-*DjJ9oC z2OyTi=w{$&CGlFAl4{0GbB;@#tg0rdCN(4?TC%%Iw|&6GsT7M?79z{cF);a3CgGWD zo3eSrkOqXQx2Ds9`75uy%aHgo!zD`Zvhs45<{Qt|+8 z%w=?DAgK*vltGg>7?aU{@eY#>Zet%}wAv$UB@XOd2c&=`w+~#t(3?SJGnTu zOuEL+qrlJDTZa>Ahn|Vye*U6AkKRVB1@rqxtvo64UTPjJN@?|Ue1%3 q4t)_1sDF|ORfwc&+Q9>hleNB2dw+R~&cPe9RbTqn+5rHDd?aRS4q2I{G;Jxca*K7#kaz82kHpI=U)x0RTC68;+D+ BC@ug1 diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_2/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f442044293fba056e43ba7f5c6ce03677cbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmb)7U|?ckU~Cwu;peO8rK@@Ev~OaE?=xYayw5NBgeT9LnQ}69Thhu> KH3lnoJ{|z;z7p>M diff --git a/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 b/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 deleted file mode 100644 index fac916106..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 +++ /dev/null @@ -1,2 +0,0 @@ -xA - Es5JUƙI1^xS-e`sM<{:!I&J.GQ6Y;d+yp8J1);DL>Rd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_2/dotGit/refs/heads/master b/test_data/test_repos/test_repo_2/dotGit/refs/heads/master deleted file mode 100644 index 605b789d6..000000000 --- a/test_data/test_repos/test_repo_2/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 diff --git a/test_data/test_repos/test_repo_2/no_secrets.md b/test_data/test_repos/test_repo_2/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_2/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_2/secrets.md b/test_data/test_repos/test_repo_2/secrets.md deleted file mode 100644 index 8cb188824..000000000 --- a/test_data/test_repos/test_repo_2/secrets.md +++ /dev/null @@ -1,3 +0,0 @@ -### This file contains some secrets - -again, no more diff --git a/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 5f0f3ea61..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/HEAD b/test_data/test_repos/test_repo_3/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_3/dotGit/config b/test_data/test_repos/test_repo_3/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_3/dotGit/description b/test_data/test_repos/test_repo_3/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_3/dotGit/index b/test_data/test_repos/test_repo_3/dotGit/index deleted file mode 100644 index f00886b57b01a5a28f65974bf911c3abffde4ccc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmZ?q402{*U|<5_*v&?}WtLpYjNPnxgRO2=G$R883-f|EK@1FyOT>Lv`dZ}8Ito;$ ztzsJ-+wyk$??b$tCodiPA|6oxB$0tPFF(FGHMuCYq*yOE1*nXHA$GIbNiIKQH!v;H z`x|OrAewn<%}2S#{(BpGil~Y&T6-c*pJnT2Wd<%Z!+_?61i88bDM 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 checkout: moving from master to dev -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets -64cfcee9aad1c84581631636bfc54f2050718d1a f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024992 -0400 checkout: moving from dev to master -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev b/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev deleted file mode 100644 index b6e041366..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/dev +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 branch: Created from HEAD -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master deleted file mode 100644 index 4ee29a707..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,10 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_3/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901d664638bb2f6f321a850d8dd1d31705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmV-70LcG%0V^p=O;s?qU@$Z=Ff%bxC{9f-N-ZhY%S~ahy|pnd7G-oh0FfcPQQOL`WFHTJ^N-ZhY%S~ZWu?>!Gc{~00Azsdt zmkxaq52$~V2vrDCrB{%e%OL9Taq=G3EmO`um=sx6xt@j5g8dDODzI706#d?0B~AEu VLjF;})9u!6*GyJ60sxb_GE!YvGHw6> diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_3/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e1584537fe3054161ef01357ec82e4cd80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3391 zcmV-F4Z!kv0d1LEkKD!)h4buR(byLy!0bSB5ZlR%u~s5@9ZL=*A%-8DWY4fQB%9`C z$Kzk0?^HKucjfrO#tzBux|}+7s$6xca$o)Zo3H-l_~&CArr^%{mv>!STspX=jl*%~ zM^~q{Ylat#Ym$qD^Mm{F{`TuvJ6ElXp4)dz8{EOqOPCjTTraar14jf`b*Vn_O~bhl zp>b2_xkGm`3qA#odc$vL`QZlKtAaf_#0hK9X=>bkd8$MCwh41RMPB0& z*=m=Jogc#9-4B>Ehn?&FrQ+{@Jz!l;?5fFkd-okd!EwbCThb6*<1dPv{Qc13L-=hB zQw&4RD=ptDgl1anAMEy-50=(1n?vKuX~nC}^k<>ouG~33>H^Q)Ax-46Pkk7c{TE*- z%lG89uGeY82D|uY-z}CJyqCenSxZbDeCL+Q$3gzjX<8z_{v6y8Lc;;CUcPiKZ<3Fk zXu_<>)u|_E3#q}~>-WmPUlvYtZ{s{i!0|r#=HlkXFYCN_A21Y~FanfJ?se+YB5ex9z0Wb4t-_vsAyzD*86%&^K6l=JkS_~{V*-F`{w2DB}v9N6^zPs#gY3=2hMj~ zuLOo1_&VtZ40-LlNQj5%9g*wpU_h8{tuFnv&%a!dxW8^mQNDU5i0aVV2 z0{80*dIQyK_VO@SQ!y2iN`@RlhV232U; z8`3koW;J*Fi^EMSYBRX@Qy}#Bc2W6UyvU2`44FJJn6QXX3$c&byam3A57Br8fHW)Q zREUTeX5b4d`3m2BT4_ws2mOl--vgo8b>x1I_Pbh@?@r21>00Imp^W5pEBNy0IHh%H zc97pWKvhtXSX6nNQz`x>LpgWQ+$Kd_TN~~DQn&Kf8o?52ITZ4&V`akJrv&JpT0*UO zH=ks*^@VGOTKWqW(fVlwod&c^@R^hk!Xt5>$#nyV0WKq0Wohp0Ar+fF1t0ZlkcU=e z2wjw9S3y|8sJ;6hNDmb63=%}dg$=0+;y~`i0{qskzd_EW7Jne@3i=TS!G3j3rSGg4 zEo$7xYr;yOd#GX2pjipSXGu9AEhrQuM#OV5(##w zsd7MJ(7^*34JVN;IiGr^PGfL?_FWagb%he3kpDvA3Tjjdl(Y`pRk-I-DWiu8%8M_#of4G}>^!mOc2d@Dz zzqwam|Bd{==s|QkE6SI&sy1Nq0F|B4Zd)MB+54NUZQjwIgcqwhMWcXKG0V-k*m(`? zL{TaC23snFuMsRtSk|+J5I73AQaWK?cANb85{R9nNO7SwYPBI4xKq7KIC{WY0!}s| zFsT0WLQZ*n#p>had&6ahkG{noxhnVUNdvIxlFK8O^msG#Svs;skR1F+GM+r6xk@hc zGjf>-WWS9vK`sH-r;sGswnKOkspaR08I)-gf#01<0KpV(mVtz=`W1v+v|DE>ZdyH> zEPoVdaj+p{OKk`}hLroEC-SPa|9ZXBBKUNXm!IHsH;)#w5|_KEexJ5a^&|95HSkb>znXykqq_c@BVUSB+X$q$*4p zOAu9S`y)NwNG(t!g>#gm78X&B8LrM0#O3x7d8H81;W@$GxbG78-{Wyw>Ae=kY->%Q zpx0&**;`v=ygoUcq_7(Q`|qZCWmKWqifN)nA6om;@OV`|Rkz9&H~5E(dvp8ho5D-w zm3Ma^+>ZebL3(Q;^0NT#-7k>pX+XnH5&_NwjZI;B_fDsN(#*ci9oV=5L7<~7rS_g> z(cNUa*|~q>+r|Cu%V&|H*M|CZBVZ7E*MmIZaoIx9aNANl@u+le&)nUE|Cc$p-rD+~Vr2uooy4Q-p|X_xe^d zz(5|4G&y~kx);SU6Hpw`d$aReL%ALq*CgNkEa;i0cq_`37+3}fsZitF^hr1aL}zI- z>S&n|U)CkDPFf4hs{pozO0zQFntSMU7|qUNt&kay7bS3w7z;C42T68?gsSUT>O~s_ z-j)9>T&M$16ygMh@0r-NClN{N=8~0-H#7xVY@hZnV=tPh9`?%XmFh7ul3~AS(6{;r zkotqBzaeB-U|_=MY2khK<;x9TIni5>mu=VLQZP4+-~-SRGA1a2Ua_opwb7IU{H?nq zXOd#-0Yh#`6f&)WngpGVae^H0QFH9IXrZd)B2e?vs@#_YaaH{Uu{5f!ffQ9zG9|M$k$zyvqzUAOk1i8%u9{CRM&(l!k>~)#6bFcnNMy2Qxfz(`CL>My@b?LuN&9d+d-WEfe3#m6DDhr)9 zbiIn>BeYMG;=swsN^zbtp$h&yK61~v+A4%#={&YG>i&7vp$Iap*4he; ziF%OEVi5s<7kF4n82w~~*tl}!Rny*3N0Aw}MmlKGT&8)O;dm(`3Usf@KCU~3OYvOf zmn5{kwv3`!R?()YR17^N!_LmO3b!UKZ%z7H9{^r=4DXu`u!e)B!%1UScp-`_GhGc? zDP}2;by_rSxh)jIXdf;c>%XzqT*{=BhO7sksi=DBsH_qRxJnaGqMbsIoRGPho)#{c8~Zg1$d!c{7F?&f_$_vS@YN>)5A~7BH0&Q{-`8Cz(e8gP2ZWwWs1I zZkC8(=f)wA^?-I;+Ot7gK`?!nCk|X?2hIpX{ctHquu9Nsz!qpW_eoZhKC*`$wUMu@ zDATg!)PesN@L<0W8uBv>nEThxA$Ix$rI~#Nb<(*wf)?Z$mLi$j(P7ue;^bJP*avR8RNwIj@o#j%v_>1(gB5J(6lBvSXi zbRgp{y`=<%DU)@R)i@i6&KU{Xo2;D#ik55$5qTkX=a!BRX3927wqfzX>pY_~fj!BL z7>2fbVk_dc;zwU=gBQyRtw@6F>qG7L-fFMM&Sm?Sy8pmr93j!NIQYU*qlP;s_Vll? jdh)o}*K)!DOMmdT{Q<{VjvMd+{5;`I(o$D%3@=j8^c7ts diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e b/test_data/test_repos/test_repo_3/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e deleted file mode 100644 index 03bf1d87b2affd12fe23a57dbaf1c2ca77fec974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwc&$5M@gPa7s@&f}eNx-+@`L>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfweO;QrM~8tP2Bd-Znt>6WfIs{Aze5CCM?A?I;%CGr3O diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_3/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e1886164d1f5dacceb63dd67ee51647b8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0ZYosPf{>3W>8jERtU++ELKR%%t=*9$xkg-$jdKLNY2kINzBYsNX)BL RC{9f-N-Zho0sxw35Zm6}7+U}U diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_3/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafaadedfa175d39bd014335720be7c5c9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmV-k0HObQ0ZYosPg1ZjW>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya zR^a0DNG(cLFIGs*Q*aCqhKgG$IC^_J`Z)Ty`nviU8ylGz`}=r0x^i&=03ZAtQ+cr{ Ag8%>k diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb b/test_data/test_repos/test_repo_3/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb deleted file mode 100644 index 6efcf07daa19a2c267f297b45ea4fb0e712af754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmV-@0D}K`0Y%EO3c@fD08r&@1eE%^G;sH6^ba_JcH`iJ3;yB*5n8&2!Fl~} flRw}5{F{Am31jB>l8;E72z$#&omT1tM*StNrGY*Z diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d b/test_data/test_repos/test_repo_3/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d deleted file mode 100644 index 15e9e92765ea3ff2d56d095e0f193fd15271f18b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdj`6##8e{Vxi5moU;Yfq%zv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e b/test_data/test_repos/test_repo_3/dotGit/objects/5d/5c8724e8787e69cebcc9ea4bceb47d9941656e deleted file mode 100644 index f1090fb35cd847048797eabe87866c168e898d94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdjXJbc`L)Thvt^J|dA3q&+@B6Ir6##I|BXT`bBTWDR diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 b/test_data/test_repos/test_repo_3/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 deleted file mode 100644 index d93d42c3b9f9046d0473a91d5e3d49f4d6b247ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmbPBjN{}9oiLBnXFNka&YjoxJaa}nOyk^n-%t%dUp+5f&9Dbd J4ECIS3jsy?6iEO8 diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c b/test_data/test_repos/test_repo_3/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c deleted file mode 100644 index 1fe46e5225a209e5e0bce46298b1fe7cdeef9c93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwc&nWEpDtfUG5PRKtBc)H!X?V8ETMgVrLBY08lBv}9e diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a b/test_data/test_repos/test_repo_3/dotGit/objects/64/cfcee9aad1c84581631636bfc54f2050718d1a deleted file mode 100644 index 261fe7f663b2d350552fb233d05cba619f73884c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmV;N0Av4n0iBM)3Bxc90Q>e7TA)RirNn_!x{Bf`Bv8l2aX*>9=?Z-v92{IKIj;?f z?sB1E~A3xORyOvhAtn2HRN`8Qso{)Hm1XpB4ciMBY*aqJ4|u_ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 b/test_data/test_repos/test_repo_3/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 deleted file mode 100644 index 78d82a50de7c6818a97596fc6b5b64081cfa0043..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwd@%l>!nhcAkMKdY`^CwZr2et)*~ZvcNZBlA)SBh&x@ diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e b/test_data/test_repos/test_repo_3/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e deleted file mode 100644 index d944898203cf71b47a5c469a2298f55a79daad42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwd@_SVL6G-6OzR#phf$ShV!%gjktNY2kINzBYERw&NTO;spPO)g3; zDOTX(;>s#5E>XzNOi9ViOIOH9ElO1YYDvt?F9EWl>a4gN!-HXL1tmvsPe&g|A6H*j VA7f)96JviLPe)fJE&x-+CJx*YEf@d* diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 b/test_data/test_repos/test_repo_3/dotGit/objects/83/c50b16ff4b3149142517a2adc8662f04b5b323 deleted file mode 100644 index d5dd750a5041f3045df613aa835e0cf1becaa6eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmV-60LlM&0ZYosPf{?pU{F?8RtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya MR^Z|S08QKutateqkN^Mx diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 b/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 deleted file mode 100644 index 3d207fd18..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/84/ac4e80d4dbf2c968b64e9d4005f5079795bb81 +++ /dev/null @@ -1,3 +0,0 @@ -xQ -0PsYl -"^e҂1Oo~0`v Cofq^ty<@U=٣ÜN9fYO%cQh )REh\hg>rv!b+l>G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 b/test_data/test_repos/test_repo_3/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 deleted file mode 100644 index 312b2c1d5394f35ecc64f70258f0203fdac26e84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7Q{0iBIO3d0}}0DJZo`+=5qjZvYLer2<6h)`n@d&%pYexavS>ZM3~|dEKPd e2Us5niDpM|#R<`z_FNAAD>h{>!+ZgTA~=5#yE$?I diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_3/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f932750dc7f93506d0eb4a1c4f26866240a74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmV-K0K5Nq0ZYosPf{>7W>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya aR^Z}FOb3eUDCFfUmBFU z?4iZ(z&VF$Nd;nB2}0iLoVEfbKM4wj7u5nyz!8`pdTq5e7h@5H n#H;O3hW)3bIp56mt(B4}e5CgrJAo8XC`kfa_WOSTR;Vcc+zLL8 diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_3/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c3a7bf4c0c1cae10c3216b710b085c72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmV-J0KETr0ZYosPf{>7WKdRCRtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya ZR^a0D%U8(FFG^L&POU8F0st#)6CKCE976yA diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 b/test_data/test_repos/test_repo_3/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 deleted file mode 100644 index f3a3ba397cb7bcdf3a412d6dfc9fb894d0078301..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdj$-7J2t^fQYmj~1KhU_rq*b(=o0|06ZB8_FFBvb$Z diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_3/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f113240b82f367789ed77ddde86fef0fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmV;V09*ff0iBLPY6CG00CV;$^nn&zvg|d4kgsTEZL>7H4vs@;Uf=W!Jq-*DjJ9oC z2OyTi=w{$&CGlFAl4{0GbB;@#tg0rdCN(4?TC%%Iw|&6GsT7M?79z{cF);a3CgGWD zo3eSrkOqXQx2Ds9`75uy%aHgo!zD`Zvhs45<{Qt|+8 z%w=?DAgK*vltGg>7?aU{@eY#>Zet%}wAv$UB@XOd2c&=`w+~#t(3?SJGnTu zOuEL+qrlJDTZa>Ahn|Vye*U6AkKRVB1@rqxtvo7U{F?8RtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya YR^Z|)O3lqL%gjqx$SmOk032`=6r7A3DgXcg diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 b/test_data/test_repos/test_repo_3/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 deleted file mode 100644 index 5e07a20409f13dd488cf7491b257265742ae009f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmV-a0IUCa0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 q4t)_1sDF|ORfwc&+Q9>hleNB2dw+R~&cPe9RbTqn+5rHDd?aRS4q2I{G;Jxca*K7#kaz82kHpI=U)x0RTC68;+D+ BC@ug1 diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 b/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 deleted file mode 100644 index 1533a3b46..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 +++ /dev/null @@ -1,3 +0,0 @@ -x] -0})JDJ҂i6+401j]; Kf09}4Q(3kletXԞ$2t1%Hх b>hsw>}igd% yzjZ7j wQU -p?G| \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 b/test_data/test_repos/test_repo_3/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 deleted file mode 100644 index 7ed4768c5f0684bc184dc370af4797ebe642bbd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmV;P0Ac@l0iBLp3c@fDMg7hyW&_IPIVp&^mFXm*1=Exe{pjkgTkz|04jj1BYF!5y z<1eG<46{aJOvKhwLFcs1g~_H9UC_n5$hlY>)XqI`14_`6qK`Bai%#S@PK+{fiG*y5 zaT3r3tN1;Z*5P1Tps$kQe*C6C_ufX^DzC4bwE6(;$)Ir)TDYP^RHr>Jj{H}wQvSf) Md6Pwb0i<(BR=a*tOaK4? diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_3/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f442044293fba056e43ba7f5c6ce03677cbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmb)7U|?ckU~Cwu;peO8rK@@Ev~OaE?=xYayw5NBgeT9LnQ}69Thhu> KH3lnoJ{|z;z7p>M diff --git a/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 b/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 deleted file mode 100644 index fac916106..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/objects/f6/1cd8587b7ac1d75a89a0c9af870a2f24c60263 +++ /dev/null @@ -1,2 +0,0 @@ -xA - Es5JUƙI1^xS-e`sM<{:!I&J.GQ6Y;d+yp8J1);DL>Rd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev b/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev deleted file mode 100644 index 986aea9ec..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/refs/heads/dev +++ /dev/null @@ -1 +0,0 @@ -64cfcee9aad1c84581631636bfc54f2050718d1a diff --git a/test_data/test_repos/test_repo_3/dotGit/refs/heads/master b/test_data/test_repos/test_repo_3/dotGit/refs/heads/master deleted file mode 100644 index 95078805f..000000000 --- a/test_data/test_repos/test_repo_3/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 diff --git a/test_data/test_repos/test_repo_3/no_secrets.md b/test_data/test_repos/test_repo_3/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_3/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_3/secrets.md b/test_data/test_repos/test_repo_3/secrets.md deleted file mode 100644 index 83c50b16f..000000000 --- a/test_data/test_repos/test_repo_3/secrets.md +++ /dev/null @@ -1,2 +0,0 @@ -### This file contains some secrets - diff --git a/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 0f22e864d..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/HEAD b/test_data/test_repos/test_repo_4/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_4/dotGit/config b/test_data/test_repos/test_repo_4/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_4/dotGit/description b/test_data/test_repos/test_repo_4/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_4/dotGit/index b/test_data/test_repos/test_repo_4/dotGit/index deleted file mode 100644 index 94eec663c924e68626094bb724aa5cea5e999d9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmZ?q402{*U|<4b=GYUGYU^H$Af?Cp9sK5`X`ADym|TY#i_|fsU^jFxhYWdmj5y> zouMqdX2GumpO diff --git a/test_data/test_repos/test_repo_4/dotGit/info/exclude b/test_data/test_repos/test_repo_4/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/HEAD b/test_data/test_repos/test_repo_4/dotGit/logs/HEAD deleted file mode 100644 index 99399d233..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/HEAD +++ /dev/null @@ -1,18 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 checkout: moving from master to dev -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets -64cfcee9aad1c84581631636bfc54f2050718d1a f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024992 -0400 checkout: moving from dev to master -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 828595723b76e4a35b5253d9f2ccb4f897f1845a zach rice 1573429084 -0500 commit: adding repo config -828595723b76e4a35b5253d9f2ccb4f897f1845a ce835da266b3f8c34e4b7f398693ed068f67cb30 zach rice 1573431270 -0500 commit: epstein didnt kill himself -ce835da266b3f8c34e4b7f398693ed068f67cb30 5accbc40c35906d99f073881fb8746c314f9d59f zach rice 1573431335 -0500 commit: removing a really important link -5accbc40c35906d99f073881fb8746c314f9d59f 7b2eba252004b7c867413def2a0984d545daab8b zach rice 1573431386 -0500 commit: gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev b/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev deleted file mode 100644 index b6e041366..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/dev +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572024822 -0400 branch: Created from HEAD -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 deea550dd6c7acaf0e59432600593533984a2125 zach rice 1572024903 -0400 commit: dev branch -deea550dd6c7acaf0e59432600593533984a2125 64cfcee9aad1c84581631636bfc54f2050718d1a zach rice 1572024982 -0400 commit: rm secrets diff --git a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master deleted file mode 100644 index 6daf2b8ca..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,14 +0,0 @@ -0000000000000000000000000000000000000000 85699e429f33e75541530998a5b5d457a12e6285 zach rice 1572022632 -0400 commit (initial): init -85699e429f33e75541530998a5b5d457a12e6285 b10b3e2cb320a8c211fda94c4567299d37de7776 zach rice 1572022719 -0400 commit: adding aws key -b10b3e2cb320a8c211fda94c4567299d37de7776 51f6dcf6b89b93f4075ba92c400b075631a6cc93 zach rice 1572022773 -0400 commit: no secrets -51f6dcf6b89b93f4075ba92c400b075631a6cc93 17471a5fda722a9e423f1a0d3f0d267ea009d41c zach rice 1572022887 -0400 commit: wait this is actually adding an aws secret -17471a5fda722a9e423f1a0d3f0d267ea009d41c 996865bb912f3bc45898a370a13aadb315014b55 zach rice 1572023261 -0400 commit: committing pem -996865bb912f3bc45898a370a13aadb315014b55 d8ac0b73aeeb45843319cdc5ce506516eb49bf7a zach rice 1572023319 -0400 commit: removing secret.pem -d8ac0b73aeeb45843319cdc5ce506516eb49bf7a b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba zach rice 1572023528 -0400 commit: adding another one -b2eb34a61c988afd9b4aaa9dd58c8dd7d5f14dba f61cd8587b7ac1d75a89a0c9af870a2f24c60263 zach rice 1572023552 -0400 commit: rm secrets again -f61cd8587b7ac1d75a89a0c9af870a2f24c60263 84ac4e80d4dbf2c968b64e9d4005f5079795bb81 zach rice 1572026048 -0400 commit: more secrets -84ac4e80d4dbf2c968b64e9d4005f5079795bb81 cd5eb8bef855f73c46b97b4c088badffdc40ebe9 zach rice 1572026066 -0400 commit: rm secrets -cd5eb8bef855f73c46b97b4c088badffdc40ebe9 828595723b76e4a35b5253d9f2ccb4f897f1845a zach rice 1573429084 -0500 commit: adding repo config -828595723b76e4a35b5253d9f2ccb4f897f1845a ce835da266b3f8c34e4b7f398693ed068f67cb30 zach rice 1573431270 -0500 commit: epstein didnt kill himself -ce835da266b3f8c34e4b7f398693ed068f67cb30 5accbc40c35906d99f073881fb8746c314f9d59f zach rice 1573431335 -0500 commit: removing a really important link -5accbc40c35906d99f073881fb8746c314f9d59f 7b2eba252004b7c867413def2a0984d545daab8b zach rice 1573431386 -0500 commit: gitleaks toml diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 b/test_data/test_repos/test_repo_4/dotGit/objects/0b/c3a0c9536cc7273b74f48edcc6adead16333f7 deleted file mode 100644 index 66cbf0901d664638bb2f6f321a850d8dd1d31705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmV-70LcG%0V^p=O;s?qU@$Z=Ff%bxC{9f-N-ZhY%S~ahy|pnd7G-oh0FfcPQQOL`WFHTJ^N-ZhY%S~ZWu?>!Gc{~00Azsdt zmkxaq52$~V2vrDCrB{%e%OL9Taq=G3EmO`um=sx6xt@j5g8dDODzI706#d?0B~AEu VLjF;})9u!6*GyJ60sxb_GE!YvGHw6> diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec b/test_data/test_repos/test_repo_4/dotGit/objects/15/40f193bc25b494cde092597a79af04013807ec deleted file mode 100644 index 5ad713e1584537fe3054161ef01357ec82e4cd80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3391 zcmV-F4Z!kv0d1LEkKD!)h4buR(byLy!0bSB5ZlR%u~s5@9ZL=*A%-8DWY4fQB%9`C z$Kzk0?^HKucjfrO#tzBux|}+7s$6xca$o)Zo3H-l_~&CArr^%{mv>!STspX=jl*%~ zM^~q{Ylat#Ym$qD^Mm{F{`TuvJ6ElXp4)dz8{EOqOPCjTTraar14jf`b*Vn_O~bhl zp>b2_xkGm`3qA#odc$vL`QZlKtAaf_#0hK9X=>bkd8$MCwh41RMPB0& z*=m=Jogc#9-4B>Ehn?&FrQ+{@Jz!l;?5fFkd-okd!EwbCThb6*<1dPv{Qc13L-=hB zQw&4RD=ptDgl1anAMEy-50=(1n?vKuX~nC}^k<>ouG~33>H^Q)Ax-46Pkk7c{TE*- z%lG89uGeY82D|uY-z}CJyqCenSxZbDeCL+Q$3gzjX<8z_{v6y8Lc;;CUcPiKZ<3Fk zXu_<>)u|_E3#q}~>-WmPUlvYtZ{s{i!0|r#=HlkXFYCN_A21Y~FanfJ?se+YB5ex9z0Wb4t-_vsAyzD*86%&^K6l=JkS_~{V*-F`{w2DB}v9N6^zPs#gY3=2hMj~ zuLOo1_&VtZ40-LlNQj5%9g*wpU_h8{tuFnv&%a!dxW8^mQNDU5i0aVV2 z0{80*dIQyK_VO@SQ!y2iN`@RlhV232U; z8`3koW;J*Fi^EMSYBRX@Qy}#Bc2W6UyvU2`44FJJn6QXX3$c&byam3A57Br8fHW)Q zREUTeX5b4d`3m2BT4_ws2mOl--vgo8b>x1I_Pbh@?@r21>00Imp^W5pEBNy0IHh%H zc97pWKvhtXSX6nNQz`x>LpgWQ+$Kd_TN~~DQn&Kf8o?52ITZ4&V`akJrv&JpT0*UO zH=ks*^@VGOTKWqW(fVlwod&c^@R^hk!Xt5>$#nyV0WKq0Wohp0Ar+fF1t0ZlkcU=e z2wjw9S3y|8sJ;6hNDmb63=%}dg$=0+;y~`i0{qskzd_EW7Jne@3i=TS!G3j3rSGg4 zEo$7xYr;yOd#GX2pjipSXGu9AEhrQuM#OV5(##w zsd7MJ(7^*34JVN;IiGr^PGfL?_FWagb%he3kpDvA3Tjjdl(Y`pRk-I-DWiu8%8M_#of4G}>^!mOc2d@Dz zzqwam|Bd{==s|QkE6SI&sy1Nq0F|B4Zd)MB+54NUZQjwIgcqwhMWcXKG0V-k*m(`? zL{TaC23snFuMsRtSk|+J5I73AQaWK?cANb85{R9nNO7SwYPBI4xKq7KIC{WY0!}s| zFsT0WLQZ*n#p>had&6ahkG{noxhnVUNdvIxlFK8O^msG#Svs;skR1F+GM+r6xk@hc zGjf>-WWS9vK`sH-r;sGswnKOkspaR08I)-gf#01<0KpV(mVtz=`W1v+v|DE>ZdyH> zEPoVdaj+p{OKk`}hLroEC-SPa|9ZXBBKUNXm!IHsH;)#w5|_KEexJ5a^&|95HSkb>znXykqq_c@BVUSB+X$q$*4p zOAu9S`y)NwNG(t!g>#gm78X&B8LrM0#O3x7d8H81;W@$GxbG78-{Wyw>Ae=kY->%Q zpx0&**;`v=ygoUcq_7(Q`|qZCWmKWqifN)nA6om;@OV`|Rkz9&H~5E(dvp8ho5D-w zm3Ma^+>ZebL3(Q;^0NT#-7k>pX+XnH5&_NwjZI;B_fDsN(#*ci9oV=5L7<~7rS_g> z(cNUa*|~q>+r|Cu%V&|H*M|CZBVZ7E*MmIZaoIx9aNANl@u+le&)nUE|Cc$p-rD+~Vr2uooy4Q-p|X_xe^d zz(5|4G&y~kx);SU6Hpw`d$aReL%ALq*CgNkEa;i0cq_`37+3}fsZitF^hr1aL}zI- z>S&n|U)CkDPFf4hs{pozO0zQFntSMU7|qUNt&kay7bS3w7z;C42T68?gsSUT>O~s_ z-j)9>T&M$16ygMh@0r-NClN{N=8~0-H#7xVY@hZnV=tPh9`?%XmFh7ul3~AS(6{;r zkotqBzaeB-U|_=MY2khK<;x9TIni5>mu=VLQZP4+-~-SRGA1a2Ua_opwb7IU{H?nq zXOd#-0Yh#`6f&)WngpGVae^H0QFH9IXrZd)B2e?vs@#_YaaH{Uu{5f!ffQ9zG9|M$k$zyvqzUAOk1i8%u9{CRM&(l!k>~)#6bFcnNMy2Qxfz(`CL>My@b?LuN&9d+d-WEfe3#m6DDhr)9 zbiIn>BeYMG;=swsN^zbtp$h&yK61~v+A4%#={&YG>i&7vp$Iap*4he; ziF%OEVi5s<7kF4n82w~~*tl}!Rny*3N0Aw}MmlKGT&8)O;dm(`3Usf@KCU~3OYvOf zmn5{kwv3`!R?()YR17^N!_LmO3b!UKZ%z7H9{^r=4DXu`u!e)B!%1UScp-`_GhGc? zDP}2;by_rSxh)jIXdf;c>%XzqT*{=BhO7sksi=DBsH_qRxJnaGqMbsIoRGPho)#{c8~Zg1$d!c{7F?&f_$_vS@YN>)5A~7BH0&Q{-`8Cz(e8gP2ZWwWs1I zZkC8(=f)wA^?-I;+Ot7gK`?!nCk|X?2hIpX{ctHquu9Nsz!qpW_eoZhKC*`$wUMu@ zDATg!)PesN@L<0W8uBv>nEThxA$Ix$rI~#Nb<(*wf)?Z$mLi$j(P7ue;^bJP*avR8RNwIj@o#j%v_>1(gB5J(6lBvSXi zbRgp{y`=<%DU)@R)i@i6&KU{Xo2;D#ik55$5qTkX=a!BRX3927wqfzX>pY_~fj!BL z7>2fbVk_dc;zwU=gBQyRtw@6F>qG7L-fFMM&Sm?Sy8pmr93j!NIQYU*qlP;s_Vll? jdh)o}*K)!DOMmdT{Q<{VjvMd+{5;`I(o$D%3@=j8^c7ts diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c b/test_data/test_repos/test_repo_4/dotGit/objects/18/51114bbb7484cccd61f18c71649699d73ede6c deleted file mode 100644 index 46ccb0d0968ed4526866a104fa4491b22f33e5cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmV-<0EYi~0V^p=O;s>7GGH(?FfcPQQAp1$$w^JjF4il_&&^>-nR!J-r1t06oPB52 zP8IT4K52GPfhx?)k1tM5E=nya*2_&{P_Ye;ZFxKW_aR=+la~&C5f7+;k_c6Zq$>SL bbb`kdE$yp;YDuSZF6}?=Q{e;v6#O!n_Xaes diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e b/test_data/test_repos/test_repo_4/dotGit/objects/18/5715c36f82be353f34845811270a4d0ae4b24e deleted file mode 100644 index 03bf1d87b2affd12fe23a57dbaf1c2ca77fec974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwc&$5M@gPa7s@&f}eNx-+@`L>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfweO;QrM~8tP2Bd-Znt>6WfIs{Aze5CCM?A?I;%CGr3O diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 b/test_data/test_repos/test_repo_4/dotGit/objects/24/3d535d84ed97fbc20d09c9d2c2f417507fe461 deleted file mode 100644 index 838bf1e1886164d1f5dacceb63dd67ee51647b8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0ZYosPf{>3W>8jERtU++ELKR%%t=*9$xkg-$jdKLNY2kINzBYsNX)BL RC{9f-N-Zho0sxw35Zm6}7+U}U diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 b/test_data/test_repos/test_repo_4/dotGit/objects/29/b514fe50d6a7b2aa18cd581b46a85b84c2d4b3 deleted file mode 100644 index 14a0321b10d44c3f8e159eeadc8a9b0fa3d437da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 425 zcmV;a0apHa0ezBBkJB&^#X09w%&G?@lx-!%p`aD3YPswQv@8dXZZln*Iy094$TFXv znKoTQ4&)Fyjy?0MuIug|vSs?X z{R|dc5AFz!3*;6M9O*hjsIs4-I`1J_u3)50HZjdEzq>wC8*jS1-R~0di!&qBAf*ds zjPIA*17o5Lp7{jcokW*bh0HMGtoEYV)M<7gTO($wyx~#%FZ;0VA)@iV-Oq0A_KAJT z=-cwV5;z!w7rrWov0az9j$W?oR_S!M$| z*U_j@H;Vk%5X^=AO@O%huNYHNgLc!|oJ0Dw+0jRIQ=U8w@Oy77|LafG# z1=Ta0nO$7S079MP!>B%gm6RpiLH?SQaZrL!6QZ|*iw2FZ2?3{MDPe&)*^)7rBuSU} TOi^E|(d_VP-F1HeA@&`aLB-hi diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca b/test_data/test_repos/test_repo_4/dotGit/objects/3d/dab16668fe919638b76dd48c96bedf0e2276ca deleted file mode 100644 index 94c73dafaadedfa175d39bd014335720be7c5c9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmV-k0HObQ0ZYosPg1ZjW>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya zR^a0DNG(cLFIGs*Q*aCqhKgG$IC^_J`Z)Ty`nviU8ylGz`}=r0x^i&=03ZAtQ+cr{ Ag8%>k diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb b/test_data/test_repos/test_repo_4/dotGit/objects/4a/3ffb6df0f421fdf325afae19dc749f8f6b1bfb deleted file mode 100644 index 6efcf07daa19a2c267f297b45ea4fb0e712af754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmV-@0D}K`0Y%EO3c@fD08r&@1eE%^G;sH6^ba_JcH`iJ3;yB*5n8&2!Fl~} flRw}5{F{Am31jB>l8;E72z$#&omT1tM*StNrGY*Z diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d b/test_data/test_repos/test_repo_4/dotGit/objects/4b/a23978297d33c8d7744f059cc5bca2385e262d deleted file mode 100644 index 15e9e92765ea3ff2d56d095e0f193fd15271f18b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdj`6##8e{Vxi5moU;Yfq%7GGH(?FfcPQQAp1$$w^JjF4il_&&^?Y-+$AeODaFW(sPY> z*yjYlBQKpELlx%b#}}t27p0aI>*b~}sMrR_w!EGG`w%bZ$xDa6hzHa^NrWmyQk8xr bI>Fzv_W/nfG \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f b/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f deleted file mode 100644 index 7ab6cbedd..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/5a/ccbc40c35906d99f073881fb8746c314f9d59f +++ /dev/null @@ -1 +0,0 @@ -xQj!S*hOϮ8bgr|64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdjXJbc`L)Thvt^J|dA3q&+@B6Ir6##I|BXT`bBTWDR diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 b/test_data/test_repos/test_repo_4/dotGit/objects/5d/630e1163864c8b5616199962390a36a8a53b69 deleted file mode 100644 index d93d42c3b9f9046d0473a91d5e3d49f4d6b247ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmbPBjN{}9oiLBnXFNka&YjoxJaa}nOyk^n-%t%dUp+5f&9Dbd J4ECIS3jsy?6iEO8 diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c b/test_data/test_repos/test_repo_4/dotGit/objects/5e/a982157d053ce35a9b79394973c7c8901f317c deleted file mode 100644 index 1fe46e5225a209e5e0bce46298b1fe7cdeef9c93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwc&nWEpDtfUG5PRKtBc)H!X?V8ETMgVrLBY08lBv}9e diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/64/99d414147df9f56cbecd26ca710c39e4834024 b/test_data/test_repos/test_repo_4/dotGit/objects/64/99d414147df9f56cbecd26ca710c39e4834024 deleted file mode 100644 index 5b40db650875f73d9d9a76dfb34befe357cfd6f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97 zcmV-n0G|JN0ZYosPf{>6v|xyiE-KAQEsl-l;!H^`PAe7TA)RirNn_!x{Bf`Bv8l2aX*>9=?Z-v92{IKIj;?f z?sB1E~A3xORyOvhAtn2HRN`8Qso{)Hm1XpB4ciMBY*aqJ4|u_ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/67/c45b6048e42a2bd5512662ca6cd2bfc74c7842 b/test_data/test_repos/test_repo_4/dotGit/objects/67/c45b6048e42a2bd5512662ca6cd2bfc74c7842 deleted file mode 100644 index fa18daabf..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/67/c45b6048e42a2bd5512662ca6cd2bfc74c7842 +++ /dev/null @@ -1,5 +0,0 @@ -x}1O0+u@BTtB*00͵6qQl+2$-!HdǾ{ﻷnl67m<E88 -ʐ*,V=,Ac!!d@~X ^ ˷kuZ\:Rf1.z -`+uIU*՞:LoJishPYF{l h8(;+*wNVZ @4Ύ().;o!+bg? J7 -9S(LdKimw's Fdb$+F(AV'G 63 0 -*$qHc@dab$g7D \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 b/test_data/test_repos/test_repo_4/dotGit/objects/68/b020592645020c9afb7462e17842a1cc723071 deleted file mode 100644 index 78d82a50de7c6818a97596fc6b5b64081cfa0043..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwd@%l>!nhcAkMKdY`^CwZr2et)*~ZvcNZBlA)SBh&x@ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e b/test_data/test_repos/test_repo_4/dotGit/objects/69/b7669aa8e125ef0e14abce31911e84dd09e25e deleted file mode 100644 index d944898203cf71b47a5c469a2298f55a79daad42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwd@_SVLopszHg4(Ffmq~7v>-+8rx>#yFa(pwFgP!0 zT#ggPtoYOC+F)myp)Hc&y8qDbTdTdk3NPzLYPo@-0Ua6)9?qJyR);+nd-^L@kEO4P OpKs{3tm+F$JV6G-6OzR#phf$ShV!%gjktNY2kINzBYERw&NTO;spPO)g3; zDOTX(;>s#5E>XzNOi9ViOIOH9ElO1YYDvt?F9EWl>a4gN!-HXL1tmvsPe&g|A6H*j VA7f)96JviLPe)fJE&x-+CJx*YEf@d* diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/82/8595723b76e4a35b5253d9f2ccb4f897f1845a b/test_data/test_repos/test_repo_4/dotGit/objects/82/8595723b76e4a35b5253d9f2ccb4f897f1845a deleted file mode 100644 index 54afca4e1c36704d2e41ce19aa31af2d258c19a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmV;U09^lg0iBLXY6CG40Daag`U45=(bfVJ@)h+WTaXzILcaL*alVjKK|w*u*!R9* z^Zv4?85mLtT+nCDDWssxq+861q*U~&P}Wq%+*zj`3q+$au{DaZWiKId$s7cUxN2)E z0gbJ=`dp7O;Z@}Uvx~v)^@sU=&auX^*Z%Vrv!b+l>G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 b/test_data/test_repos/test_repo_4/dotGit/objects/85/699e429f33e75541530998a5b5d457a12e6285 deleted file mode 100644 index 312b2c1d5394f35ecc64f70258f0203fdac26e84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7Q{0iBIO3d0}}0DJZo`+=5qjZvYLer2<6h)`n@d&%pYexavS>ZM3~|dEKPd e2Us5niDpM|#R<`z_FNAAD>h{>!+ZgTA~=5#yE$?I diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 b/test_data/test_repos/test_repo_4/dotGit/objects/8c/b18882408aad0b2abf556bf1f2c5478ef328f5 deleted file mode 100644 index d87f932750dc7f93506d0eb4a1c4f26866240a74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmV-K0K5Nq0ZYosPf{>7W>8jERtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya aR^Z}FOb3eUDCFfUmBFU z?4iZ(z&VF$Nd;nB2}0iLoVEfbKM4wj7u5nyz!8`pdTq5e7h@5H n#H;O3hW)3bIp56mt(B4}e5CgrJAo8XC`kfa_WOSTR;Vcc+zLL8 diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 b/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 deleted file mode 100644 index c88cfdb92..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/99/6865bb912f3bc45898a370a13aadb315014b55 +++ /dev/null @@ -1,3 +0,0 @@ -xK -0@]se22M&`⦧.XKY:T5 *죤+2IyvhM ;6s&Ql͘( -☜\ghKT_jkux&$Kpc_^'lZ>J$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 b/test_data/test_repos/test_repo_4/dotGit/objects/a6/214eec6a6290fec81fe250e5b73b86d634a981 deleted file mode 100644 index 2511ae02c3a7bf4c0c1cae10c3216b710b085c72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmV-J0KETr0ZYosPf{>7WKdRCRtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya ZR^a0D%U8(FFG^L&POU8F0st#)6CKCE976yA diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 b/test_data/test_repos/test_repo_4/dotGit/objects/b1/07a0d7a337f04413efa73d337461f548aef336 deleted file mode 100644 index f3a3ba397cb7bcdf3a412d6dfc9fb894d0078301..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmV-Z0IdIb0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 p4t)_1sDF|ORfwdj$-7J2t^fQYmj~1KhU_rq*b(=o0|06ZB8_FFBvb$Z diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 b/test_data/test_repos/test_repo_4/dotGit/objects/b1/0b3e2cb320a8c211fda94c4567299d37de7776 deleted file mode 100644 index ac93c76f113240b82f367789ed77ddde86fef0fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmV;V09*ff0iBLPY6CG00CV;$^nn&zvg|d4kgsTEZL>7H4vs@;Uf=W!Jq-*DjJ9oC z2OyTi=w{$&CGlFAl4{0GbB;@#tg0rdCN(4?TC%%Iw|&6GsT7M?79z{cF);a3CgGWD zo3eSrkOqXQx2Ds9`75uy%aHgo!zD`Zvhs45<{Qt|+8 z%w=?DAgK*vltGg>7?aU{@eY#>Zet%}wAv$UB@XOd2c&=`w+~#t(3?SJGnTu zOuEL+qrlJDTZa>Ahn|Vye*U6AkKRVB1@rqxtvo7GGH(?FfcPQQAp1$$w^JjF4il_&&^>-nR!J-r1t06oPB52 zP8IT4K52GPfhx?)k1tM5E=nya*2_&{P_Ye;ZFxKW_aR=+la~&C5f7+;k_c6Zq)KzE b$iIMV%Qvl(I2$4Dwj#Ra(3Q;q8>lmO1$Q-+ diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 b/test_data/test_repos/test_repo_4/dotGit/objects/b8/a52870f2b093699e0d98cb896387c87e0c98a6 deleted file mode 100644 index ff582f60d9d67a6b5395c3aa58dd494fc1e81ff1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66 zcmV-I0KNZs0ZYosPf{>7U{F?8RtU++ELKR%%t=*9&d)1J%*-oRD9+DKRVYqPE=nya YR^Z|)O3lqL%gjqx$SmOk032`=6r7A3DgXcg diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 b/test_data/test_repos/test_repo_4/dotGit/objects/c0/23aab082c73abd327675ad485fe78bb427ae21 deleted file mode 100644 index 5e07a20409f13dd488cf7491b257265742ae009f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmV-a0IUCa0V^p=O;s?rWH2-^Ff%bx$jgr}PE9UKEh*N^O<_>64UTPjJN@?|Ue1%3 q4t)_1sDF|ORfwc&+Q9>hleNB2dw+R~&cPe9RbTqn+5rHDd?aRS4q2I{G;Jxca*K7#kaz82kHpI=U)x0RTC68;+D+ BC@ug1 diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 b/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 deleted file mode 100644 index 1533a3b46..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/cd/5eb8bef855f73c46b97b4c088badffdc40ebe9 +++ /dev/null @@ -1,3 +0,0 @@ -x] -0})JDJ҂i6+401j]; Kf09}4Q(3kletXԞ$2t1%Hх b>hsw>}igd% yzjZ7j wQU -p?G| \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 b/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 deleted file mode 100644 index 62c73ed71..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/ce/835da266b3f8c34e4b7f398693ed068f67cb30 +++ /dev/null @@ -1 +0,0 @@ -xAj0 EgS-lE Wป9}+t?>j-OU!z"#96D $3#-ѫM攮ǀp]Y8%cJp'13-i^}6Q쟩/wK֚{lֲ޹ﰕz/FMq \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a b/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a deleted file mode 100644 index f195924bf..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/objects/d8/ac0b73aeeb45843319cdc5ce506516eb49bf7a +++ /dev/null @@ -1 +0,0 @@ -xAj1 E)t۲b BUdEI]^!kom1}ad%WO$\3#'ΨY pÐm2l|,GCaD`PZ19>%?㲍>d9hogGninXzyج7&J/ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 b/test_data/test_repos/test_repo_4/dotGit/objects/de/ea550dd6c7acaf0e59432600593533984a2125 deleted file mode 100644 index 7ed4768c5f0684bc184dc370af4797ebe642bbd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmV;P0Ac@l0iBLp3c@fDMg7hyW&_IPIVp&^mFXm*1=Exe{pjkgTkz|04jj1BYF!5y z<1eG<46{aJOvKhwLFcs1g~_H9UC_n5$hlY>)XqI`14_`6qK`Bai%#S@PK+{fiG*y5 zaT3r3tN1;Z*5P1Tps$kQe*C6C_ufX^DzC4bwE6(;$)Ir)TDYP^RHr>Jj{H}wQvSf) Md6Pwb0i<(BR=a*tOaK4? diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace b/test_data/test_repos/test_repo_4/dotGit/objects/e0/894b9037d76464dbb8d25768c9a036987d6ace deleted file mode 100644 index e8012361507a6bef2c7c0aa5978280534fbf95bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmV-<0EYi~0V^p=O;s>7GGH(?FfcPQQAp1$$w^JjF4il_&&^>-nR!J-r1t06oPB52 zP8IT4K52GPfhx?)k1tM5E=nya*2_&{P_Ye;ZFxKW_aR=+la~&C5f7+;k_c6Zq^kKS bx7dGgLr)P^@kMJ-r0KJ4-K-1%0-7+V0?IV! diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 b/test_data/test_repos/test_repo_4/dotGit/objects/e8/abc5d9c3ea7760bf20054e8dada3832f9a00a9 deleted file mode 100644 index aaa3f442044293fba056e43ba7f5c6ce03677cbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmb)7U|?ckU~Cwu;peO8rK@@Ev~OaE?=xYayw5NBgeT9LnQ}69Thhu> KH3lnoJ{|z;z7p>M diff --git a/test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 b/test_data/test_repos/test_repo_4/dotGit/objects/ef/8fd94f0a1a6f503949ac4b56f3604ec4e942e3 deleted file mode 100644 index 6de0925540e5eabb2472e1f36a01ac4eb15ccb99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99 zcmV-p0G$7L0ZYosPf{>6v|xyiE-KAQEsl-l;!H^`PARd'8OkiM{n\7ཅvZӞV`jw.K \ No newline at end of file diff --git a/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev b/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev deleted file mode 100644 index 986aea9ec..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/refs/heads/dev +++ /dev/null @@ -1 +0,0 @@ -64cfcee9aad1c84581631636bfc54f2050718d1a diff --git a/test_data/test_repos/test_repo_4/dotGit/refs/heads/master b/test_data/test_repos/test_repo_4/dotGit/refs/heads/master deleted file mode 100644 index b05755804..000000000 --- a/test_data/test_repos/test_repo_4/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -7b2eba252004b7c867413def2a0984d545daab8b diff --git a/test_data/test_repos/test_repo_4/gitleaks.toml b/test_data/test_repos/test_repo_4/gitleaks.toml deleted file mode 100644 index a09fee0fd..000000000 --- a/test_data/test_repos/test_repo_4/gitleaks.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[rules]] - description = "entropy" - regex = '''['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]''' - tags = ["entropy"] - [[rules.Entropies]] - Min = "3.3" - Max = "3.5" - Group = "1" diff --git a/test_data/test_repos/test_repo_4/no_secrets.md b/test_data/test_repos/test_repo_4/no_secrets.md deleted file mode 100644 index 243d535d8..000000000 --- a/test_data/test_repos/test_repo_4/no_secrets.md +++ /dev/null @@ -1 +0,0 @@ -### This file does not contain any secrets diff --git a/test_data/test_repos/test_repo_4/secrets.md b/test_data/test_repos/test_repo_4/secrets.md deleted file mode 100644 index 67c45b604..000000000 --- a/test_data/test_repos/test_repo_4/secrets.md +++ /dev/null @@ -1,21 +0,0 @@ -### This file contains some secrets - - - hey, if you type in your pw, it will show as stars - ********* see! - hunter2 - doesnt look like stars to me - ******* - thats what I see - oh, really? - Absolutely - you can go hunter2 my hunter2-ing hunter2 - haha, does that look funny to you? - lol, yes. See, when YOU type hunter2, it shows to us as ******* - thats neat, I didnt know IRC did that - yep, no matter how many times you type hunter2, it will show to us as ******* - awesome! - wait, how do you know my pw? - er, I just copy pasted YOUR ******'s and it appears to YOU as hunter2 cause its your pw - oh, ok. - diff --git a/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG deleted file mode 100644 index c629f60f5..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/HEAD b/test_data/test_repos/test_repo_5/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_5/dotGit/config b/test_data/test_repos/test_repo_5/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_5/dotGit/description b/test_data/test_repos/test_repo_5/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_5/dotGit/index b/test_data/test_repos/test_repo_5/dotGit/index deleted file mode 100644 index c4a9350cedc43f950ad704a8dad9085692b69321..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217 zcmZ?q402{*U|<5_IMd0?M4cL3K(xq_&j%S97+4tsle-xh8kaCIFn$H95dmV>>3S>v zeEEEHkywgP-$vPw7TS4Cs~I@*@=H>S^>R}f7~)K)w+QX}ybnzKDr|duHw|>qSTUNy@E=hU0@Ir)p0_i>AM80{|YgNNxZC diff --git a/test_data/test_repos/test_repo_5/dotGit/info/exclude b/test_data/test_repos/test_repo_5/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_5/dotGit/logs/HEAD b/test_data/test_repos/test_repo_5/dotGit/logs/HEAD deleted file mode 100644 index f4063b514..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/logs/HEAD +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec Zach Rice 1580490269 -0500 commit (initial): init -547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec 1f2a4abc47dabf991e6af6f9770867ce0ac1f360 Zach Rice 1580569654 -0500 commit: introduce secrets -1f2a4abc47dabf991e6af6f9770867ce0ac1f360 ca71fcdeda15f25f0cc661d90e8785c255925c27 Zach Rice 1580569684 -0500 commit: introduce more secrets -ca71fcdeda15f25f0cc661d90e8785c255925c27 a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0 Zach Rice 1580571022 -0500 commit: even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master deleted file mode 100644 index f4063b514..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec Zach Rice 1580490269 -0500 commit (initial): init -547bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec 1f2a4abc47dabf991e6af6f9770867ce0ac1f360 Zach Rice 1580569654 -0500 commit: introduce secrets -1f2a4abc47dabf991e6af6f9770867ce0ac1f360 ca71fcdeda15f25f0cc661d90e8785c255925c27 Zach Rice 1580569684 -0500 commit: introduce more secrets -ca71fcdeda15f25f0cc661d90e8785c255925c27 a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0 Zach Rice 1580571022 -0500 commit: even more secrets diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 b/test_data/test_repos/test_repo_5/dotGit/objects/00/9114bb4fc3521c478aeb1666f4fc87a4fe2964 deleted file mode 100644 index 33381fc0af4225a45bf73cb4ab35d61c71273c12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmV->0EGW|0ZYosPf{?nG-pUGFOE-4PEIW@j?Yf5jL%H5Rd@9EboBH$b@O-e^D}pi zaP$rEaaHFkD9X$$(ZEoy$;E{shSdlod`9Hv7p2A*rzRJrmJ}=4DyUmpniv};rKOf9 drdb#nrzRU4S(>C885_dPKvoZQ0RX5iL$@DFfgjw;H \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 b/test_data/test_repos/test_repo_5/dotGit/objects/2b/8f95ef90b07889acd0607a91a22bee87ac4a46 deleted file mode 100644 index d98e1094cdfb7bd569737c0c9717d8b6ef90448d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmV-J0KETr0ZYosPf{>5V@ND7j!#TZPAx8u&rYq3&rGpZcl7pj^z=7%^LO#{Gk1+} Z^bPQFRp%-w%FHX#z)-Hq1pt|e7{netAn^bI diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec b/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec deleted file mode 100644 index 9e502d7f8..000000000 --- a/test_data/test_repos/test_repo_5/dotGit/objects/54/7bc0caa26ce3f20bea9ad9bb0f7e3e9dc749ec +++ /dev/null @@ -1,4 +0,0 @@ -xA -!F[{@1)DttLi ->xG&>d*3@hμZB$olEL.dT>&<pop5gW' -qe"!Eכj&Q3 \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 b/test_data/test_repos/test_repo_5/dotGit/objects/5d/bb39e8aa13063310c7cd4787a62d3119674be0 deleted file mode 100644 index 1dbbf398b598cba5295d46b010b11d569e967954..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87 zcmV-d0I2_X0V^p=O;s>AVK6i>Ff%bx$jdKDE!N9TVVJJB;?I}QHy4Se`1Ea*{b-?` t$Fv%%rZ_dZD7Bzn(P@3pv{&RJ(12LR%{Aac*XD@*_Y diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb b/test_data/test_repos/test_repo_5/dotGit/objects/81/723dcbff8ae8bbcb2fb3051bfd12c79bd4b8fb deleted file mode 100644 index 058a166446b2c3002c9137360bee5fb5a07a770a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87 zcmV-d0I2_X0V^p=O;s>AVK6i>Ff%bx$jdKDE!N9TVVJJB;?I}QHy4Se`1Ea*{b-?` t$Fv%%rZ_dZD7Bbd}oD)Ji9{#i23&b5-:y[#z˦quR/k•2'\Aw>G#a06 G \ No newline at end of file diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 b/test_data/test_repos/test_repo_5/dotGit/objects/cd/4f2dbbeb8c026390c7e31fd89c624f0552bdc2 deleted file mode 100644 index 54825cb8c9df7be85cbcd31aad8eea9332b6a510..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmV-50LuS(0V^p=O;s>9V=y!@Ff%bx$jdKDE!N9TVVJJB;?I}QHy4Se`1Ea*{b-?` L$Fv#%Q;ZP}Ff$i5 diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e b/test_data/test_repos/test_repo_5/dotGit/objects/f6/878b4d8b01947b3bd9bf23de8446cb6cae335e deleted file mode 100644 index 0f4f495710d4394b6276171f76b391d3303e8231..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmV-T0J8sh0ZYosPf{>6HfBgHFOE-4PEIW@j?Yf5jL%H5Rd@9EboBH$b@O-e^D}pi jaP$rEaaHFkD9X$$(ZEoy$;E{shSdloJVpQjET=DiZyh8X diff --git a/test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 b/test_data/test_repos/test_repo_5/dotGit/objects/fe/2074a5245bc33007255e6f4fe2e6e7464f2b55 deleted file mode 100644 index 6ea38dfc840aca28239b2b037923aa83166e9f8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87 zcmV-d0I2_X0V^p=O;s>AVK6i>Ff%bx$jdKDE!N9TVVJJB;?I}QHy4Se`1Ea*{b-?` t$Fv%%rZ_dZD7B_?EoLG{XpQl%un41GO=PXDI&^#~=)@~r)gl1lR%m#)FU#7*)=HcKF zaqr#l*M3msID>3*eqLH;x<0b81x5JD{#FUy3F#ANDl*FacWUnYLQ+^YH^8PK_y6UNRX>5kWyvPHB>O 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571595 -0500 commit: Adding some secrets in config folder -98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571636 -0500 discard: [bc379e22c22a97ca5ffc871c1449af854f6f26c4] diff --git a/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master deleted file mode 100644 index 1112c7dbc..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 98b6c7cb3fb29a5993c4c95c56a2dc53050b9247 Noel Algora 1582571595 -0500 commit: Adding some secrets in config folder diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_6/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d44974fe535cf2b75e37623bbcbb69492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 784 zcmV+r1MmEJ0fm%bZ__Xo#d)Ql;*wT$f0~2=FMx^!V~k0Rp|!kC3^%!H46Yq)XJZo| zp5r*BV@x3RA+>$)J@TEv_h8VmBU2=u-N+i_&7nWUB7FlBnQo z;i(obtRTM6+Gm_lWt1|PF=MD&a#SOYUZ;s6i0y;Mj+|+2!5PsUA)yDXHLY!oW0ELk zh)by3w6Te%pbC*kQDX<75>mO?gCK2mdd=35^TM}og3wK#kXpw1yNCh5}#@E#BmA2D{Is0Jr6u8;P>SuxKWin#wA&o+sPkKhfO+F^O^9$C0QsInxPc^d&q2y+I05 zU@Ct(v OU4)Rel7nBha@t(wn|DV5 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_6/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1d8cca5c8246d0dd18fc408854cbe069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmV;50CoR(0ZYosPf{>6GGlP@402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv sV+aXybp=vv47!F223)+Ejk-r?-kftzqvgflt1p>^C*RQm066(7zoF4W0{{R3 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_6/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899e55860a4eb9fd52adc3deaa74d41f11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmV+!0p|XA0acJ&P6IIvMfuJuF6pQOL0Wamv=Q^!XXiH1wk zg=vZz}Pal`Ndeue!ODiC}gn+foU}Oq=ooe=^kN1UoO^YsFL< f<^bLNA~fc6c>uNl!{+PhK{s#uTfL|spbC+Vc>jt5 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_6/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa77fbc9e56902bc61148d32e42a70755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmV-T0J8sh0ZYosPf{>9W(dv8OUzA8Q7B3+$S=+;$uFw3R!B|BEKw-Q$ShV!%gjkt jP)|uMPA9Zjg diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 b/test_data/test_repos/test_repo_6/dotGit/objects/5c/b000d0f4965e9b0c080814478dbf4e87c114c7 deleted file mode 100644 index 8226e0266b6e7ffe61314d45269678458f4b9075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmV-#0FeK90ZYosPg1ZnWynd)OD|1KPqj_Wi+A$eGm`)S diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_6/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3fabd74203f9f743d042f0cde0bc711f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmbBdhdwu^tQ1~wf8p^i(s0T zT2HqeOm$Cvty?mYbnd$p&zYJo)?BWL&a|~$Qhra_#ehHSSqI*Q-)@t3iM59A1KYt+VIRAuu?D5!oHdRkh=Z9l z4cA<$LrKOpU}jv3N|`|>qIcFqRj{m1r**9L8Xu$a!_IUIWNYV39ByH(eJ>{UqF597 z79A#4MEf0o26rK4{f4$2quwNfp^adhJk7qHf6nMt@57C7ZGztf9DKb}Y9MfuE!LUp zg2m!6Q|jU9;N;*x|CEB6n3=%31P63|h2F*$dLErh!J*m}qN?<2W-9tl*$bGj!zCY&NHlkQ(qMTiioLj@689l+~EN1AUr50RZ8Gd&+}$MZK3M99|M`{3Ice zX4u^@n%_}DbSwje%cj&AR@i`ni>=(lzX2VJjGjCN+>u+Y{zR{g!ofM6$)kXg3j~)& z2y6^kC)apPpy2J&qAo2R$pFH=hF<=}`InF{anG)ilLWz;Y%yeKBIKhGT-2UUUmQ~Q q!FR5FQcf<#NDkKR$-^;CUj~4gyfU=L3Y_JaCR(NFf%*+dC9pC^&}bt7 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_6/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0e62b9a281faba25dcfc481559bbccbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmV;00DAv;0iBIo3c@fD0R7G>_5w=MY#s#>uac}=5->*66``lMf+z56U|<;PtyKXN z<3R>9@XXH6ehKWRlrY{Hqsthr=bSYfqOb%)uhL6OAFw4VFe)*ew=c%^IlA;mOZ9%D n-Y#HVF!N-C4{+3|wc72z6#gsz)nMRVrNGKGSXT7`Tx&jrpjJOP diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 b/test_data/test_repos/test_repo_6/dotGit/objects/69/465772e5c3a14379da6c369cdb46edbaa6d097 deleted file mode 100644 index e59352e95772e6098665f165dce21d63710f0d03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmV;00DAv;0V^p=O;s>7v}76N4wm*^E#GAz7%S^xFtz0Z;j75m%kznPziiJt@jRLC^s?si0n diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_6/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee533384e5be65d132e80b92e8d46ca29a11c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 946 zcmV;j15NyR0d16FYurW)DX-B86r5$B= zb>|DAzrF9QbPg{4cBh@4dFP#Hw(6v!%OAe~@w>xU=auv4u`LdZLt1&_C({odQ!DaF zu?}uXl!P`MT(hHXYZAFgrjjv#ub67-dzTX1B{JNau47BpjuvZ|=CcKDU24e-nXn#v z_9-rj9@>4CR>scaGC$$U9O}z29E4&rX+*syaX{fXI=?34$qYk~AvlwmdXCYonOuV$ zn!%ueijGMJN+>f)ggyj32(dR6T1+iE(LT>8;8Q<;X`G%3Er!75baSyR3fGW!6nIk( zCPb#PoK5-l-Rft$Ik&ty_hZ-5o15dy0%d)1VAjU@n65RX;4X4;a7cIFC1<)>)fHLS zG&DzQZ`==QM=3CqRDW}wzU4W3tr}Vr+j2Uh5@XQF=kljT;|lb7*U(PJY=(A&xyTkH z@a5|L?cE(|m)dir$Vj19Yz+L&#t3qbye#r1+%d6s?s_U-i*MW--B%)Awl6MU#GPvO zKiIke=>$%O36+>Ehp;U8iEFyNIew#Yw?Sg0p);wG&=ZEL4P$!jZI-%EskCovY=Pjv`|ME^ofp-m4V*`;On-CztfNx^uqk1Yp2qt`B-L`|aoqrcB1thQ$a2WgOi4qWGyAfflt zVW^QVFHRzzk1^zJPvP{8qVsjeQJsjNM-zB20PC9oMvEmw0i|lqsO9L^9(!je zY0KgO!HFh1GRtLIo4Q3nSt??s_-=>adRBrvn0LLR@(Ug9q5oPO5Z&MYwYtB*zSX8n zOD7+w{O8lhixc`v+nUPyRBgPN7pull-oE|#?)P7ccOgi)q7|MXEKY{Ts&_A0Csl$q zeo)eDY*}s8bpQwA`-sQm#ky=IJWhihSoA#cSW@=z$7sE|wjb73&%sOtf!|_U`Ki U?AIJ_Y5s+)Q~BHc07G9gA$trp-T(jq diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_6/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66e206a72124d32206debad73e240f4ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2176 zcmV-`2!Ho@0hL($Z`;Tb?yursF{h}tlCB;Yhx@e zWu`QQ*14r9WUSEE&`Rai8XM-g{#7lQ)WrG?_S= zrZ!efQMwx=buJBUg&|n<5xN)>Hlo2IE?8<&r5o7HdcCzP8Y)e)tnH4r8(I0s{N7pD zXw8=Tg`)@?4m6^y3rS|9wgz6^l2v=Zs5(!>8bGoeVM)Nrq5#^}4v*~jG=-(S13YX)b+asTv%x-_+*qY|(Q_}l>|bvkKJ9O zV414;J*kXJVPL|P=%qn^(Cc3~mOfy(KjA&jm5aR$DiQjkaCu?y-Z>1kan73jcW>v- z4Sj({=|<7BzbvT#3MtbtXFYX;JA%#g&051a`XQ$U_DQnZ9R-t)X>j`H$A7;&ygUle zOS5JVKaLU`v<+@$-0PzC`#f?Xj}`st`>G$*4FBALK7zth)SSM(-t5Eh-QnbWG086f zI-(iN_lD?P$Ioa!;=5Zib&=cQ?0q#G2YB;K_X_Qc7`rTFNyApowI1Re%5BmJPlu-S-w@gZX7}VUNY|J!p%~zQ8b~{{FV5o-6iqm;FEd@c#Vu z+0~0z=Sgyb9v7Rkn<e(vSGPS7bphRB9JIo>9+PAH{DF!_N<5*-I0 zGC5Cc-feF&)VOBBT_M`)<{mgXkioA`H=NZvvHQR9>rZf<9jG#;05qjEZe%(^FMt z`MS|!iIEg9lfjQKFRspCzM1(qz{+8mIocn=@Mx@c47DPxyQepn` zam*($YbN?9ALc-I3?>LXvLVPGH{B)xfIMA%@L=Na^v9HFe_T+Hs|8e*=UGn zzY#Tf>=}*I81jZVc}9pGPDUGFfuY&052Yr8Kp_4h?SY|!55+j6xuggg3hwuMAds3& zCV%)1S?X5In0ENY{|~NNieCz7=I@eDS?2Bn2(e68$ya3f5k65eg|_xf&;3h&pRgr- z(fPUu?$7)7G75I(mJZ_C9mycq731su$E%z4W}ExdCQ{(pGsnp@Q0qWps)P_04HBQ z|HC7^tE_NB(qb)>=MOf%;09gR4JLM!ZYHt+VJ95+;(6wS_a=9&Z%Bk#IthP{KtfB@ z1!VR(WI8*)V<6@h7T=rK1+#bv#yfU8by$ED^}uByyy||BiACVsr7(%(-~Rym!v%V@ C_Bz%8 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_6/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d69460c86bbcd9b032b9c98776f077f08c21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmV;?051P{0Zorji^4Dv#XaX!4D`?yMX<7Z@=$I4!@4ShsHc)<1`XB(GQp+aeq&W| zPH$j-@4YE2TS78SS`lOxjP-Dl4nbKYP>zs{*Ro=vDjg(@p|su(de8MsK$w^Zako(s zEZ#5zd#BBrLGq_jx5;p%?CnMd340AG|G1D!5p!{+y3ja|)1PI!+;X&yJ} zSKao%?;|PMw46E3I-@`pk$3#=?z@ktMXna~=G)o%H{Dm$MJA^@jk-~n-boUl_ejwG9Hm0@1DYyih6^T#^<>(>4_*6~%F=+bqv% zA;|ebh?&IE*y{WgVxx3sR8dWczOQI05?GdM&r-KdOv=+ zy}$YJ3!{%$7LklPB2LjZH;$J@X>kHb-R!QVE$}#iF=2FlcF`EpYdEh|Nn0+>$UViX zwEbIdHb_r>pgWA<|InCv=kyj~UDI114<39l*Mnx~Cs1b=C0P`NQD=hDSoyfT_5N?~ zwc$<~o-^ES99SMY@=>A+k_s~DNd<9;Hii0K#KyjYM-BBD3+m7Q z=2PEfAv4Hwr;Gb>d@u{(rA}30?rUfB-koT zO&|M?$2Rz#+S$s2kQ=_j#L=iCe0jm@bRbzB%b|n3`SSR@)wF=qRx11g-ang&8#_4I zfxutNFNpXgN*wJWw(A-eY}f1uDCz8s{J8gsQLjKcdv)>Yn$XpcQ(0nqy0|`@A!>gI zg$1}p-usP7AH~B&v8*tQX4>c=%kJ8;&Ha-bTV9ZZz{%4|NO5ADagEh{tvzWxc`6V{Li;sv-@2XT6gZMlA$rl^Ro&wj)x3Z;J5!cXqFz&@9#O z+{cX@FfO5g4^nNRX;6Jq3HdJ{D@y3MebZsZ?WpgMTF%`Bx0kBcP4`14Go4~~by{{F J{R5J=dNhq_Y9s&v diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 b/test_data/test_repos/test_repo_6/dotGit/objects/98/b6c7cb3fb29a5993c4c95c56a2dc53050b9247 deleted file mode 100644 index f3467bbd4d3b4c11f03a43f5954b6cf9619053b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmV;h08jsT0iBN9ZNwlD0P{^1+d!fP7GtDSlxrY8;AKsactn`%KdvFaGa6}lv{n`v zXWrHnfs{Cf$Xh@P4ihu&LX31oBNig53zG4KXoDuctwnaqL zmigFhQ1P{X#)R)76`nPZ8R5}~#F|TfedQKQ{ov6)LA%{JuU&BPjt)`X^j=)@uUI`( eDm}wBn!qJIWnEA@@aSjBaE_W}D)k3TXHVivi&aAa diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 b/test_data/test_repos/test_repo_6/dotGit/objects/a1/ddd32febf3bde66331218f877ff637c85c5f92 deleted file mode 100644 index 0867e75c9a688924acd123a3cee57ab17c13a56b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmV;>05AV|0Zot1s=_c3g)|3Dg0e`U93dI6WywO7I!G8pVZH5lUTaf8n3(%jLRGAYaAIcw diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_6/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404ead93e87747db7463148dcfc4406264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57 zcmbOuDK-kgbrAKuAb%2QHA^dN)z?r`Std5O*i(wxzt< z<8Q{(x!A$u)AQBhdezymA|n=J0q+5Dr+sn=CdLg=pKW5`2))6618flb=)GldaRiS< zdPHEo!2sR95OhjzpEUOdh8#WULR4N`cM`V;qmKfb9Za0uy0{kP*0O;RgZjc8fmriI zpa;ebmT0nJEV$Vt$CRyRJW;_8PzgFP)wsklU8HRR&W@HU!nwG`b(P|}99}$jdTOu^ zk70`_=&qE)#?m48J>)X-$4Qk|l>GZ%c^YLaL<^&3MMe?wl*C+K*}clt!8Zn-Acho3~C3mIU^)2m!&xD{|}q*hdbH4$sh3|egWDEqwx$qkTC!N diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_6/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546046fd8e97c51aa441fc04770e35a2e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 529 zcmV+s0`C2I0ezC&Zqq;zhPjQO;>U@|L2;~bfdHwI3PI2tDpB`}kZNs@?N#kvcX!=# z2=C6U-H3n?H&HU4`43;5);h(@S1+E7pT?Skk)oml@JP|ZH;b? z6poIOAq#i~p&UDEKGm&vW|blO>cmsBW?kzC?#HW?^Wh1I$B^(nm;@^%yre|R5M9N$ zKKBxaM_js}_*E|z4qj1X%WxI&<+bt?#?%|6#HM~vLt={uxbsp!cg=(5Nq|o`L@x9z%<+64vz diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 b/test_data/test_repos/test_repo_6/dotGit/objects/bc/379e22c22a97ca5ffc871c1449af854f6f26c4 deleted file mode 100644 index ad8ee05b479c62be3ecdc997879e1cd70d7c4904..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmV;!06hPA0iDiEY6CG4MbV6V6}16}Zhb8XA%={dQ5H}tRm%c>f+T1C(Hb&)TsZKk zm69e1t6pYj2IG{`)(X}n@levbfQF=T6udGVJfaD^v)d1Lt`pqV8?xl(>4ih>oFqj~ zlQt*&ptv1FSQ+$5Jf+@dJEAMdVtI+l^(!gcueOq;1 xocu4m4gBQ*-}lciNcC*J;7qN;TF`m$1bSeNJOFEekOpB73!EwQ_yhQ*Ss;z>UgQ7( diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_6/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be8055a643e766f4891228035eb86c109..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmV;P0Ac@l0ZYosPf{>6F=cS^402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv zV+aXybp=wA42B8@T>m~x@=YnSt7xg(`Qg?o(Y06pUwMDDPPCEZ!SShDS_fbL%zb99 MyDotZ0RKTY9%ztF9RL6T diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_6/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ced73ec5db532487582e5971988714a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37 tcmbGp0iBLZ3Iib!1+(@PeSrkOqYWYCDy_E6KpY1#n>l?Jt4f_zRr-(&nB2tcWwxwjtMI6+5AFw#*6Y53jY@%`KF=nfmIn>TY z6AKoK-U@n;wRJcttiG%-=fA$O& IAAFxjc?OwAqyPW_ diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 b/test_data/test_repos/test_repo_6/dotGit/objects/db/4ccd6cc9ef282e9bf2f8c5f7877f0d40520724 deleted file mode 100644 index 7f8431777a0b401f45298e1a0df6364593149613..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmV-J0KETr0V^p=O;s>8U@$Z=Ff%bxNGvGG$xKcx$;{8wD=5k@NG&SKOf6=J*}!n& Z%e1)JJRBS%?!Ei{+7F5x2LL$x6(>ml8+8Bx diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 b/test_data/test_repos/test_repo_6/dotGit/objects/dd/6e8207f130e113c97f5ed15238e7901290ee42 deleted file mode 100644 index db5b596edb2959c3cae95e467f751e8a9afaa2fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmV-w0G0oE0ZYosPf{>6Fk?t8DDX?nO|?=`a?dQuNlnZy)(uH5F3HSG*L5r?P~u7~ z$c!(^&rZ#=Qb?^x%q_@C4NgriN-YUUEG{n3FG}G`Ns2FkvaJ-#Qj02~@7v}76N4wm*^E#GBk7x9X;hOqMSZiufX+c=rYScB0T^q{W1q<5I?m5 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_6/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077bbfa5593abd0ed2b1ae93b259fa6873e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1646 zcmV-!29f!A0hL$pPa8Q9y|0_UV!A|1QjsieKinx4t`+@poGL&qy`EGka(11>Wn(Y4 zmo%dEZ@)M8E&+OXYWV<(?HSL!dGkC>N;9D+PagmJ%f^GOb~c+RomJA7olfl}Id4_& zx5MY9uv+Pvi{JK-_QvDGO6tekoz4b5*CfA)MO8|g8*@%Bx2p2w4JqyA%nC2*gYfx$ zAvBKn=iXOtoMlsy%LxodGv(*?WTZ^CY>s6ET4Ir~!+u;PWkGdCh4eD_hy;GLT$0cQ zEli=N3j0%4N;m3kVDEU|#G)Kk!a3{;x|G%_qp6?Q)=KTm6+IdR7lOQ6NQ6sTXyasV zbm8D;YV1OI&(;nO7!f@S7N+)9?Oh1Y7x+e^EMo-Z=fcxmTuPcq$r;~7=#S;jzoE`J^?*lbON|e_I-R&M|l^WeCK{N-)9&O;#KtHc^Lz z_iq{?3`s2}Sn_jV!S&h16N3Ow+M#F9-@g7U5NB^L^Yf5a;0?3IGAY_hbvkOg zc0oHkT(7H6vcb{7vAQBx>I{#?{-7 z$$dJcop01zxRvYC*RRxV7V_0>sdO*od)E+YeNg(z?F%>XKUp}t*j)N{fiMVkH>j**~Dz6w<}!v2o)vr&f3Qit))@^y({QNGu)>Xg)f+@;!Ld-G=wv`s0lpSv z>OS}x{FyTQXg4%aC@=I1*SMet6Iq%iEoBd|2p5_QZ4YKGq(k4`>ghndxzIDPBzAJ7 z*#zCclrY!mRBwfL3hF|AFe|q*^ro1C+HAkJ(1uC_UlzeA=Lg`@2A?=KB=X!qPL-R7 z9^GuBtGT&D5^1oVU_I8RKzb~n zDYUaJT*}8vwP3-GPNKx|a?pqd5M8cDEU)_epw^(mnY0U-axl}{!lUJ$g@6i(EWRQ{ zSC<}g-DHiW9D&UY*ap$65)}6>ISJ5d{uy(B|a|=I<(ygYb;woa0dQ8v>} zO7C_cRv<1((o_nBW%=6-OAX*-`j|4P>1kZP1z*@Q9!@@{kQOrypJLG)CB=;~JD9Vh za5@bEyY%$*6gOSt7Xn5272YjRp#k>~s2egt_&^7oX_oPwdlq%6P$-GUEeu@&M^REY z+oq>&|L$I+?W1mfXrAjaio3w;UZAYLwi*ordPf5NgisRXejR|kpp-!l{r^8VDUDh} zY2tN2x=rE76@qGw(ZQ`vS(CF*Csz>92+L<@^jUR2Lp&1Kh2pki`scgDgYo$9ci2n1 z?Lpv|wi|&e5YXhBSkC|}PTsXXI{FXmqa(HskaKwq{NCI#+y$|RyS1PGHry@n_7$>! zlRb-b65h`!;k&dI`n_w0yI0a$W3Rvaj;t41-OLMyd(@PeM8XI%dI%+kut06_u8$rL z2=fFhUQlpZU}WR8BGujf&;!L9K3T>J>}aXvnmfHA~895N^u zUv9?2=H&feLzR+9lULz+VD}4g&T0{-&c^P37%eq_U&=yl+r9R!^gQ9s}_z*mGRDfe|FR8MI5D-!W%Pk>Ts5{we}yZ9Ch+baCPBo&IV<}Vil s|FdAcmITIy*&-ctJ8*Q3bZv4c#&{z)pIwE^!@F{gK(9Oh0QinDkobiyOaK4? diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_6/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4610280c50c51ee98c9c92925d129f44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0V^p=O;s>4VlXr?Ff%bxC{8UZOD)nXNi8nXE2w0c7i6TmS?aFJbAA2S R+-k1pH>Wz?0RWT25#mb?7wrH5 diff --git a/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_6/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAHdjX8fwljG;`*Kluj;-i0<-Zme}~_ z!1ID{vvQma7&uc(b8{>8N-9bq<`i#V2{s2vL(Tb(Y7Ue2rbI<`Yw1s~EutQJU0Cq3 z?eUU&Zw9f_wEW`u+|2ZhlK7<5_@dOr9I&B44}=7{x&kRl24e*SF7dC|e^jdOU7J36 k!=F0i=8FG24bzgmf?SP^GL9t(em{0@cK@%J2M@Xf0QU`Lj{pDw diff --git a/test_data/test_repos/test_repo_8/dotGit/info/exclude b/test_data/test_repos/test_repo_8/dotGit/info/exclude deleted file mode 100644 index a5196d1be..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test_data/test_repos/test_repo_8/dotGit/logs/HEAD b/test_data/test_repos/test_repo_8/dotGit/logs/HEAD deleted file mode 100644 index c1e43ae7b..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/logs/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 748f11eaf2c38c3cf0ac6a22e44208777e79fa6f Zach Rice 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master deleted file mode 100644 index c1e43ae7b..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/logs/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 748f11eaf2c38c3cf0ac6a22e44208777e79fa6f Zach Rice 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD b/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD deleted file mode 100644 index c1e43ae7b..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/logs/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 748f11eaf2c38c3cf0ac6a22e44208777e79fa6f Zach Rice 1595702825 -0400 clone: from https://github.com/zricethezav/test_repo_8.git diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a b/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a deleted file mode 100644 index 1f425766c..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/objects/0b/aadf22eda42ba55c4fec3e14973edc6cec783a +++ /dev/null @@ -1,4 +0,0 @@ -xuRn8@Z TdYqEK@Rb[LQVO7̻C^zRGs2дlJuf۔SmrRfZꎝ*4u!_$6 a :*:)Ǩg ptjnFM]s8eiZjd6#.QH'ZawxxiD-KE3fj'`$ (崣9_R2Op$a0G+@}F{-N]fG(!~4ґfL~9>ӹ|x ʰw inN#>ǘyvtfaz.Cw5o{}t,'Fߨ_ XBy<֢e)lb3Q@\1d#rGWΤi0y_.4G:Z`2(M$zE8>k,o- -LJ'zv.n 9mEn)׋}2FPn/7 %J~0' ;9ЈRfy' -AOh̟wcJEAӝ@k[ u~,@n?HV7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@c;ZL{WQoqR3J&rFKr^WHqzLR*Xpbu44nwDQ2pPQMUQ4*h& l8ef!}m;=^P`s%s^%WL)HFCX6hJn=*4D;CF3P5`W%HJBfgK{fyY diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/0c/79fa4384c973e9a6fe794491492da04ea289aa b/test_data/test_repos/test_repo_8/dotGit/objects/0c/79fa4384c973e9a6fe794491492da04ea289aa deleted file mode 100644 index 40b16b2a84b0a583d54c820f77fd705d10863b2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmV-}0DS*=0V^p=O;s>7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@cVe`5TU-x-6?|$`8HtXs3&;SL6#(7XhrD^%a@wu7l871*a lsqsari8){$Hm7s6jeEqich^1?^|`)HmOnA{8~_T`GypwVK_f*yynL(&ZwlW|Q1bJu_^ftU70y^RYzCPLHy4#2D zs;=tlLwDRYP1yqpE5CZ4ra(fNVMWd&9E&o`NJbQ>%#e&_l**AfLm5J{0+GP3ebI4n zU~$3t0M=!kf|rqh$v3^_4J(ho)*Zr1aQBou}Z0`QR=JyGBb=@ zuB}yTR#e!%iQK$Xni!@@7qn_slAO<>2`6HMV$n486&JufX(ww*3*@`!*}m_7z$(*R z6iHP_#Sw2ON_uCLw2DGQL>imyRXxiMD>&?KXIeqGwZ7|=)DwU;ub`H)dB)7#WY(siSFvSdhwq{b zZxJO!m;}r1;KJIFEvq7-Uo#etH&im`w3G#~xhtV4%k|2(CuF6YBWu^h!H+a)oDZoc zkFW^e$8@>xy6|b#@7Nv?KJE(XaaxN+s|3(a{rGU^qj%MpQGg2WZ_GlQKAGdK$pd{= zYpazs$$KvtWZiqu;!Q1fI^R89nRLVDRRFKNJ?@2{&2(q}@5KbOE&Gxk!Ot;10TD3D EILeX&#{d8T diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/17/f5d7f87925bdad6793b0fc7e338378ffb93166 b/test_data/test_repos/test_repo_8/dotGit/objects/17/f5d7f87925bdad6793b0fc7e338378ffb93166 deleted file mode 100644 index fef363e1c8081bde6bb32983d7b3128dd24ef73b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmV-}0DS*=0V^p=O;s>7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@cA*6J2SwwV~AG5^9HwT^QZQ7Z!YMd%UFH8vvdnG(0u~JJbLG diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/23/efedf4961168dc048e896f68eda78bcfb8e51f b/test_data/test_repos/test_repo_8/dotGit/objects/23/efedf4961168dc048e896f68eda78bcfb8e51f deleted file mode 100644 index ed1e3becd5a56bd84ed93118a59d806bd3908572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmV-}0DS*=0V^p=O;s>7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@cA*6J2SwwV~AG5^9HwT^K1Kil diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/2a/5fecc2737429b02047e5a99d9c0ac6e76a3ac2 b/test_data/test_repos/test_repo_8/dotGit/objects/2a/5fecc2737429b02047e5a99d9c0ac6e76a3ac2 deleted file mode 100644 index ec7b7787adeb92a015ff8e9c7bc88a5640a46277..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 554 zcmV+_0@eL^0d-N?j-xOD+h@Ka?`XC_0x8nWYLb=~XrYuITjq@;9Ob5=*Vk`%o_GCX z$&zKuj@!B}IKYzhgAa^>NSEYPLokvVVMS3EHBhT9be1&ly4iDfLF$3?<;YGt|H?+KM z>aeJO#%=uz$f~Yl>6L@Pn}j4uc&V?JoDE=EaC3~nd(#fAs~(?O!SgZtk1gx6OOb)M zzo5p_a)Gz>z|LB_WPk9DZ(RTaxLs&W386DWwsdQ!rYUV_K3(Dbj5b#|ST{lv)3OMe zV?$IB($f5#EUpv#Xlff)2q1GzyO(#^I>S}u2Bhq&Y9=?nsvAnVb|dSq;yk@+A*EG+ zYSvxVxu*6c&cXJ`<}M0Aj73FyP4_Brc|b9hQ3J~Y-;W(Tk+PgugqNXK5StQxZw-dy zglM&T@HE)Wjod5+aL5wRANLAfT~1Th3Cw#s5|MFeM!0}T`VFlsJNhBIz>?|DvL#-;IAKN<~s8( zFZq&}yyU}mSr!cFqWptVLVzTblq9KQYNDta2^JKC7^aqL21$@^#5j!&qKYZkAWA9* zB&4PUV@a2FMKWVS5)_@N$TSlZ3kYjO*N}{`#G#JmH3cVxb3_La7MOsKCw&$DYG}>s zszk;09oOYgAgZRS3zDV?;7w2jfqT){OGYU03O4Ct@KM#2G}qxPD_Gve|Cwb?))pCf z`yI>m`~a-H71;P*0Jpo){lhuHfk$g$3qs3=aBZ!p>0}~4?9iI&`B_=sW$Hg5OeVe$ z?Y)ba*Mw|?r9WTQP3cyifGZA6qPP{Byq=^tx#+xuU(I)9-Rt8%DQ22Bj6)Mz#ElB) zVdFw2Be=4+(!!hVV}AV1-+k)r`P0H;BUf@zm}SbcA2v7ju`$j#3HfMP z&2N(8&u*>A;vIh(bfc4=9Psk_td?cNlFeiNxKkL3xg*&^MPWgE&o=P|dDCGt3)?G( zEQ4&V&uX%l_sJMpj>dtACpRk{4Po?jvwl8{>9Of*1i^TDRY2k>%_=Cf}5x>pSb&FQ291 EgHDJY*8l(j diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/3c/cb6c2b338c176bbb7de1154cd7b61d0f6155ce b/test_data/test_repos/test_repo_8/dotGit/objects/3c/cb6c2b338c176bbb7de1154cd7b61d0f6155ce deleted file mode 100644 index f17380c84..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/objects/3c/cb6c2b338c176bbb7de1154cd7b61d0f6155ce +++ /dev/null @@ -1,4 +0,0 @@ -x5QJ@ })rRQ. -*L̴^CÏI|>Hgđp =ŌSvwAVK6i>Ff%bx2y%6F@paY9O<~yZlX$D34*;pN9@pE5E35zj diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/54/759376585b8a4e0318b1ecc0e770f69a6c4230 b/test_data/test_repos/test_repo_8/dotGit/objects/54/759376585b8a4e0318b1ecc0e770f69a6c4230 deleted file mode 100644 index a2e02e6b4a884c3ed5080b49cbe4b3bbf1feedeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmV-;0Ehp00ZYosPf{>6wP0{eNy*GhS4dPSPE9UKE#XQmFOE-4PEIW@j?Yf5jL%H5 zRd@9EboBH$b@O-e^D}piaP$rEaaGsh;^IQntB{|kkeHWWl95`ZkW`eImz<%fs7Q)| a!TGtV3c2}3sS3&Yc_pcNC0qcfdNq%vR6PO! diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/61/4a498fb4c38af5f5909718481e8b371f118901 b/test_data/test_repos/test_repo_8/dotGit/objects/61/4a498fb4c38af5f5909718481e8b371f118901 deleted file mode 100644 index 380207392de6161abf5bc9271714479adb268bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O<~yZgnQ;!?A=P2_kxsE0c?X43~OR1buJML%L3u$WsR|aebe^Z z&Sj)e8fiw8^=(@TfE4YU;FJP6(`{QfOhky9Aw(#lIb9YZg5Gan9xX-Ap^?1_w=HfVc zu-Q1P?V*1ib_A6cT=sZSLlzy_EP+%BdYIX0?IfI9KAG4eDgv=@O1y_|Ob_aACfjxN zB&z1zF0#;ii?Z_YJSA~d&;CIIpLklBS*41F;#YzZ9w#e6)my{39sx$tB0**@1AX3GM;MIBywjaf9Uj#-BZ zoKJn>O%3+qh%KB((5H(87<7?34+>nyb-fFgr!?k)FBl0ezdf4nv}N)xhDWGfFhXb; zzqYyKNG@Hn`5Zl60;h!dp{gG#hS!2Y9E!e+}zk);ocJ1YgVyvc^$%AT)(H$ zI+&uD*W+8}jt>%eSbK3N{rzkeE&u(PbQtnfP;f5#@uRI+DLx4O;52Q%i&^{v>RsR7 Dkh&0) diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/64/dbb271509f9b9647106da59914a6f5320de7c4 b/test_data/test_repos/test_repo_8/dotGit/objects/64/dbb271509f9b9647106da59914a6f5320de7c4 deleted file mode 100644 index 572af320aa4be96923d1a746313e2416e63bd0b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmV-}0DS*=0V^p=O;s>7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@c;ZL{WQoqR3J&rFKr^WHqzLR*Xpbu44nwDQ2pPQMUQ4*h& l8ef!}m;=^fb2>-cxJNvDckM$_pX=LX`4dCW0RVu!G1U7iKm-5) diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/74/8f11eaf2c38c3cf0ac6a22e44208777e79fa6f b/test_data/test_repos/test_repo_8/dotGit/objects/74/8f11eaf2c38c3cf0ac6a22e44208777e79fa6f deleted file mode 100644 index 062870af1..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/objects/74/8f11eaf2c38c3cf0ac6a22e44208777e79fa6f +++ /dev/null @@ -1,5 +0,0 @@ -xuI@sW51ЬL4a21i,n/L&-y>*iR7)diz0mʌB c ÐZi-b1U:%*mBPbZjP,ɲ)*FlLTU"^ L -`] -9k.?HSn리ϫ'JPR} -xKQ6<3XzKmK@!BB+g2W35q0X30dO5{Kg#(mBy>Hr~#AbNn^0YOJWW!T3`cXd+O>5{JQWZkE^hTvXq zPO{a*8t9jN_2>6}HAWfX`ug@_FK{nuq70nic}6dr_V7fh;3VmE{8V@ycEjTUuZasB zI7WEDH-cwb2zH!2r%B5$;l<7K*1a2HXP1Dif(rqGy%&c2_S z9UKPufh(IYOn_Rlyw4xXj2KESL%eQ<|&q zl)e-C?-G=a8?G)dZ+cMVHUdlEIJJf5P{~;6H!hs8u%za^4P3BU!>H!jTQLO8_Ba|{ z5lhr$>p6$U*$Qg5MGdl5%)GQJ19h>s{&Z!<+KqX_L7hE}GWy$W`1y^)ynAAK+YlaDneVmN0 ziY01gn|TY3i#4=jiyYEB7GAx}KtpPt{N?=nWb34*=$EXfZ-=uh+MH6_NQcY$kEOKB c{*#J!T__Z-ZYswg-#x#!tp8s37at+VI<=C$uK)l5 diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/92/67bc86ec1497471cbc6f3308f3527f7ef34b9d b/test_data/test_repos/test_repo_8/dotGit/objects/92/67bc86ec1497471cbc6f3308f3527f7ef34b9d deleted file mode 100644 index 9ab8fb9f5b259eb165741b9f04994e5991ce7a03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 554 zcmV+_0@eL^0d&MQ6=dcwe- z-CXHNSGv++m%1(lKoI^A9p?Ztgj1@ihQ=^bIi~ZJBdlpy*07RLsBx+om{O^w9d86U zsVB~ms!>f=b;L9So{*u>IaIKb@VSPmp7K=IBsz%v(t((=oOU;`FBk{U_wKv8*S5Qe zOH5GLsO~B4lUo+|+UIjBvw=1Rw&Uy6Bv%=+YX&e^i zJ7pGvSGOL+Rt|(clfXQJ>aEi=QhMf9J1*i$**zF&Le1xKvmrDxbW51jyIQ)4mi9WR zO0FK?uG!LQ_OqETfloFZ{8c;<`Y=QKV(dldjNCi2o8_+@HxLKQ#ve(RyH^~3(19eO sQ9u`!K`@>2>_q}Ew5@m2UuU+r__r}BY7;6rNQSz;J&7;z3z3`Jkd<8!ssI20 diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/b0/e4c4f24e7787b8ae08521f56b5dd9a76f90011 b/test_data/test_repos/test_repo_8/dotGit/objects/b0/e4c4f24e7787b8ae08521f56b5dd9a76f90011 deleted file mode 100644 index 0fbd83bbc0569fc192e9268623ababa49e7417a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43 zcmb;<18d&oq77YZThc z?MW(c8^gSeq+j3vYf3V~$J_VsjsjmL&s2ajJT4ey*8v_VSDYnZ&c76%#>03&!c*o7 zCr%0O@R{IIR)PcPz$TBW;s zOX)44|1Lqg9+ixRe&EU(D@*RqyWoo58YVT*!I~jrv5%9{ zRk1{^Y%|x;xL89gwx~n)j)m9WWuQK_p8Vzf`(*2+rO+=~P2Ub@SF|~$w2_XN^B+rT nm;EOdb6wq$TjNy*GhS4dPSPE9UKE#XQmFOE-4PEIW@j?Yf5jL%H5 zRd@9EboBH$b@O-e^D}piaP$rEaaGsh;^IQntB{|kkeHWWl95`ZkW`eImz<%fs7Qi= I0P09C_?5OZp8x;= diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/b3/bec734a41357c480b7856e0298de649a5fef14 b/test_data/test_repos/test_repo_8/dotGit/objects/b3/bec734a41357c480b7856e0298de649a5fef14 deleted file mode 100644 index 66a5e8cbccc9c59bff6d8f57a9720167af70f0e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmV-60?GY&0d&MQ6=dcptT~c^Ra3RLBdG<^^dW-Bh+QkCXs$ObGe<$;@nL z?&eBIy3&y@t52sw0*tgDQg9ATJ)u;^$bfcgQ`^)rf@VSt+eSJuQ$tf>!ZFj8h6r9s zz&Pd>!kE(3A_%Jtn$#qSYZwv@>xsdToth?8NGtPNfKS45B6<)MjDwfEc$9c+L@n#; zM2hm6)u*2T8Mc9;s;d@wf;xoCgFY-J7hqOMuchFnss(S#{w*tH-qQcfvL?F}8F=~~ zcQW%=U^Cl*(4VcG-A6F_!xf-_?&31naomyPY~AfV^}L>q0(XJ)qrSds!tWd>@qFKz z_9ED?!`>T5Y#W8l({d|pi2@R@i&c0S@uB^#SA7r`mrFG0J8ef(SRXh2X1dg}FkLV< zr_EqKf7d40S{;#X>g#o3DL}Kmyfn4K)OLO2m*d@f?4m2&w^(b9!aTej_xI}D$;7Px{BQM(2i!O6wBq_ zU*WlRy~Q0~(53Ua#tJBmn#vtUGB+!0Qw@UN8b&Qzr=j<4ZRW#|GZbRlq_XZLTuJ{B zHPd?#1p9Hi>^}8Z1-y9BHd&4T{g^TmoJbDZw7z_uiY%93lz%-~`7Cep7kb0s ETgWvYC;$Ke diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/b9/01f643b1eeeaeb7ff12931213bd0d9a47254d1 b/test_data/test_repos/test_repo_8/dotGit/objects/b9/01f643b1eeeaeb7ff12931213bd0d9a47254d1 deleted file mode 100644 index 32965723788ae8009793ba676eba5b2cb9ca4d44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmV-}0DS*=0V^p=O;s>7GGQ<@FfcPQQ3!H%bn$i7%S~a}@Z`uRzw-7S>o|hs!?xa? zRrZrX5UMDpG&i?WucV@cA*6J2SwwV~AG5^9HwT^-cxJNvDckM$_pX=LX`4dCW0RWN5GEXtWJXZh! diff --git a/test_data/test_repos/test_repo_8/dotGit/objects/ce/6e0398cd8a40085cad12a8f4c96e580c2200c1 b/test_data/test_repos/test_repo_8/dotGit/objects/ce/6e0398cd8a40085cad12a8f4c96e580c2200c1 deleted file mode 100644 index 142ab78be68660bd00d64e26c4f67cf0b120674d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmV-p0-XJL0d-PKZ<|0E?3rJ&w;U`tzyb?WQU&}1V`B{QE4O`NaBaZLf@6Mt-A28& zbNQsveA0|&Xmz<15+ECXlY(=gq0D3`vyr2lgkfeO2NE@-h(l;YWM>(1pk`T0jRh|y zfR^e|%os-mQXA@!Ii_PkW^tC$%%KRIHX|(it5*reEYo$)u%Q!dn$*ZRgv`t;`eu}PA<9q2s)Hi9xi0gAzzwX!dTZ<}%ZtvJdpBR6AY1;tD&Uej zhqT+MWEV1h^f6KGb-$58p-bOINYlMzL*3+4g^O)Ww)^?*gteeg{ZsNe>*}Caz%C}q z&)q>d3)LNbE>_|7@L`NuqK~F+U#_l8FTO5UvPY(E>@|NT#;g3C1uM;JZNmG9hmm$u zM>Li#v&NK0X11M9%SE6%xjbH zCdZO(qws#d?NgWMVIa4`bJwP`DCh|~oU6OJbkccOBaIGZG|=+sPWaSFu>#)5O$(*m zPww5QZpu+af{7{yFe$3SKHqNU8sb>ITit1NDPIC4M)E@=*)F1UGY;|Ua{tiWTug)FKPpN9>ng3IBT>=$gc_PSX=?U}EbyOnsr3@}ns1@IUs3C0U}xv>le%w`x2=Ii6O*Y;hW z^cLw!FRIHjV?c)d57tr&L`mkcAYmM0Dg{BJAQAEl1yeo_5sWC76cmI=;+mkP6$8AK zAX%nV2yyZZJxwZO0b(JRWgJH`#Q};jOt_$DY2AWz5T!x;0NX60;B9K3)P6K=&FZQQ zvf?$W%b$Qp7|BprARfFx5kl^%K36i@0wZH)AA+~4ZfR3IJ}wzc`|v-tOLOV63wZer zjTn{#T*C!B%W%}aw8w)vHq=IH8M&6d+#T;CV1HK=NAT9&F> zYI=+heSV(}svnOD)P0O@955z5HephNj2>< z-;#$~L5=1{gL!u+!~x|}T7q3*r|CrUX(nXj*y||WLoDj3YMi}P-#)eV3Wf0QDfOmK zquM6@tew{L;|*0DI0WXyD%f5^ntqL`nHwUnHyQNLv1RMbx?T$Fl$(A|DwwZWK3B@e zd4HbHfq&Zh+lT|?noFx~*o?E3b!+>UdEKZNz1X(nz#kbIGUb*yP1GyAd0OU&s5bod5s; diff --git a/test_data/test_repos/test_repo_8/dotGit/packed-refs b/test_data/test_repos/test_repo_8/dotGit/packed-refs deleted file mode 100644 index 749d59553..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/packed-refs +++ /dev/null @@ -1,4 +0,0 @@ -# pack-refs with: peeled fully-peeled sorted -ce6e0398cd8a40085cad12a8f4c96e580c2200c1 refs/remotes/origin/additional-secret-branch -748f11eaf2c38c3cf0ac6a22e44208777e79fa6f refs/remotes/origin/master -64b4391ddf2b399fb5218ee44cf90111d3f7ca9a refs/remotes/origin/zricethezav-patch-1 diff --git a/test_data/test_repos/test_repo_8/dotGit/refs/heads/master b/test_data/test_repos/test_repo_8/dotGit/refs/heads/master deleted file mode 100644 index 4037f091a..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -748f11eaf2c38c3cf0ac6a22e44208777e79fa6f diff --git a/test_data/test_repos/test_repo_8/dotGit/refs/remotes/origin/HEAD b/test_data/test_repos/test_repo_8/dotGit/refs/remotes/origin/HEAD deleted file mode 100644 index 6efe28fff..000000000 --- a/test_data/test_repos/test_repo_8/dotGit/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/remotes/origin/master diff --git a/test_data/test_repos/test_repo_8/dummy.txt b/test_data/test_repos/test_repo_8/dummy.txt deleted file mode 100644 index 547593765..000000000 --- a/test_data/test_repos/test_repo_8/dummy.txt +++ /dev/null @@ -1,8 +0,0 @@ -Adding a secret -aws_access_key_id='AKIAIO5FODNN7EXAMPLE', - - -Adding a secret on another branch!!! -aws_access_key_id='AKIAIO5FODNN7EXAMPLE', - -Some more content diff --git a/test_data/test_repos/test_repo_8/ufos_might_be_real.txt b/test_data/test_repos/test_repo_8/ufos_might_be_real.txt deleted file mode 100644 index b26121273..000000000 --- a/test_data/test_repos/test_repo_8/ufos_might_be_real.txt +++ /dev/null @@ -1,19 +0,0 @@ -No Longer in Shadows, Pentagon’s U.F.O. Unit Will Make Some Findings Public - -For over a decade, the program, now tucked inside the Office of Naval Intelligence, has discussed mysterious events in classified briefings. - - - -Eric W. Davis, an astrophysicist who worked as a subcontractor and then a consultant for the Pentagon U.F.O. program since 2007, said that, in some cases, examination of the materials had so far failed to determine their source and led him to conclude, “We couldn’t make it ourselves.” - - -wowzers - -credit to NYT - - - -uhmmmmmmm - -Some more stuff - diff --git a/test_data/test_repos/test_repo_9/dotGit/COMMIT_EDITMSG b/test_data/test_repos/test_repo_9/dotGit/COMMIT_EDITMSG deleted file mode 100644 index 73bc0b919..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -gitleaks allow secret diff --git a/test_data/test_repos/test_repo_9/dotGit/HEAD b/test_data/test_repos/test_repo_9/dotGit/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/test_data/test_repos/test_repo_9/dotGit/config b/test_data/test_repos/test_repo_9/dotGit/config deleted file mode 100644 index 6c9406b7d..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true diff --git a/test_data/test_repos/test_repo_9/dotGit/description b/test_data/test_repos/test_repo_9/dotGit/description deleted file mode 100644 index 498b267a8..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test_data/test_repos/test_repo_9/dotGit/index b/test_data/test_repos/test_repo_9/dotGit/index deleted file mode 100644 index fcab4fb7a3d12b80dc1a24c9a945d129848353fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmZ?q402{*U|<4b#&{ErCjCo{HDEehHi40WftAs_^&A63;}W3sSD+dZAT9dy)91{j zUlylaRd>$&&h&eMomJ&>2EO9dqO#N?y^_@861{>-pjw8IAXir)CCOl@V8C_o^Dz@q qk7dyh-@Xmo^8M7g 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 8d1fb60d2d80f0590f191ed5ace1e45ef780909a Zach Rice 1597253780 -0400 commit: gitleaks allow secret diff --git a/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master b/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master deleted file mode 100644 index 8244f3823..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/logs/refs/heads/master +++ /dev/null @@ -1,3 +0,0 @@ -0000000000000000000000000000000000000000 6557c92612d3b35979bd426d429255b3bf9fab74 zach rice 1571923767 -0400 commit (initial): commit 1 with secrets -6557c92612d3b35979bd426d429255b3bf9fab74 d274003914c707212cbe84e3e466a00013ccb639 zach rice 1571925818 -0400 commit: comment -d274003914c707212cbe84e3e466a00013ccb639 8d1fb60d2d80f0590f191ed5ace1e45ef780909a Zach Rice 1597253780 -0400 commit: gitleaks allow secret diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 b/test_data/test_repos/test_repo_9/dotGit/objects/10/fa14c5ab0134436e2ae435138bf921eb477c60 deleted file mode 100644 index c32cf91d44974fe535cf2b75e37623bbcbb69492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 784 zcmV+r1MmEJ0fm%bZ__Xo#d)Ql;*wT$f0~2=FMx^!V~k0Rp|!kC3^%!H46Yq)XJZo| zp5r*BV@x3RA+>$)J@TEv_h8VmBU2=u-N+i_&7nWUB7FlBnQo z;i(obtRTM6+Gm_lWt1|PF=MD&a#SOYUZ;s6i0y;Mj+|+2!5PsUA)yDXHLY!oW0ELk zh)by3w6Te%pbC*kQDX<75>mO?gCK2mdd=35^TM}og3wK#kXpw1yNCh5}#@E#BmA2D{Is0Jr6u8;P>SuxKWin#wA&o+sPkKhfO+F^O^9$C0QsInxPc^d&q2y+I05 zU@Ct(v OU4)Rel7nBha@t(wn|DV5 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf b/test_data/test_repos/test_repo_9/dotGit/objects/3a/76f3781306faf5612017bf18a4b4bdb9f927bf deleted file mode 100644 index 0bd54d2c1d8cca5c8246d0dd18fc408854cbe069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmV;50CoR(0ZYosPf{>6GGlP@402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv sV+aXybp=vv47!F223)+Ejk-r?-kftzqvgflt1p>^C*RQm066(7zoF4W0{{R3 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 b/test_data/test_repos/test_repo_9/dotGit/objects/41/42082bcb939bbc17985a69ba748491ac6b62a5 deleted file mode 100644 index dba982899e55860a4eb9fd52adc3deaa74d41f11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmV+!0p|XA0acJ&P6IIvMfuJuF6pQOL0Wamv=Q^!XXiH1wk zg=vZz}Pal`Ndeue!ODiC}gn+foU}Oq=ooe=^kN1UoO^YsFL< f<^bLNA~fc6c>uNl!{+PhK{s#uTfL|spbC+Vc>jt5 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 b/test_data/test_repos/test_repo_9/dotGit/objects/49/8b267a8c7812490d6479839c5577eaaec79d62 deleted file mode 100644 index b558235fa77fbc9e56902bc61148d32e42a70755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmV-T0J8sh0ZYosPf{>9W(dv8OUzA8Q7B3+$S=+;$uFw3R!B|BEKw-Q$ShV!%gjkt jP)|uMPA9Zjg diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f b/test_data/test_repos/test_repo_9/dotGit/objects/60/c9e47f150a6b713e247e6105b77f1b961f844f deleted file mode 100644 index e212d90f3fabd74203f9f743d042f0cde0bc711f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmbBdhdwu^tQ1~wf8p^i(s0T zT2HqeOm$Cvty?mYbnd$p&zYJo)?BWL&a|~$Qhra_#ehHSSqI*Q-)@t3iM59A1KYt+VIRAuu?D5!oHdRkh=Z9l z4cA<$LrKOpU}jv3N|`|>qIcFqRj{m1r**9L8Xu$a!_IUIWNYV39ByH(eJ>{UqF597 z79A#4MEf0o26rK4{f4$2quwNfp^adhJk7qHf6nMt@57C7ZGztf9DKb}Y9MfuE!LUp zg2m!6Q|jU9;N;*x|CEB6n3=%31P63|h2F*$dLErh!J*m}qN?<2W-9tl*$bGj!zCY&NHlkQ(qMTiioLj@689l+~EN1AUr50RZ8Gd&+}$MZK3M99|M`{3Ice zX4u^@n%_}DbSwje%cj&AR@i`ni>=(lzX2VJjGjCN+>u+Y{zR{g!ofM6$)kXg3j~)& z2y6^kC)apPpy2J&qAo2R$pFH=hF<=}`InF{anG)ilLWz;Y%yeKBIKhGT-2UUUmQ~Q q!FR5FQcf<#NDkKR$-^;CUj~4gyfU=L3Y_JaCR(NFf%*+dC9pC^&}bt7 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 b/test_data/test_repos/test_repo_9/dotGit/objects/65/57c92612d3b35979bd426d429255b3bf9fab74 deleted file mode 100644 index edf7d2fb0e62b9a281faba25dcfc481559bbccbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmV;00DAv;0iBIo3c@fD0R7G>_5w=MY#s#>uac}=5->*66``lMf+z56U|<;PtyKXN z<3R>9@XXH6ehKWRlrY{Hqsthr=bSYfqOb%)uhL6OAFw4VFe)*ew=c%^IlA;mOZ9%D n-Y#HVF!N-C4{+3|wc72z6#gsz)nMRVrNGKGSXT7`Tx&jrpjJOP diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 b/test_data/test_repos/test_repo_9/dotGit/objects/6a/756416384c210ada2631f17862f5c01fffa478 deleted file mode 100644 index 072ee533384e5be65d132e80b92e8d46ca29a11c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 946 zcmV;j15NyR0d16FYurW)DX-B86r5$B= zb>|DAzrF9QbPg{4cBh@4dFP#Hw(6v!%OAe~@w>xU=auv4u`LdZLt1&_C({odQ!DaF zu?}uXl!P`MT(hHXYZAFgrjjv#ub67-dzTX1B{JNau47BpjuvZ|=CcKDU24e-nXn#v z_9-rj9@>4CR>scaGC$$U9O}z29E4&rX+*syaX{fXI=?34$qYk~AvlwmdXCYonOuV$ zn!%ueijGMJN+>f)ggyj32(dR6T1+iE(LT>8;8Q<;X`G%3Er!75baSyR3fGW!6nIk( zCPb#PoK5-l-Rft$Ik&ty_hZ-5o15dy0%d)1VAjU@n65RX;4X4;a7cIFC1<)>)fHLS zG&DzQZ`==QM=3CqRDW}wzU4W3tr}Vr+j2Uh5@XQF=kljT;|lb7*U(PJY=(A&xyTkH z@a5|L?cE(|m)dir$Vj19Yz+L&#t3qbye#r1+%d6s?s_U-i*MW--B%)Awl6MU#GPvO zKiIke=>$%O36+>Ehp;U8iEFyNIew#Yw?Sg0p);wG&=ZEL4P$!jZI-%EskCovY=Pjv`|ME^ofp-m4V*`;On-CztfNx^uqk1Yp2qt`B-L`|aoqrcB1thQ$a2WgOi4qWGyAfflt zVW^QVFHRzzk1^zJPvP{8qVsjeQJsjNM-zB20PC9oMvEmw0i|lqsO9L^9(!je zY0KgO!HFh1GRtLIo4Q3nSt??s_-=>adRBrvn0LLR@(Ug9q5oPO5Z&MYwYtB*zSX8n zOD7+w{O8lhixc`v+nUPyRBgPN7pull-oE|#?)P7ccOgi)q7|MXEKY{Ts&_A0Csl$q zeo)eDY*}s8bpQwA`-sQm#ky=IJWhihSoA#cSW@=z$7sE|wjb73&%sOtf!|_U`Ki U?AIJ_Y5s+)Q~BHc07G9gA$trp-T(jq diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 b/test_data/test_repos/test_repo_9/dotGit/objects/6c/bef5c370d8c3486ca85423dd70440c5e0a2aa2 deleted file mode 100644 index b098b0b66e206a72124d32206debad73e240f4ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2176 zcmV-`2!Ho@0hL($Z`;Tb?yursF{h}tlCB;Yhx@e zWu`QQ*14r9WUSEE&`Rai8XM-g{#7lQ)WrG?_S= zrZ!efQMwx=buJBUg&|n<5xN)>Hlo2IE?8<&r5o7HdcCzP8Y)e)tnH4r8(I0s{N7pD zXw8=Tg`)@?4m6^y3rS|9wgz6^l2v=Zs5(!>8bGoeVM)Nrq5#^}4v*~jG=-(S13YX)b+asTv%x-_+*qY|(Q_}l>|bvkKJ9O zV414;J*kXJVPL|P=%qn^(Cc3~mOfy(KjA&jm5aR$DiQjkaCu?y-Z>1kan73jcW>v- z4Sj({=|<7BzbvT#3MtbtXFYX;JA%#g&051a`XQ$U_DQnZ9R-t)X>j`H$A7;&ygUle zOS5JVKaLU`v<+@$-0PzC`#f?Xj}`st`>G$*4FBALK7zth)SSM(-t5Eh-QnbWG086f zI-(iN_lD?P$Ioa!;=5Zib&=cQ?0q#G2YB;K_X_Qc7`rTFNyApowI1Re%5BmJPlu-S-w@gZX7}VUNY|J!p%~zQ8b~{{FV5o-6iqm;FEd@c#Vu z+0~0z=Sgyb9v7Rkn<e(vSGPS7bphRB9JIo>9+PAH{DF!_N<5*-I0 zGC5Cc-feF&)VOBBT_M`)<{mgXkioA`H=NZvvHQR9>rZf<9jG#;05qjEZe%(^FMt z`MS|!iIEg9lfjQKFRspCzM1(qz{+8mIocn=@Mx@c47DPxyQepn` zam*($YbN?9ALc-I3?>LXvLVPGH{B)xfIMA%@L=Na^v9HFe_T+Hs|8e*=UGn zzY#Tf>=}*I81jZVc}9pGPDUGFfuY&052Yr8Kp_4h?SY|!55+j6xuggg3hwuMAds3& zCV%)1S?X5In0ENY{|~NNieCz7=I@eDS?2Bn2(e68$ya3f5k65eg|_xf&;3h&pRgr- z(fPUu?$7)7G75I(mJZ_C9mycq731su$E%z4W}ExdCQ{(pGsnp@Q0qWps)P_04HBQ z|HC7^tE_NB(qb)>=MOf%;09gR4JLM!ZYHt+VJ95+;(6wS_a=9&Z%Bk#IthP{KtfB@ z1!VR(WI8*)V<6@h7T=rK1+#bv#yfU8by$ED^}uByyy||BiACVsr7(%(-~Rym!v%V@ C_Bz%8 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c b/test_data/test_repos/test_repo_9/dotGit/objects/80/8b12c5ca4b142367932e7045d555a639fc148c deleted file mode 100644 index 9cd8d69460c86bbcd9b032b9c98776f077f08c21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmV;?051P{0Zorji^4Dv#XaX!4D`?yMX<7Z@=$I4!@4ShsHc)<1`XB(GQp+aeq&W| zPH$j-@4YE2TS78SS`lOxjP-Dl4nbKYP>zs{*Ro=vDjg(@p|su(de8MsK$w^Zako(s zEZ#5zd#BBrLGq_jx5;p%?CnMd340AG|G1D!5p!{+y3ja|)1PI!+;X&yJ} zSKao%?;|PMw46E3I-@`pk$3#=?z@ktMXna~=G)o%H{Dm$MJA^@jk-~n-boUl_ejwG9Hm0@1DYyih6^T#^<>(>4_*6~%F=+bqv% zA;|ebh?&IE*y{WgVxx3sR8dWczOQI05?GdM&r-KdOv=+ zy}$YJ3!{%$7LklPB2LjZH;$J@X>kHb-R!QVE$}#iF=2FlcF`EpYdEh|Nn0+>$UViX zwEbIdHb_r>pgWA<|InCv=kyj~UDI114<39l*Mnx~Cs1b=C0P`NQD=hDSoyfT_5N?~ zwc$<~o-^ES99SMY@=>A+k_s~DNd<9;Hii0K#KyjYM-BBD3+m7Q z=2PEfAv4Hwr;Gb>d@u{(rA}30?rUfB-koT zO&|M?$2Rz#+S$s2kQ=_j#L=iCe0jm@bRbzB%b|n3`SSR@)wF=qRx11g-ang&8#_4I zfxutNFNpXgN*wJWw(A-eY}f1uDCz8s{J8gsQLjKcdv)>Yn$XpcQ(0nqy0|`@A!>gI zg$1}p-usP7AH~B&v8*tQX4>c=%kJ8;&Ha-bTV9ZZz{%4|NO5ADagEh{tvzWxc`6V{Li;sv-@2XT6gZMlA$rl^Ro&wj)x3Z;J5!cXqFz&@9#O z+{cX@FfO5g4^nNRX;6Jq3HdJ{D@y3MebZsZ?WpgMTF%`Bx0kBcP4`14Go4~~by{{F J{R5J=dNhq_Y9s&v diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a b/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a deleted file mode 100644 index e086a5ae9..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/8d/1fb60d2d80f0590f191ed5ace1e45ef780909a +++ /dev/null @@ -1,2 +0,0 @@ -xM -0F]se߀gpn2bk$zWEmeFwMԯ*t_湼aG* \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc b/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc deleted file mode 100644 index 2103921eb..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/9e/523225b31add24e72f2feb0b2645cfb36542dc +++ /dev/null @@ -1,3 +0,0 @@ -xMO @;`%:XjE <ɺ;~ -z`~MV FӅPnHZ"-xILEca>ǠC㶮 ,)TNm7 -]U$J%R.wBΜ`ևq|It vmy_6?!0bW\>ε9 r:-A+a}^KN$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 b/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 deleted file mode 100644 index b72c5f771..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/a1/fd29ec14823d8bc4a8d1a2cfe35451580f5118 +++ /dev/null @@ -1,3 +0,0 @@ -xuPMO0 GV1lc.LEB`ĸ!Mi*a]R5!;N{+t;̍z-:K zQ"hEcRK\z5\~/7~ڑ_h|PMnXf]RvTVh$mSԄׂD+dUF\%Z}VJ{nPA@S"[z2=̧wv~5}IHLv,nu"CF_?dDг 9){e/,$axZugm -(jc~[+9%.N"s<=V -~LbYeM$ \ No newline at end of file diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d b/test_data/test_repos/test_repo_9/dotGit/objects/a4/fa2187727281aea78d7c3aaebdb4b924fc4e4d deleted file mode 100644 index 0aabdd404ead93e87747db7463148dcfc4406264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57 zcmbOuDK-kgbrAKuAb%2QHA^dN)z?r`Std5O*i(wxzt< z<8Q{(x!A$u)AQBhdezymA|n=J0q+5Dr+sn=CdLg=pKW5`2))6618flb=)GldaRiS< zdPHEo!2sR95OhjzpEUOdh8#WULR4N`cM`V;qmKfb9Za0uy0{kP*0O;RgZjc8fmriI zpa;ebmT0nJEV$Vt$CRyRJW;_8PzgFP)wsklU8HRR&W@HU!nwG`b(P|}99}$jdTOu^ zk70`_=&qE)#?m48J>)X-$4Qk|l>GZ%c^YLaL<^&3MMe?wl*C+K*}clt!8Zn-Acho3~C3mIU^)2m!&xD{|}q*hdbH4$sh3|egWDEqwx$qkTC!N diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 b/test_data/test_repos/test_repo_9/dotGit/objects/b5/8d1184a9d43a39c0d95f32453efc78581877d6 deleted file mode 100644 index 043d9c546046fd8e97c51aa441fc04770e35a2e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 529 zcmV+s0`C2I0ezC&Zqq;zhPjQO;>U@|L2;~bfdHwI3PI2tDpB`}kZNs@?N#kvcX!=# z2=C6U-H3n?H&HU4`43;5);h(@S1+E7pT?Skk)oml@JP|ZH;b? z6poIOAq#i~p&UDEKGm&vW|blO>cmsBW?kzC?#HW?^Wh1I$B^(nm;@^%yre|R5M9N$ zKKBxaM_js}_*E|z4qj1X%WxI&<+bt?#?%|6#HM~vLt={uxbsp!cg=(5Nq|o`L@x9z%<+64vz diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 b/test_data/test_repos/test_repo_9/dotGit/objects/c1/f3c6341548a65be1eded56b4f7cacec7fe9090 deleted file mode 100644 index 7a69ceae39b2ced357a194cee84ba746b5a31caf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0V^p=O;s>4VlXr?Ff%bxC{8UZOD)nXNi8nXE2w1n`RQ|J(l3isuBtod ReP{Z;z|N|2IRL_z6trD{7>)n{ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 b/test_data/test_repos/test_repo_9/dotGit/objects/c9/8e6c52cbd1f50de572ff12a3441271fccff705 deleted file mode 100644 index 14206b0be8055a643e766f4891228035eb86c109..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmV;P0Ac@l0ZYosPf{>6F=cS^402{*U|<4b#@LPP6&Tys1%m19Dqlth1{UVIz3dDO zjZ4IRR{C1x%{mHH#@5g+bo7+Bh;sU5y#m*(q021)i1aY<6{i-Jr55Rxq!yRx6;uMv zV+aXybp=wA42B8@T>m~x@=YnSt7xg(`Qg?o(Y06pUwMDDPPCEZ!SShDS_fbL%zb99 MyDotZ0RKTY9%ztF9RL6T diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c b/test_data/test_repos/test_repo_9/dotGit/objects/cb/089cd89a7d7686d284d8761201649346b5aa1c deleted file mode 100644 index 17c8d93ced73ec5db532487582e5971988714a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37 tcmbGp0iBLZ3Iib!1+(@PeSrkOqYWYCDy_E6KpY1#n>l?Jt4f_zRr-(&nB2tcWwxwjtMI6+5AFw#*6Y53jY@%`KF=nfmIn>TY z6AKoK-U@n;wRJcttiG%-=fA$O& IAAFxjc?OwAqyPW_ diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c b/test_data/test_repos/test_repo_9/dotGit/objects/e6/73bb3980f3c286291809e05f80873852bc3e9c deleted file mode 100644 index 144d4077bbfa5593abd0ed2b1ae93b259fa6873e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1646 zcmV-!29f!A0hL$pPa8Q9y|0_UV!A|1QjsieKinx4t`+@poGL&qy`EGka(11>Wn(Y4 zmo%dEZ@)M8E&+OXYWV<(?HSL!dGkC>N;9D+PagmJ%f^GOb~c+RomJA7olfl}Id4_& zx5MY9uv+Pvi{JK-_QvDGO6tekoz4b5*CfA)MO8|g8*@%Bx2p2w4JqyA%nC2*gYfx$ zAvBKn=iXOtoMlsy%LxodGv(*?WTZ^CY>s6ET4Ir~!+u;PWkGdCh4eD_hy;GLT$0cQ zEli=N3j0%4N;m3kVDEU|#G)Kk!a3{;x|G%_qp6?Q)=KTm6+IdR7lOQ6NQ6sTXyasV zbm8D;YV1OI&(;nO7!f@S7N+)9?Oh1Y7x+e^EMo-Z=fcxmTuPcq$r;~7=#S;jzoE`J^?*lbON|e_I-R&M|l^WeCK{N-)9&O;#KtHc^Lz z_iq{?3`s2}Sn_jV!S&h16N3Ow+M#F9-@g7U5NB^L^Yf5a;0?3IGAY_hbvkOg zc0oHkT(7H6vcb{7vAQBx>I{#?{-7 z$$dJcop01zxRvYC*RRxV7V_0>sdO*od)E+YeNg(z?F%>XKUp}t*j)N{fiMVkH>j**~Dz6w<}!v2o)vr&f3Qit))@^y({QNGu)>Xg)f+@;!Ld-G=wv`s0lpSv z>OS}x{FyTQXg4%aC@=I1*SMet6Iq%iEoBd|2p5_QZ4YKGq(k4`>ghndxzIDPBzAJ7 z*#zCclrY!mRBwfL3hF|AFe|q*^ro1C+HAkJ(1uC_UlzeA=Lg`@2A?=KB=X!qPL-R7 z9^GuBtGT&D5^1oVU_I8RKzb~n zDYUaJT*}8vwP3-GPNKx|a?pqd5M8cDEU)_epw^(mnY0U-axl}{!lUJ$g@6i(EWRQ{ zSC<}g-DHiW9D&UY*ap$65)}6>ISJ5d{uy(B|a|=I<(ygYb;woa0dQ8v>} zO7C_cRv<1((o_nBW%=6-OAX*-`j|4P>1kZP1z*@Q9!@@{kQOrypJLG)CB=;~JD9Vh za5@bEyY%$*6gOSt7Xn5272YjRp#k>~s2egt_&^7oX_oPwdlq%6P$-GUEeu@&M^REY z+oq>&|L$I+?W1mfXrAjaio3w;UZAYLwi*ordPf5NgisRXejR|kpp-!l{r^8VDUDh} zY2tN2x=rE76@qGw(ZQ`vS(CF*Csz>92+L<@^jUR2Lp&1Kh2pki`scgDgYo$9ci2n1 z?Lpv|wi|&e5YXhBSkC|}PTsXXI{FXmqa(HskaKwq{NCI#+y$|RyS1PGHry@n_7$>! zlRb-b65h`!;k&dI`n_w0yI0a$W3Rvaj;t41-OLMyd(@PeM8XI%dI%+kut06_u8$rL z2=fFhUQlpZU}WR8BGujf&;!L9K3T>J>}aXvnmfHA~895N^u zUv9?2=H&feLzR+9lULz+VD}4g&T0{-&c^P37%eq_U&=yl+r9R!^gQ9s}_z*mGRDfe|FR8MI5D-!W%Pk>Ts5{we}yZ9Ch+baCPBo&IV<}Vil s|FdAcmITIy*&-ctJ8*Q3bZv4c#&{z)pIwE^!@F{gK(9Oh0QinDkobiyOaK4? diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 b/test_data/test_repos/test_repo_9/dotGit/objects/e9/e5396f7e52aa48de485b4836ebb041cc7f7c46 deleted file mode 100644 index da7e1c7c4610280c50c51ee98c9c92925d129f44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 zcmV-B0L1@z0V^p=O;s>4VlXr?Ff%bxC{8UZOD)nXNi8nXE2w0c7i6TmS?aFJbAA2S R+-k1pH>Wz?0RWT25#mb?7wrH5 diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e b/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e deleted file mode 100644 index d7558de5f..000000000 --- a/test_data/test_repos/test_repo_9/dotGit/objects/ec/17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e +++ /dev/null @@ -1,2 +0,0 @@ -x-K0P9E [rK&0H -Ȥ&7~]/q\!vyrqִ0&א &HʉAHYQjJehI`(p7|0=(20^6+3Lc_~t<#<&K?dH#|>>A<=GNAwD$Qv}kJA{#Us7SiY#VG4~4ZZf>B0|9YTo}^iy z68O5q3OIOeTL$E3QP$t^B;EN;R*@R^Bwn~iDT%p0QCDj+`FB+)RNm(}7;j#qiNr_cZ2&TrcTm-cVBn~#daT`FFM WNC1_JeF5VSj^x2;OX3PNC|jdhXKG6T diff --git a/test_data/test_repos/test_repo_9/dotGit/objects/fe/f3190e94723e78847ab9f0daaa15add4ffd4ef b/test_data/test_repos/test_repo_9/dotGit/objects/fe/f3190e94723e78847ab9f0daaa15add4ffd4ef deleted file mode 100644 index 708c674cc657379608f2552cdc96673bc3a0f78d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 zcmb|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]''' +secretGroup = 5 +entropy = 3.5 diff --git a/testdata/config/base.toml b/testdata/config/base.toml new file mode 100644 index 000000000..ba7b2ce2c --- /dev/null +++ b/testdata/config/base.toml @@ -0,0 +1,10 @@ +title = "gitleaks config" + +[extend] +path="../testdata/config/extend_1.toml" + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/entropy_group.toml b/testdata/config/entropy_group.toml new file mode 100755 index 000000000..eacfc50ea --- /dev/null +++ b/testdata/config/entropy_group.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" + +[[rules]] +id = "discord-api-key" +description = "Discord API key" +regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]''' +secretGroup = 3 +entropy = 3.5 diff --git a/testdata/config/escaped_character_group.toml b/testdata/config/escaped_character_group.toml new file mode 100644 index 000000000..b28039539 --- /dev/null +++ b/testdata/config/escaped_character_group.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" +# https://learnxinyminutes.com/docs/toml/ for toml reference + +[[rules]] + id = "pypi-upload-token" + description = "PyPI upload token" + regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' + tags = ["key", "pypi"] \ No newline at end of file diff --git a/testdata/config/extend_1.toml b/testdata/config/extend_1.toml new file mode 100644 index 000000000..1f4eec0f0 --- /dev/null +++ b/testdata/config/extend_1.toml @@ -0,0 +1,10 @@ +title = "gitleaks extended 1" + +[extend] +path="../testdata/config/extend_2.toml" + +[[rules]] + description = "AWS Access Key" + id = "aws-access-key" + regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' + tags = ["key", "AWS"] diff --git a/testdata/config/extend_2.toml b/testdata/config/extend_2.toml new file mode 100644 index 000000000..7532c99e6 --- /dev/null +++ b/testdata/config/extend_2.toml @@ -0,0 +1,10 @@ +title = "gitleaks extended 2" + +[extend] +path="../testdata/config/extend_3.toml" + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key-again" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/extend_3.toml b/testdata/config/extend_3.toml new file mode 100644 index 000000000..47644c296 --- /dev/null +++ b/testdata/config/extend_3.toml @@ -0,0 +1,9 @@ +title = "gitleaks extended 3" + +## This should not be loaded since we can only extend configs to a depth of 3 + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key-again-again" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] diff --git a/testdata/config/generic.toml b/testdata/config/generic.toml new file mode 100644 index 000000000..625e44efc --- /dev/null +++ b/testdata/config/generic.toml @@ -0,0 +1,8 @@ +title = "gitleaks config" + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)((key|api|token|secret|password)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]''' +entropy = 3.7 +secretGroup = 4 diff --git a/testdata/config/generic_with_py_path.toml b/testdata/config/generic_with_py_path.toml new file mode 100644 index 000000000..a528893e9 --- /dev/null +++ b/testdata/config/generic_with_py_path.toml @@ -0,0 +1,36 @@ +title = "gitleaks config" + +[[rules]] +description = "Generic API Key" +id = "generic-api-key" +regex = '''(?i)((key|api|token|secret|password)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]''' +path = '''.py''' +entropy = 3.7 +secretGroup = 4 + +[allowlist] +description = "global allow lists" +regexes = [ + '''219-09-9999''', + '''078-05-1120''', + '''(9[0-9]{2}|666)-\d{2}-\d{4}''', + '''process''', + '''getenv''', + '''\.env''', + '''env\(''', + '''env\.''', + '''setting''', + '''load''', + '''token''', + '''password''', + '''secret''', + '''api\_key''', + '''apikey''', + '''api\-key''', + ] +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''', + '''(go.mod|go.sum)$''' +] + diff --git a/testdata/config/path_only.toml b/testdata/config/path_only.toml new file mode 100644 index 000000000..97a8a4870 --- /dev/null +++ b/testdata/config/path_only.toml @@ -0,0 +1,6 @@ +title = "gitleaks config" + +[[rules]] +description = "Python Files" +id = "python-files-only" +path = '''.py''' diff --git a/testdata/config/simple.toml b/testdata/config/simple.toml new file mode 100644 index 000000000..c5fbea1c3 --- /dev/null +++ b/testdata/config/simple.toml @@ -0,0 +1,222 @@ +title = "gitleaks config" +# https://learnxinyminutes.com/docs/toml/ for toml reference + +[[rules]] + description = "AWS Access Key" + id = "aws-access-key" + regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' + tags = ["key", "AWS"] + +[[rules]] + description = "AWS Secret Key" + id = "aws-secret-key" + regex = '''(?i)aws_(.{0,20})?=?.[\'\"0-9a-zA-Z\/+]{40}''' + tags = ["key", "AWS"] + +[[rules]] + description = "AWS MWS key" + id = "aws-mws-key" + regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' + tags = ["key", "AWS", "MWS"] + +[[rules]] + description = "Facebook Secret Key" + id = "facebook-secret-key" + regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' + tags = ["key", "Facebook"] + +[[rules]] + description = "Facebook Client ID" + id = "facebook-client-id" + regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' + tags = ["key", "Facebook"] + +[[rules]] + description = "Twitter Secret Key" + id = "twitter-secret-key" + regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' + tags = ["key", "Twitter"] + +[[rules]] + description = "Twitter Client ID" + id = "twitter-client-id" + regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' + tags = ["client", "Twitter"] + +[[rules]] + description = "Github Personal Access Token" + id = "github-pat" + regex = '''ghp_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + description = "Github OAuth Access Token" + id = "github-oauth" + regex = '''gho_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + id = "github-app" + description = "Github App Token" + regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' + tags = ["key", "Github"] +[[rules]] + id = "github-refresh" + description = "Github Refresh Token" + regex = '''ghr_[0-9a-zA-Z]{76}''' + tags = ["key", "Github"] + +[[rules]] + id = "linkedin-client" + description = "LinkedIn Client ID" + regex = '''(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}''' + tags = ["client", "LinkedIn"] + +[[rules]] + id = "linkedin-secret" + description = "LinkedIn Secret Key" + regex = '''(?i)linkedin(.{0,20})?[0-9a-z]{16}''' + tags = ["secret", "LinkedIn"] + +[[rules]] + id = "slack" + description = "Slack" + regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' + tags = ["key", "Slack"] + +[[rules]] + id = "apkey" + description = "Asymmetric Private Key" + regex = '''-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----''' + tags = ["key", "AsymmetricPrivateKey"] + +[[rules]] + id = "google" + description = "Google API key" + regex = '''AIza[0-9A-Za-z\-_]{35}''' + tags = ["key", "Google"] + +[[rules]] + id = "google" + description = "Google (GCP) Service Account" + regex = '''"type": "service_account"''' + tags = ["key", "Google"] + +[[rules]] + id = "heroku" + description = "Heroku API key" + regex = '''(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' + tags = ["key", "Heroku"] + +[[rules]] + id = "mailchimp" + description = "MailChimp API key" + regex = '''(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}''' + tags = ["key", "Mailchimp"] + +[[rules]] + id = "mailgun" + description = "Mailgun API key" + regex = '''((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}''' + tags = ["key", "Mailgun"] + +[[rules]] + id = "paypal" + description = "PayPal Braintree access token" + regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' + tags = ["key", "Paypal"] + +[[rules]] + id = "piacatic" + description = "Picatic API key" + regex = '''sk_live_[0-9a-z]{32}''' + tags = ["key", "Picatic"] + +[[rules]] + id = "sendgrid" + description = "SendGrid API Key" + regex = '''SG\.[\w_]{16,32}\.[\w_]{16,64}''' + tags = ["key", "SendGrid"] + +[[rules]] + description = "Sidekiq Secret" + id = "sidekiq-secret" + regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' + secretGroup = 1 + keywords = [ + "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", + ] + +[[rules]] + description = "Sidekiq Sensitive URL" + id = "sidekiq-sensitive-url" + regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' + secretGroup = 2 + keywords = [ + "gems.contribsys.com","enterprise.contribsys.com", + ] + +[[rules]] + id = "slack-webhook" + description = "Slack Webhook" + regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}''' + tags = ["key", "slack"] + +[[rules]] + id = "stripe" + description = "Stripe API key" + regex = '''(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}''' + tags = ["key", "Stripe"] + +[[rules]] + id = "square" + description = "Square access token" + regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' + tags = ["key", "square"] + +[[rules]] + id = "square-oauth" + description = "Square OAuth secret" + regex = '''sq0csp-[0-9A-Za-z\-_]{43}''' + tags = ["key", "square"] + +[[rules]] + id = "twilio" + description = "Twilio API key" + regex = '''(?i)twilio(.{0,20})?SK[0-9a-f]{32}''' + tags = ["key", "twilio"] + +[[rules]] + id = "dynatrace" + description = "Dynatrace ttoken" + regex = '''dt0[a-zA-Z]{1}[0-9]{2}\.[A-Z0-9]{24}\.[A-Z0-9]{64}''' + tags = ["key", "Dynatrace"] + +[[rules]] + id = "shopify" + description = "Shopify shared secret" + regex = '''shpss_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-access" + description = "Shopify access token" + regex = '''shpat_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-custom" + description = "Shopify custom app access token" + regex = '''shpca_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "shopify-private" + description = "Shopify private app access token" + regex = '''shppa_[a-fA-F0-9]{32}''' + tags = ["key", "Shopify"] + +[[rules]] + id = "pypi" + description = "PyPI upload token" + regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}''' + tags = ["key", "pypi"] + diff --git a/testdata/expected/git/small-branch-foo.txt b/testdata/expected/git/small-branch-foo.txt new file mode 100644 index 000000000..b3554c7ac --- /dev/null +++ b/testdata/expected/git/small-branch-foo.txt @@ -0,0 +1,17 @@ +import ( + "fmt" + "os" +) + // seems safer + aws_token := os.Getenv("AWS_TOKEN") +package foo + +import "fmt" + +func Foo() { + fmt.Println("foo") + + // seems safe + aws_token := "AKIALALEMEL33243OLIA" + fmt.Println(aws_token) +} diff --git a/testdata/expected/git/small.txt b/testdata/expected/git/small.txt new file mode 100644 index 000000000..7235dd3a8 --- /dev/null +++ b/testdata/expected/git/small.txt @@ -0,0 +1,67 @@ +import ( + "fmt" + "os" +) + // seems safer + aws_token := os.Getenv("AWS_TOKEN") +package foo + +import "fmt" + +func Foo() { + fmt.Println("foo") + + // seems safe + aws_token := "AKIALALEMEL33243OLIA" + fmt.Println(aws_token) +} +package api + +import "fmt" + +func PrintHello() { + fmt.Println("hello") +} +import ( + "fmt" + "os" +) + var a = "initial" + fmt.Println(a) + var b, c int = 1, 2 + fmt.Println(b, c) + var d = true + fmt.Println(d) + var e int + fmt.Println(e) + // load secret via env + awsToken := os.Getenv("AWS_TOKEN") + + f := "apple" + fmt.Println(f) + + // opps I added a secret at line 20 + awsToken := "AKIALALEMEL33243OLIA" +package main + +import "fmt" + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + f := "apple" + fmt.Println(f) +} +# test +This is a repo used for testing gitleaks diff --git a/testdata/expected/report/csv_simple.csv b/testdata/expected/report/csv_simple.csv new file mode 100644 index 000000000..ca3cb0a02 --- /dev/null +++ b/testdata/expected/report/csv_simple.csv @@ -0,0 +1,2 @@ +RuleID,Commit,File,Secret,Match,StartLine,EndLine,StartColumn,EndColumn,Author,Message,Date,Email,Fingerprint +test-rule,0000000000000000,auth.py,a secret,line containing secret,1,2,1,2,John Doe,opps,10-19-2003,johndoe@gmail.com,fingerprint diff --git a/testdata/expected/report/empty.json b/testdata/expected/report/empty.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/testdata/expected/report/empty.json @@ -0,0 +1 @@ +[] diff --git a/testdata/expected/report/json_simple.json b/testdata/expected/report/json_simple.json new file mode 100644 index 000000000..9d0a521ba --- /dev/null +++ b/testdata/expected/report/json_simple.json @@ -0,0 +1,21 @@ +[ + { + "Description": "", + "StartLine": 1, + "EndLine": 2, + "StartColumn": 1, + "EndColumn": 2, + "Match": "line containing secret", + "Secret": "a secret", + "File": "auth.py", + "Commit": "0000000000000000", + "Entropy": 0, + "Author": "John Doe", + "Email": "johndoe@gmail.com", + "Date": "10-19-2003", + "Message": "opps", + "Tags": [], + "RuleID": "test-rule", + "Fingerprint": "" + } +] diff --git a/testdata/expected/report/sarif_simple.sarif b/testdata/expected/report/sarif_simple.sarif new file mode 100644 index 000000000..802f415fb --- /dev/null +++ b/testdata/expected/report/sarif_simple.sarif @@ -0,0 +1,301 @@ +{ + "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "gitleaks", + "semanticVersion": "v8.0.0", + "rules": [ + { + "id": "aws-access-key", + "name": "AWS Access Key", + "shortDescription": { + "text": "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}" + } + }, + { + "id": "aws-secret-key", + "name": "AWS Secret Key", + "shortDescription": { + "text": "(?i)aws_(.{0,20})?=?.[\\'\\\"0-9a-zA-Z\\/+]{40}" + } + }, + { + "id": "aws-mws-key", + "name": "AWS MWS key", + "shortDescription": { + "text": "amzn\\.mws\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" + } + }, + { + "id": "facebook-secret-key", + "name": "Facebook Secret Key", + "shortDescription": { + "text": "(?i)(facebook|fb)(.{0,20})?(?-i)['\\\"][0-9a-f]{32}['\\\"]" + } + }, + { + "id": "facebook-client-id", + "name": "Facebook Client ID", + "shortDescription": { + "text": "(?i)(facebook|fb)(.{0,20})?['\\\"][0-9]{13,17}['\\\"]" + } + }, + { + "id": "twitter-secret-key", + "name": "Twitter Secret Key", + "shortDescription": { + "text": "(?i)twitter(.{0,20})?['\\\"][0-9a-z]{35,44}['\\\"]" + } + }, + { + "id": "twitter-client-id", + "name": "Twitter Client ID", + "shortDescription": { + "text": "(?i)twitter(.{0,20})?['\\\"][0-9a-z]{18,25}['\\\"]" + } + }, + { + "id": "github-pat", + "name": "Github Personal Access Token", + "shortDescription": { + "text": "ghp_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-oauth", + "name": "Github OAuth Access Token", + "shortDescription": { + "text": "gho_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-app", + "name": "Github App Token", + "shortDescription": { + "text": "(ghu|ghs)_[0-9a-zA-Z]{36}" + } + }, + { + "id": "github-refresh", + "name": "Github Refresh Token", + "shortDescription": { + "text": "ghr_[0-9a-zA-Z]{76}" + } + }, + { + "id": "linkedin-client", + "name": "LinkedIn Client ID", + "shortDescription": { + "text": "(?i)linkedin(.{0,20})?(?-i)[0-9a-z]{12}" + } + }, + { + "id": "linkedin-secret", + "name": "LinkedIn Secret Key", + "shortDescription": { + "text": "(?i)linkedin(.{0,20})?[0-9a-z]{16}" + } + }, + { + "id": "slack", + "name": "Slack", + "shortDescription": { + "text": "xox[baprs]-([0-9a-zA-Z]{10,48})?" + } + }, + { + "id": "apkey", + "name": "Asymmetric Private Key", + "shortDescription": { + "text": "-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----" + } + }, + { + "id": "google", + "name": "Google (GCP) Service Account", + "shortDescription": { + "text": "\"type\": \"service_account\"" + } + }, + { + "id": "google", + "name": "Google (GCP) Service Account", + "shortDescription": { + "text": "\"type\": \"service_account\"" + } + }, + { + "id": "heroku", + "name": "Heroku API key", + "shortDescription": { + "text": "(?i)heroku(.{0,20})?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" + } + }, + { + "id": "mailchimp", + "name": "MailChimp API key", + "shortDescription": { + "text": "(?i)(mailchimp|mc)(.{0,20})?[0-9a-f]{32}-us[0-9]{1,2}" + } + }, + { + "id": "mailgun", + "name": "Mailgun API key", + "shortDescription": { + "text": "((?i)(mailgun|mg)(.{0,20})?)?key-[0-9a-z]{32}" + } + }, + { + "id": "paypal", + "name": "PayPal Braintree access token", + "shortDescription": { + "text": "access_token\\$production\\$[0-9a-z]{16}\\$[0-9a-f]{32}" + } + }, + { + "id": "piacatic", + "name": "Picatic API key", + "shortDescription": { + "text": "sk_live_[0-9a-z]{32}" + } + }, + { + "id": "sendgrid", + "name": "SendGrid API Key", + "shortDescription": { + "text": "SG\\.[\\w_]{16,32}\\.[\\w_]{16,64}" + } + }, + { + "id": "sidekiq-secret", + "name": "Sidekiq Secret", + "shortDescription": { + "text": "(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\\-_\\t .]{0,20})(?:[\\s|']|[\\s|\"]){0,3}(?:=|\u003e|:=|\\|\\|:|\u003c=|=\u003e|:)(?:'|\\\"|\\s|=|\\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\\\"|\\n|\\r|\\s|\\x60|;]|$)" + } + }, + { + "id": "sidekiq-sensitive-url", + "name": "Sidekiq Sensitive URL", + "shortDescription": { + "text": "(?i)\\b(http(?:s??):\\/\\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\\/|\\#|\\?|:]|$)" + } + }, + { + "id": "slack-webhook", + "name": "Slack Webhook", + "shortDescription": { + "text": "https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}" + } + }, + { + "id": "stripe", + "name": "Stripe API key", + "shortDescription": { + "text": "(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}" + } + }, + { + "id": "square", + "name": "Square access token", + "shortDescription": { + "text": "sq0atp-[0-9A-Za-z\\-_]{22}" + } + }, + { + "id": "square-oauth", + "name": "Square OAuth secret", + "shortDescription": { + "text": "sq0csp-[0-9A-Za-z\\-_]{43}" + } + }, + { + "id": "twilio", + "name": "Twilio API key", + "shortDescription": { + "text": "(?i)twilio(.{0,20})?SK[0-9a-f]{32}" + } + }, + { + "id": "dynatrace", + "name": "Dynatrace ttoken", + "shortDescription": { + "text": "dt0[a-zA-Z]{1}[0-9]{2}\\.[A-Z0-9]{24}\\.[A-Z0-9]{64}" + } + }, + { + "id": "shopify", + "name": "Shopify shared secret", + "shortDescription": { + "text": "shpss_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-access", + "name": "Shopify access token", + "shortDescription": { + "text": "shpat_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-custom", + "name": "Shopify custom app access token", + "shortDescription": { + "text": "shpca_[a-fA-F0-9]{32}" + } + }, + { + "id": "shopify-private", + "name": "Shopify private app access token", + "shortDescription": { + "text": "shppa_[a-fA-F0-9]{32}" + } + }, + { + "id": "pypi", + "name": "PyPI upload token", + "shortDescription": { + "text": "pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}" + } + } + ] + } + }, + "results": [ + { + "message": { + "text": "test-rule has detected secret for file auth.py at commit 0000000000000000." + }, + "ruleId": "test-rule", + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "auth.py" + }, + "region": { + "startLine": 1, + "startColumn": 1, + "endLine": 2, + "endColumn": 2, + "snippet": { + "text": "a secret" + } + } + } + } + ], + "partialFingerprints": { + "commitSha": "0000000000000000", + "email": "johndoe@gmail.com", + "author": "John Doe", + "date": "10-19-2003", + "commitMessage": "opps" + } + } + ] + } + ] +} diff --git a/testdata/repos/nogit/main.go b/testdata/repos/nogit/main.go new file mode 100644 index 000000000..acbef43fd --- /dev/null +++ b/testdata/repos/nogit/main.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + // opps I added a secret at line 20 + awsToken := "AKIALALEMEL33243OLIA" + + f := "apple" + fmt.Println(f) +} diff --git a/testdata/repos/small/README.md b/testdata/repos/small/README.md new file mode 100644 index 000000000..5cc9baf4d --- /dev/null +++ b/testdata/repos/small/README.md @@ -0,0 +1,2 @@ +# test +This is a repo used for testing gitleaks diff --git a/testdata/repos/small/api/api.go b/testdata/repos/small/api/api.go new file mode 100644 index 000000000..d83247911 --- /dev/null +++ b/testdata/repos/small/api/api.go @@ -0,0 +1,7 @@ +package api + +import "fmt" + +func PrintHello() { + fmt.Println("hello") +} diff --git a/testdata/repos/small/dotGit/COMMIT_EDITMSG b/testdata/repos/small/dotGit/COMMIT_EDITMSG new file mode 100644 index 000000000..0ba1543fd --- /dev/null +++ b/testdata/repos/small/dotGit/COMMIT_EDITMSG @@ -0,0 +1 @@ +removing secret from foo package diff --git a/testdata/repos/small/dotGit/FETCH_HEAD b/testdata/repos/small/dotGit/FETCH_HEAD new file mode 100644 index 000000000..66c1c77ce --- /dev/null +++ b/testdata/repos/small/dotGit/FETCH_HEAD @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e branch 'main' of github.com:gitleaks/test diff --git a/testdata/repos/small/dotGit/HEAD b/testdata/repos/small/dotGit/HEAD new file mode 100644 index 000000000..b870d8262 --- /dev/null +++ b/testdata/repos/small/dotGit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/testdata/repos/small/dotGit/ORIG_HEAD b/testdata/repos/small/dotGit/ORIG_HEAD new file mode 100644 index 000000000..96321ccd4 --- /dev/null +++ b/testdata/repos/small/dotGit/ORIG_HEAD @@ -0,0 +1 @@ +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 diff --git a/test_data/test_repos/test_repo_8/dotGit/config b/testdata/repos/small/dotGit/config similarity index 68% rename from test_data/test_repos/test_repo_8/dotGit/config rename to testdata/repos/small/dotGit/config index 137b81bbb..374df60b1 100644 --- a/test_data/test_repos/test_repo_8/dotGit/config +++ b/testdata/repos/small/dotGit/config @@ -6,8 +6,8 @@ ignorecase = true precomposeunicode = true [remote "origin"] - url = https://github.com/zricethezav/test_repo_8.git + url = git@github.com:gitleaks/test.git fetch = +refs/heads/*:refs/remotes/origin/* -[branch "master"] +[branch "main"] remote = origin - merge = refs/heads/master + merge = refs/heads/main diff --git a/test_data/test_repos/test_repo_1/dotGit/description b/testdata/repos/small/dotGit/description similarity index 100% rename from test_data/test_repos/test_repo_1/dotGit/description rename to testdata/repos/small/dotGit/description diff --git a/testdata/repos/small/dotGit/index b/testdata/repos/small/dotGit/index new file mode 100644 index 0000000000000000000000000000000000000000..fec9889ae79cb0af45c8665b198e56dd8d7c80d4 GIT binary patch literal 317 zcmZ?q402{*U|<4b<|NgEnTjtrMZ;)D1_pixmjjO(7#f!_Ffe`vsu2NVgP4=MzTD)0 z%W!UW=m}>Yjr(?v>022%gIpb5d|mZ&Qy9SdU!VR2qoL+JMKj0!hLQV3kvrMX73%KP zn4g!s%d?E-_u#tY>PUcwTIjb}ZyF9^;An#aP-#~Ola9;5WE z$$I9mR{l=eFwgzzi^!9kPMmgM%fOzSn3)GLEF{R)6=qk^szME`|t0UuMCV?jzSJQU!;9}HeGn>%QuBR M$B!>J{IKCX0RPQ#yZ`_I literal 0 HcmV?d00001 diff --git a/test_data/test_repos/test_repo_1/dotGit/info/exclude b/testdata/repos/small/dotGit/info/exclude similarity index 100% rename from test_data/test_repos/test_repo_1/dotGit/info/exclude rename to testdata/repos/small/dotGit/info/exclude diff --git a/testdata/repos/small/dotGit/logs/HEAD b/testdata/repos/small/dotGit/logs/HEAD new file mode 100644 index 000000000..8fc59bb3b --- /dev/null +++ b/testdata/repos/small/dotGit/logs/HEAD @@ -0,0 +1,13 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896362 -0500 checkout: moving from main to remove-secrets +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 906335481df9a4b48906c90318b4fac76b67fe73 Zach Rice 1635896426 -0500 commit: load token via env var +906335481df9a4b48906c90318b4fac76b67fe73 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896518 -0500 commit: add api package +a122b33c6bad3ee54724f52f2caad385ab1982ab a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896543 -0500 checkout: moving from remove-secrets to api-pkg +a122b33c6bad3ee54724f52f2caad385ab1982ab 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896644 -0500 checkout: moving from api-pkg to main +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: Fast-forward +2e1db472eeba53f06c4026ae4566ea022e36598e 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896716 -0500 checkout: moving from main to foo +2e1db472eeba53f06c4026ae4566ea022e36598e 491504d5a31946ce75e22554cc34203d8e5ff3ca Zach Rice 1635896886 -0500 commit: adding foo package with secret +491504d5a31946ce75e22554cc34203d8e5ff3ca f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896931 -0500 commit: removing secret from foo package +f1b58b97808f8e744f6a23c693859df5b5968901 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635897009 -0500 checkout: moving from foo to main +2e1db472eeba53f06c4026ae4566ea022e36598e f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635897062 -0500 checkout: moving from main to foo +f1b58b97808f8e744f6a23c693859df5b5968901 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635897508 -0500 checkout: moving from foo to main diff --git a/testdata/repos/small/dotGit/logs/refs/heads/api-pkg b/testdata/repos/small/dotGit/logs/refs/heads/api-pkg new file mode 100644 index 000000000..18e1cff1a --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/api-pkg @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896543 -0500 branch: Created from HEAD diff --git a/testdata/repos/small/dotGit/logs/refs/heads/foo b/testdata/repos/small/dotGit/logs/refs/heads/foo new file mode 100644 index 000000000..0588ad530 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/foo @@ -0,0 +1,3 @@ +0000000000000000000000000000000000000000 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896716 -0500 branch: Created from HEAD +2e1db472eeba53f06c4026ae4566ea022e36598e 491504d5a31946ce75e22554cc34203d8e5ff3ca Zach Rice 1635896886 -0500 commit: adding foo package with secret +491504d5a31946ce75e22554cc34203d8e5ff3ca f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896931 -0500 commit: removing secret from foo package diff --git a/testdata/repos/small/dotGit/logs/refs/heads/main b/testdata/repos/small/dotGit/logs/refs/heads/main new file mode 100644 index 000000000..50148f0e8 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/main @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: Fast-forward diff --git a/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets b/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets new file mode 100644 index 000000000..58344a340 --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/heads/remove-secrets @@ -0,0 +1,3 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896362 -0500 branch: Created from HEAD +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 906335481df9a4b48906c90318b4fac76b67fe73 Zach Rice 1635896426 -0500 commit: load token via env var +906335481df9a4b48906c90318b4fac76b67fe73 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896518 -0500 commit: add api package diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD b/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD new file mode 100644 index 000000000..a2076e59a --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 Zach Rice 1635896329 -0500 clone: from github.com:gitleaks/test.git diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg b/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg new file mode 100644 index 000000000..9c8e059cf --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/api-pkg @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 a122b33c6bad3ee54724f52f2caad385ab1982ab Zach Rice 1635896552 -0500 update by push diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo b/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo new file mode 100644 index 000000000..f6aed264f --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/foo @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 f1b58b97808f8e744f6a23c693859df5b5968901 Zach Rice 1635896935 -0500 update by push diff --git a/testdata/repos/small/dotGit/logs/refs/remotes/origin/main b/testdata/repos/small/dotGit/logs/refs/remotes/origin/main new file mode 100644 index 000000000..530a7894d --- /dev/null +++ b/testdata/repos/small/dotGit/logs/refs/remotes/origin/main @@ -0,0 +1 @@ +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 2e1db472eeba53f06c4026ae4566ea022e36598e Zach Rice 1635896648 -0500 pull origin main: fast-forward diff --git a/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 b/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 new file mode 100644 index 000000000..dab89999a --- /dev/null +++ b/testdata/repos/small/dotGit/objects/02/d85657604c34e7b7fbb324a0c6c8b13c2c3760 @@ -0,0 +1 @@ +xU1 0`ܯ8nJ.:*(8\ɕ$ w3 Nox{$6f1~wF'0YbF TBpND|*]uCST kL>a#(Jm(sԴ]=>03 \ No newline at end of file diff --git a/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 b/testdata/repos/small/dotGit/objects/15/2888a42422b2ff5868b8d003d626120a9cb738 new file mode 100644 index 0000000000000000000000000000000000000000..f9ada07217b81e2055ac789cce7a4e74b3e98571 GIT binary patch literal 86 zcmV-c0IC0Y0V^p=O;s>AVlXr?Ff%bx2y%6F@paY9O<{;Rx$DbK{Gumc8zsg>LAvJ2Q?U=6|e)0ejD zt)0tgetI*~(;L#%b=d>mgkO42DZqp&I%S5!poy_gGmUDhoM{pxB$LHVq=Znz(1aFo zdhLOPwG1gTHXw$ODik3}oNpMEs-{Fu31Q5LYUqFUNP-Z{GSM)~K=|mDM-W)Zc-m$*N&$nrMP2Q58jD zrn9S_a^RNz+knCIwc)g_rq{geivj;}e|3-se&PcNL%e zQ;;b4v@3VTLW-;)cgwUii_$DRy-9v ztpA;u;8UJc&<<4vIPC^{>%mtEFy7Q){)mdA%Wa9;@~OS#f?#DCm z+g3V|4{yDhfkYA1=qagX<|xr;!bzsd6A#D>1O;7fFcTTz3L-*%#1k5+r#H!0s2t=lIIJcc>)JTtswKy;@)7rXr{ dc9K%r?~rSSL-ZkcgP+n@c$zlr?hoKjPX=)8R5Snp literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 b/testdata/repos/small/dotGit/objects/5c/547e4215d9594c3935bdfefdf4f500016a4112 new file mode 100644 index 0000000000000000000000000000000000000000..5bddb82e2d848a5f668c70a9b3a5d8887c4cfc67 GIT binary patch literal 51 zcmV-30L=e*0V^p=O;s>9VK6i>Ff%bxNG!9VK6i>Ff%bxNXyUHOV4Lux)Bzh;A8T9`|r&v3yz)GXrp7E J0016I4}|e<6uAHZ literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 b/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 new file mode 100644 index 000000000..ce4a269d3 --- /dev/null +++ b/testdata/repos/small/dotGit/objects/90/6335481df9a4b48906c90318b4fac76b67fe73 @@ -0,0 +1,3 @@ +xM +0F]s%t +"I2E۔ >x_2w@;z㑈ءCX@6 5)M&F:l'FTHďFF1iPSm4cNo;ݷV{]ߗT`=aZw d}fuKK \ No newline at end of file diff --git a/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad b/testdata/repos/small/dotGit/objects/9a/932e37eaa9fb64b09e47e5e859c9b2c8cb47ad new file mode 100644 index 0000000000000000000000000000000000000000..5e51e39d45702fbb232d53354c28fdca96718e6a GIT binary patch literal 196 zcmV;#06YJ90bPzU3&JoEggrOQLKvy9UR0#P(i^_uI*Jq)1;)a4&r||DLB;W z;C}EY9EH@< zNm5?*h56Y^?UatmS4O8uu|%JFb(vx|wF3N!l{cJy^3FMD*&freTen98Evpv-5E*wztdudOGZmB9!Yu1$CX`zyIq5KJWzunN+wPUSfIx literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab b/testdata/repos/small/dotGit/objects/a1/22b33c6bad3ee54724f52f2caad385ab1982ab new file mode 100644 index 0000000000000000000000000000000000000000..fbcf357cc571a102e357b16d95a3538941f33de3 GIT binary patch literal 163 zcmV;U09^lg0iBLP4#FT106p`H{eT7vERY!E8$5bjmPH$FX$W3?y?ukHNhX( zV6yr!x(H;hE=Y~8PATUg1qHn=Xex8Dx@cjR7*TE1WgU<-TI*djr6zLO#a(dH*2L^8 zalnkBO0bGPXKbJNk9&ZM1cv`F-NHT)?39F`+jRj@oOjcDpYQ`72gb R3eYygM*O0Os2|U*Nw*#3PL%)v literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 b/testdata/repos/small/dotGit/objects/a5/caae6d742e49a33982f1fdc608ce861ea59be5 new file mode 100644 index 0000000000000000000000000000000000000000..8be258a32c78adf07fdfe065081c2ef755049b8d GIT binary patch literal 134 zcmV;10D1p-0ac8#3c@fH0A2IG;_;?tv1nWr95PfWjp!dpS`sO3@=BB9ApX0Z1lQy4 z+L2q_spDp{-C&;%Ju^TbCZ02r519b`5<9#w7ZTqfR<^y*eavGlXthZKh_b}wTu7L# ocOdL5Ju(k2;^~Z}n_3%fs%vGG+8@--)SCWBzd*tVz6gvg!CC@8Z~y=R literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a b/testdata/repos/small/dotGit/objects/a9/aa0c942dcef669a94f207a77426106b25efd1a new file mode 100644 index 0000000000000000000000000000000000000000..9221b3c0ad1fcb47f3445b805507bb6d16a28197 GIT binary patch literal 143 zcmV;A0C4|!0V^p=O;s>7HexU|FfcPQQ3!H%bn$i7%S~a3Il1f0P5!qG=T?WFaOTmt zZ|9i4)x-b@6cP(E8Dc`}oJ4O%`dFIo{rC6FR|du`M40V^p=O;s>7Fk&z?FfcPQQ3!H%bn$i7%S~a3Il1f0P5!qG=T?WFaOTmt zZ|9i4)x-b@6cP(E8Dc`}oJ4O%`dFIo{rC6FR|du`M9WGF~X&Q45ERY)wz#Y>~ literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb b/testdata/repos/small/dotGit/objects/e5/c0849a65c586eab87dcfc31fec74f0fd7c62cb new file mode 100644 index 0000000000000000000000000000000000000000..53b83ef007a757e589e3cf16407ff49717397595 GIT binary patch literal 143 zcmV;A0C4|!0V^p=O;s>7HexU|FfcPQQ3!H%bn$i7%S~a3Il1f0P5!qG=T?WFaOTmt zZ|9i4)x-b@6cP(E8Dc`}oJ4O%`dFIo{rC6FR|du`M^uWjW>vuaQEcJLJ z>L?w@o3MG_#P_-@tE`tBRQ_N~E`9EzdVKecqb%|7rS!P8eom0mOD@ltuB>-{mwfbU z*H`zpt>JN+JJIsc*E~ykv8($JK7QPL1QK*?0YJa=0E;stV3xZI#0!8$LMSlF&IaPw vI(Ib7cDQF;Xqr=crnmpd4bOc^XAerFx|G@YAb-QBa2mkt=K#Lt>myWQtA&0RcKbuip?!xQV?Zf zfK&@@521UF$9mfA_7^N3u zXRrTixpZ@3B(aO$zo#ccuc`2{8TEYKk1*gD_t0slafXGv#MH>j|!Qu&8<5X z=&9g@H9H5gM!4BzT|YqQL9(m^AIL6Ewnbinu{6W&8mTvgnJ;&2){vv)4R0Ktd{6!m zyDzcXEU)dgFL{#r_X&kvIJH!Fiq`~LZ^paf^^HDnmK174*!i3s;hP_OSAdyhrH?}L zHD>oRn+z5=+w_kYWoO>Cj0T-naJCDpM==;$p>~NcyC~Zi1;i?1%Y`P-U`FCb*x*0c zVshQm#C1NNY0^Q8hBYH~L86JHo)sN1LW?b)nOxKEDUceaddeJ*#Cfb$FD@k;fe1o# zeLvPql}d0G!#rY0P+%`g&4dh{W^IH+8Ncd`C%lS8Ji960spKsoX(#WPG9el0^89(% zthmmuy%N67Am{}wGC*8#8Lc3Pk4)c9RrzY8emU{zvB8bN_~9i8ckId8qc4J&F_V0t z4p!|~L!k2lrhD2@DL?yu+s#IG=<+Pobnt%9!xb&@Fo0^5&I$fJQkl_^!BJM{UC*J> zDUnA$`P7*(sr3-^{<5fV+roJ=$t&om7$x=uqhW)K@;xAI+lP=XWnJhQ@w5)4lEcuD zpr9E{OnZGJbe_Do8&t}KzgNQs)EwlEkpRA}lXk^w|6L>?s?q|Gu;8;wSZd-lSM{#Q_-=Kra`A&KRB1jvazbngfBjgn&`bJzAm6xn_l`)i@ zC$=@Pd*bvFwpy;t+e;!<%5R0@d7Zet#GF;fo~7=Hlc=Ph&vp!o6n)1|pNN$sT1Z;X zQc>y){CpRFa{UDYhe6&L8n?TOhz~i=EC`q!6(=61|HK}hkLcE(*k?|CwVT-A;g?UT z=s;5;+S3p#&8wavOx4Tng??U|C4|AlUdY3kO=r?4C=n+@PC%$Ew@9;2KbGKGEf37Q z%H4V%PxSS3<@(|D-+bwO7sDM0El&*ZN?i{*W@p&OYmiyY#A|QIHR%OQaDc{f^!^*T zSmn@5sDrc5Gw248+-sVLn##n)){%^_fxOWRgBen?4BXHolf^npn?%alXh}-1f|&rf zFQS2?+5P}l&wYhEFeL~sduu^rs7p-SxbmUC2zp!ajlf8ihBY|A7ynBNa(LH8G(YB? z2wUnCqj}ltPGxu%sg-*%*n%1uYQn1%*iwB67_6`BE`*N7uw%!l&et=Hx>l&pM;#&y-Ve*8=RbEwEfn>P z0V~xEboE_zOkec&aqL!eh`%a!Efe4!4;}89QhiSI0$xkVv^Mf#OFg{R?6oh=3J>&a zc>^k~(<{H+OGu})zMM^OJydKA4h_Ux#)aCu+zh&{3j*X=18Hq%v85ryB++|dpulFg zE4w;hnQT52%z8It@nLc1ROuEt+wD0V1MVSIi#{Kz=(|JOS=aKqgV*(=+X{V~8oJw$ z--c(zfxWZ_#ffPahGJ;>Rr$8hfgVaX&hN2STiMyg?wovvkw%&!6fvCVvWhsK(=gl+ zC^y`Gh&_x}G|Y4-7CK_achoE#nuNJKSB-Y$aketH_^h1r-_?Yc-pi}`e`FB{slQ|X z73zy0a0$tyMlpT>t<8 literal 0 HcmV?d00001 diff --git a/testdata/repos/small/dotGit/packed-refs b/testdata/repos/small/dotGit/packed-refs new file mode 100644 index 000000000..859b8c5a8 --- /dev/null +++ b/testdata/repos/small/dotGit/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +1b6da43b82b22e4eaa10bcf8ee591e91abbfc587 refs/remotes/origin/main diff --git a/testdata/repos/small/dotGit/refs/heads/api-pkg b/testdata/repos/small/dotGit/refs/heads/api-pkg new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/api-pkg @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/heads/foo b/testdata/repos/small/dotGit/refs/heads/foo new file mode 100644 index 000000000..57d584841 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/foo @@ -0,0 +1 @@ +f1b58b97808f8e744f6a23c693859df5b5968901 diff --git a/testdata/repos/small/dotGit/refs/heads/main b/testdata/repos/small/dotGit/refs/heads/main new file mode 100644 index 000000000..98f12e928 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/main @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e diff --git a/testdata/repos/small/dotGit/refs/heads/remove-secrets b/testdata/repos/small/dotGit/refs/heads/remove-secrets new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/heads/remove-secrets @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/HEAD b/testdata/repos/small/dotGit/refs/remotes/origin/HEAD new file mode 100644 index 000000000..4b0a87595 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg b/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg new file mode 100644 index 000000000..31b6c7893 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/api-pkg @@ -0,0 +1 @@ +a122b33c6bad3ee54724f52f2caad385ab1982ab diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/foo b/testdata/repos/small/dotGit/refs/remotes/origin/foo new file mode 100644 index 000000000..57d584841 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/foo @@ -0,0 +1 @@ +f1b58b97808f8e744f6a23c693859df5b5968901 diff --git a/testdata/repos/small/dotGit/refs/remotes/origin/main b/testdata/repos/small/dotGit/refs/remotes/origin/main new file mode 100644 index 000000000..98f12e928 --- /dev/null +++ b/testdata/repos/small/dotGit/refs/remotes/origin/main @@ -0,0 +1 @@ +2e1db472eeba53f06c4026ae4566ea022e36598e diff --git a/testdata/repos/small/main.go b/testdata/repos/small/main.go new file mode 100644 index 000000000..9a932e37e --- /dev/null +++ b/testdata/repos/small/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + + var a = "initial" + fmt.Println(a) + + var b, c int = 1, 2 + fmt.Println(b, c) + + var d = true + fmt.Println(d) + + var e int + fmt.Println(e) + + // load secret via env + awsToken := os.Getenv("AWS_TOKEN") + + f := "apple" + fmt.Println(f) +} diff --git a/testdata/tmp/note.txt b/testdata/tmp/note.txt new file mode 100644 index 000000000..429d60380 --- /dev/null +++ b/testdata/tmp/note.txt @@ -0,0 +1 @@ +nothing should be saved here diff --git a/version/version.go b/version/version.go deleted file mode 100644 index ddc9ca1a2..000000000 --- a/version/version.go +++ /dev/null @@ -1,6 +0,0 @@ -package version - -// Version is loaded via LDFLAGS: -// VERSION := `git fetch --tags && git tag | sort -V | tail -1` -// LDFLAGS=-ldflags "-X=github.com/zricethezav/gitleaks-ng/version.Version=$(VERSION)" -var Version string