Gitleaks is a SAST tool for detecting hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an **easy-to-use, all-in-one solution** for finding secrets, past or present, in your code.
### Introduction Video
### Features:
- Scan for [commited](https://github.com/zricethezav/gitleaks#Scanning) secrets
- Scan for [unstaged](https://github.com/zricethezav/gitleaks#scan-unstaged-changes) secrets to shift security left
- Scan [directories and files](https://github.com/zricethezav/gitleaks#scan-local-directory)
- Run [Gitleaks Action](https://github.com/marketplace/actions/gitleaks) in your CI/CD pipeline
- [Custom rules](https://github.com/zricethezav/gitleaks#configuration) via toml configuration
- Increased performance using [go-git](https://github.com/go-git/go-git)
- JSON, SARIF, and CSV reporting
- Private repo scans using key or password based authentication
### Installation
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).
##### MacOS
```
brew install gitleaks
```
##### Docker
```bash
docker pull zricethezav/gitleaks
```
##### Go
```bash
GO111MODULE=on go get github.com/zricethezav/gitleaks/v7
```
### Usage and Options
```
Usage:
gitleaks [OPTIONS]
Application Options:
-v, --verbose Show verbose output from scan
-q, --quiet Sets log level to error and only output leaks, one json object per line
-r, --repo-url= Repository URL
-p, --path= Path to directory (repo if contains .git) or file
-c, --config-path= Path to config
--repo-config-path= Path to gitleaks config relative to repo root
--version Version number
--username= Username for git repo
--password= Password for git repo
--access-token= Access token for git repo
--threads= Maximum number of threads gitleaks spawns
--ssh-key= Path to ssh key used for auth
--unstaged Run gitleaks on unstaged code
--branch= Branch to scan
--redact Redact secrets from log messages and leaks
--debug Log debug messages
--leaks-exit-code= Exit code when leaks have been encountered (default: 1)
--no-git Treat git repos as plain directories and scan those
files
--append-repo-config Append the provided or default config with the repo config.
--additional-config= Path to an additional gitleaks config to append with an existing config. Can be used with --append-repo-config to append up to three configurations
-o, --report= Report output path
-f, --format= JSON, CSV, SARIF (default: json)
--files-at-commit= Sha of commit to scan all files at commit
--commit= Sha of commit to scan or "latest" to scan the last
commit of the repository
--commits= Comma separated list of a commits to scan
--commits-file= Path to file of line separated list of commits to scan
--commit-from= Commit to start scan from
--commit-to= Commit to stop scan
--commit-since= Scan commits more recent than a specific date. Ex:
'2006-01-02' or '2006-01-02T15:04:05-0700' format.
--commit-until= Scan commits older than a specific date. Ex:
'2006-01-02' or '2006-01-02T15:04:05-0700' format.
--depth= Number of commits to scan
Help Options:
-h, --help Show this help message
```
### [Scanning](https://www.youtube.com/watch?v=WUzpRL8mKCk)
#### Basic repo-url scan:
This scans the entire history of tests/secrets and logs leaks as they are encountered `-v`/`--verbose` being set.
```
gitleaks --repo-url=https://github.com/my-insecure/repo -v
```
#### Basic repo-url scan output to a report:
If you want the report in sarif or csv you can set the `-f/--format` option
```
gitleaks --repo-url=https://github.com/my-insecure/repo -v --report=my-report.json
```
#### Scan specific commit:
```
gitleaks --repo-url=https://github.com/my-insecure/repo --commit=commit-sha -v
```
#### Scan local repo:
```
gitleaks --path=path/to/local/repo -v
```
#### Scan repos contained in a parent directory:
If you have `repo1`, `repo2`, `repo3` all under `path/to/local`, gitleaks will discover and scan those repos.
```
gitleaks --path=path/to/local/ -v
```
#### Scan local directory:
If you want to scan the current contents of a repo, ignoring git alltogether. You can use the `--no-git` option to do this.
```
gitleaks --path=path/to/local/repo -v --no-git
```
#### Scan a file:
Or if you want to scan a single file using gitleaks rules. You can do this by specifying the file in `--path` and including the `--no-git` option.
```
gitleaks --path=path/to/local/repo/main.go -v --no-git
```
#### Scan unstaged changes:
If you have unstaged changes are are currently at the root of the repo, you can run `gitleaks` with no `--path` or `--repo-url` specified which will run a scan on your uncommitted changes. Or if you want to specify a
path, you can run:
```
gitleaks --path=path/to/local/repo -v --unstaged
```
### Configuration
Provide your own gitleaks configurations with `--config-path` or `--repo-config-path`. `--config-path` loads a local gitleaks configuration whereas `--repo-config-path` will load a configuration present just in the repo you want to scan. For example, `gitleaks --repo-config-path=".github/gitleaks.config"`.
The default configuration Gitleaks uses is located [here](https://github.com/zricethezav/gitleaks/blob/master/config/default.go). More configuration examples can be seen [here](https://github.com/zricethezav/gitleaks/tree/master/examples). Configuration files will contain a few different toml tables. Further explanation is provided below.
### Rules summary
The rules are written in [TOML](https://github.com/toml-lang/toml) as defined in [TomlLoader struct](https://github.com/zricethezav/gitleaks/blob/master/config/config.go#L57-L87), and can be summarized as:
```
[[rules]]
description = "a string describing one of many rule in this config"
regex = '''one-go-style-regex-for-this-rule'''
file = '''a-file-name-regex'''
path = '''a-file-path-regex'''
tags = ["tag","another tag"]
[[rules.entropies]] # note these are strings, not floats
Min = "3.5"
Max = "4.5"
Group = "1"
[rules.allowlist]
description = "a string"
files = ['''one-file-name-regex''']
commits = [ "commit-A", "commit-B"]
paths = ['''one-file-path-regex''']
regexes = ['''one-regex-within-the-already-matched-regex''']
[allowlist]
description = "a description string for a global allowlist config"
commits = [ "commit-A", "commit-B"]
files = [ '''file-regex-a''', '''file-regex-b''']
paths = [ '''path-regex-a''', '''path-regex-b''']
repos = [ '''repo-regex-a''', '''repo-regex-b''']
regexes = ['''one-regex-within-the-already-matched-regex''']
```
Regular expressions are _NOT_ the full Perl set, so there are no look-aheads or look-behinds.
### Examples
#### Example 1
The first and most commonly edited array of tables is `[[rules]]`. This is where you can define your own custom rules for Gitleaks to use while scanning repos. Example keys/values within the `[[rules]]` table:
```
[[rules]]
description = "generic secret regex"
regex = '''secret(.{0,20})([0-9a-zA-Z-._{}$\/\+=]{20,120})'''
tags = ["secret", "example"]
```
#### Example 2
We can also **combine** regular expressions AND entropy:
```
[[rules]]
description = "entropy and regex example"
regex = '''secret(.{0,20})['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]'''
[[rules.Entropies]]
Min = "4.5"
Max = "4.7"
```
Translating this rule to English, this rule states: "if we encounter a line of code that matches *regex* AND the line falls within the bounds of a [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory)) of 4.5 to 4.7, then the line must be a leak"
#### Example 3
Let's compare two lines of code:
```
aws_secret='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE'
```
and
```
aws_secret=os.getenv('AWS_SECRET_ACCESS_KEY')
```
The first line of code is an example of a hardcoded secret being assigned to the variable `aws_secret`. The second line of code is an example of a secret being assigned via env variables to `aws_secret`. Both would be caught by the rule defined in *example 2* but only the first line is actually a leak. Let's define a new rule that will capture only the first line of code. We can do this by combining regular expression **groups** and entropy.
```
[[rules]]
description = "entropy and regex example"
regex = '''secret(.{0,20})['|"]([0-9a-zA-Z-._{}$\/\+=]{20,120})['|"]'''
[[rules.Entropies]]
Min = "4.5"
Max = "4.7"
Group = "2"
```
Notice how we added `Group = "2"` to this rule. We can translate this rule to English: "if we encounter a line of code that matches regex AND the entropy of the *second regex group* falls within the bounds of a [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory)) of 4.5 to 4.7, then the line must be a leak"
### Example 4: Using allowlist regex
The proper Perl regex for AWS secret keys is
`(?Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License.