Giter VIP home page Giter VIP logo

git-secrets's Introduction

git-secrets

Prevents you from committing passwords and other sensitive information to a git repository.

depth

2

Synopsis

git secrets --scan [-r|--recursive] [--cached] [--no-index] [--untracked] [<files>...]
git secrets --scan-history
git secrets --install [-f|--force] [<target-directory>]
git secrets --list [--global]
git secrets --add [-a|--allowed] [-l|--literal] [--global] <pattern>
git secrets --add-provider [--global] <command> [arguments...]
git secrets --register-aws [--global]
git secrets --aws-provider [<credentials-file>]

Description

git-secrets scans commits, commit messages, and --no-ff merges to prevent adding secrets into your git repositories. If a commit, commit message, or any commit in a --no-ff merge history matches one of your configured prohibited regular expression patterns, then the commit is rejected.

Installing git-secrets

git-secrets must be placed somewhere in your PATH so that it is picked up by git when running git secrets.

*nix (Linux/macOS)

You can use the install target of the provided Makefile to install git secrets and the man page. You can customize the install path using the PREFIX and MANPREFIX variables.

make install

Windows

Run the provided install.ps1 powershell script. This will copy the needed files to an installation directory (%USERPROFILE%/.git-secrets by default) and add the directory to the current user PATH.

PS > ./install.ps1

Homebrew (for macOS users)

brew install git-secrets

Warning

You're not done yet! You MUST install the git hooks for every repo that you wish to use with git secrets --install.

Here's a quick example of how to ensure a git repository is scanned for secrets on each commit:

cd /path/to/my/repo
git secrets --install
git secrets --register-aws

Advanced configuration

Add a configuration template if you want to add hooks to all repositories you initialize or clone in the future.

git secrets --register-aws --global

Add hooks to all your local repositories.

git secrets --install ~/.git-templates/git-secrets
git config --global init.templateDir ~/.git-templates/git-secrets

Add custom providers to scan for security credentials.

git secrets --add-provider -- cat /path/to/secret/file/patterns

Before making public a repository

With git-secrets is also possible to scan a repository including all revisions:

git secrets --scan-history

Options

Operation Modes

Each of these options must appear first on the command line.

--install

Installs git hooks for a repository. Once the hooks are installed for a git repository, commits and non-fast-forward merges for that repository will be prevented from committing secrets.

--scan

Scans one or more files for secrets. When a file contains a secret, the matched text from the file being scanned will be written to stdout and the script will exit with a non-zero status. Each matched line will be written with the name of the file that matched, a colon, the line number that matched, a colon, and then the line of text that matched. If no files are provided, all files returned by git ls-files are scanned.

--scan-history

Scans repository including all revisions. When a file contains a secret, the matched text from the file being scanned will be written to stdout and the script will exit with a non-zero status. Each matched line will be written with the name of the file that matched, a colon, the line number that matched, a colon, and then the line of text that matched.

--list

Lists the git-secrets configuration for the current repo or in the global git config.

--add

Adds a prohibited or allowed pattern.

--add-provider

Registers a secret provider. Secret providers are executables that when invoked output prohibited patterns that git-secrets should treat as prohibited.

--register-aws

Adds common AWS patterns to the git config and ensures that keys present in ~/.aws/credentials are not found in any commit. The following checks are added:

  • AWS Access Key IDs via (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
  • AWS Secret Access Key assignments via ":" or "=" surrounded by optional quotes
  • AWS account ID assignments via ":" or "=" surrounded by optional quotes
  • Allowed patterns for example AWS keys (AKIAIOSFODNN7EXAMPLE and wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)
  • Known credentials from ~/.aws/credentials

Note

While the patterns registered by this command should catch most instances of AWS credentials, these patterns are not guaranteed to catch them all. git-secrets should be used as an extra means of insurance -- you still need to do your due diligence to ensure that you do not commit credentials to a repository.

--aws-provider

Secret provider that outputs credentials found in an INI file. You can optionally provide the path to an INI file.

Options for --install

-f, --force

Overwrites existing hooks if present.

<target-directory>

When provided, installs git hooks to the given directory. The current directory is assumed if <target-directory> is not provided.

If the provided <target-directory> is not in a git repository, the directory will be created and hooks will be placed in <target-directory>/hooks. This can be useful for creating git template directories using with git init --template <target-directory>.

You can run git init on a repository that has already been initialized. From the git init documentation:

From the git documentation: Running git init in an existing repository is safe. It will not overwrite things that are already there. The primary reason for rerunning git init is to pick up newly added templates (or to move the repository to another place if --separate-git-dir is given).

The following git hooks are installed:

  1. pre-commit: Used to check if any of the files changed in the commit use prohibited patterns.
  2. commit-msg: Used to determine if a commit message contains a prohibited patterns.
  3. prepare-commit-msg: Used to determine if a merge commit will introduce a history that contains a prohibited pattern at any point. Please note that this hook is only invoked for non fast-forward merges.

Note

Git only allows a single script to be executed per hook. If the repository contains Debian-style subdirectories like pre-commit.d and commit-msg.d, then the git hooks will be installed into these directories, which assumes that you've configured the corresponding hooks to execute all of the scripts found in these directories. If these git subdirectories are not present, then the git hooks will be installed to the git repo's .git/hooks directory.

Examples

Install git hooks to the current directory:

cd /path/to/my/repository
git secrets --install

Install git hooks to a repository other than the current directory:

git secrets --install /path/to/my/repository

Create a git template that has git-secrets installed, and then copy that template into a git repository:

git secrets --install ~/.git-templates/git-secrets
git init --template ~/.git-templates/git-secrets

Overwrite existing hooks if present:

git secrets --install -f

Options for --scan

-r, --recursive

Scans the given files recursively. If a directory is encountered, the directory will be scanned. If -r is not provided, directories will be ignored.

-r cannot be used alongside --cached, --no-index, or --untracked.

--cached

Searches blobs registered in the index file.

--no-index

Searches files in the current directory that is not managed by git.

--untracked

In addition to searching in the tracked files in the working tree, --scan also in untracked files.

<files>...

The path to one or more files on disk to scan for secrets.

If no files are provided, all files returned by git ls-files are scanned.

Examples

Scan all files in the repo:

git secrets --scan

Scans a single file for secrets:

git secrets --scan /path/to/file

Scans a directory recursively for secrets:

git secrets --scan -r /path/to/directory

Scans multiple files for secrets:

git secrets --scan /path/to/file /path/to/other/file

You can scan by globbing:

git secrets --scan /path/to/directory/*

Scan from stdin:

echo 'hello!' | git secrets --scan -

Options for --list

--global

Lists only git-secrets configuration in the global git config.

Options for --add

--global

Adds patterns to the global git config

-l, --literal

Escapes special regular expression characters in the provided pattern so that the pattern is searched for literally.

-a, --allowed

Mark the pattern as allowed instead of prohibited. Allowed patterns are used to filter out false positives.

<pattern>

The regex pattern to search.

Examples

Adds a prohibited pattern to the current repo:

git secrets --add '[A-Z0-9]{20}'

Adds a prohibited pattern to the global git config:

git secrets --add --global '[A-Z0-9]{20}'

Adds a string that is scanned for literally (+ is escaped):

git secrets --add --literal 'foo+bar'

Add an allowed pattern:

git secrets --add -a 'allowed pattern'

Options for --register-aws

--global

Adds AWS specific configuration variables to the global git config.

Options for --aws-provider

[<credentials-file>]

If provided, specifies the custom path to an INI file to scan. If not provided, ~/.aws/credentials is assumed.

Options for --add-provider

--global

Adds the provider to the global git config.

<command>

Provider command to invoke. When invoked the command is expected to write prohibited patterns separated by new lines to stdout. Any extra arguments provided are passed on to the command.

Examples

Registers a secret provider with arguments:

git secrets --add-provider -- git secrets --aws-provider

Cats secrets out of a file:

git secrets --add-provider -- cat /path/to/secret/file/patterns

Defining prohibited patterns

egrep-compatible regular expressions are used to determine if a commit or commit message contains any prohibited patterns. These regular expressions are defined using the git config command. It is important to note that different systems use different versions of egrep. For example, when running on macOS, you will use a different version of egrep than when running on something like Ubuntu (BSD vs GNU).

You can add prohibited regular expression patterns to your git config using git secrets --add <pattern>.

Ignoring false positives

Sometimes a regular expression might match false positives. For example, git commit SHAs look a lot like AWS access keys. You can specify many different regular expression patterns as false positives using the following command:

git secrets --add --allowed 'my regex pattern'

You can also add regular expressions patterns to filter false positives to a .gitallowed file located in the repository's root directory. Lines starting with # are skipped (comment line) and empty lines are also skipped.

First, git-secrets will extract all lines from a file that contain a prohibited match. Included in the matched results will be the full path to the name of the file that was matched, followed by ':', followed by the line number that was matched, followed by the entire line from the file that was matched by a secret pattern. Then, if you've defined allowed regular expressions, git-secrets will check to see if all of the matched lines match at least one of your registered allowed regular expressions. If all of the lines that were flagged as secret are canceled out by an allowed match, then the subject text does not contain any secrets. If any of the matched lines are not matched by an allowed regular expression, then git-secrets will fail the commit/merge/message.

Important

Just as it is a bad practice to add prohibited patterns that are too greedy, it is also a bad practice to add allowed patterns that are too forgiving. Be sure to test out your patterns using ad-hoc calls to git secrets --scan $filename to ensure they are working as intended.

Secret providers

Sometimes you want to check for an exact pattern match against a set of known secrets. For example, you might want to ensure that no credentials present in ~/.aws/credentials ever show up in a commit. In these cases, it's better to leave these secrets in one location rather than spread them out across git repositories in git configs. You can use "secret providers" to fetch these types of credentials. A secret provider is an executable that when invoked outputs prohibited patterns separated by new lines.

You can add secret providers using the --add-provider command:

git secrets --add-provider -- git secrets --aws-provider

Notice the use of --. This ensures that any arguments associated with the provider are passed to the provider each time it is invoked when scanning for secrets.

Example walkthrough

Let's take a look at an example. Given the following subject text (stored in /tmp/example):

This is a test!
password=ex@mplepassword
password=******
More test...

And the following registered patterns:

git secrets --add 'password\s*=\s*.+'
git secrets --add --allowed --literal 'ex@mplepassword'

Running git secrets --scan /tmp/example, the result will result in the following error output:

/tmp/example:3:password=******

[ERROR] Matched prohibited pattern

Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- Use --no-verify if this is a one-time false positive

Breaking this down, the prohibited pattern value of password\s*=\s*.+ will match the following lines:

/tmp/example:2:password=ex@mplepassword
/tmp/example:3:password=******

...But the first match will be filtered out due to the fact that it matches the allowed regular expression of ex@mplepassword. Because there is still a remaining line that did not match, it is considered a secret.

Because that matching lines are placed on lines that start with the filename and line number (e.g., /tmp/example:3:...), you can create allowed patterns that take filenames and line numbers into account in the regular expression. For example, you could whitelist an entire file using something like:

git secrets --add --allowed '/tmp/example:.*'
git secrets --scan /tmp/example && echo $?
# Outputs: 0

Alternatively, you could allow a specific line number of a file if that line is unlikely to change using something like the following:

git secrets --add --allowed '/tmp/example:3:.*'
git secrets --scan /tmp/example && echo $?
# Outputs: 0

Keep this in mind when creating allowed patterns to ensure that your allowed patterns are not inadvertently matched due to the fact that the filename is included in the subject text that allowed patterns are matched against.

Skipping validation

Use the --no-verify option in the event of a false positive match in a commit, merge, or commit message. This will skip the execution of the git hook and allow you to make the commit or merge.

About

Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

git-secrets's People

Contributors

andreaswittig avatar aramprice avatar awstools avatar chrisgilmerproj avatar costleya avatar creswick avatar daneah avatar dannysauer avatar dariuswiles avatar dbraley avatar enabokov avatar fmarier avatar hyandell avatar initbar avatar jdyke avatar jsoref avatar kramos avatar lsegal avatar manabusakai avatar mbacchi avatar michaelwittig avatar mtdowling avatar patmyron avatar sparr avatar t13a avatar yoshutch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

git-secrets's Issues

Crash on too many changed files

Git-secrets failed a merge from upstream master, because it found some secrets in the upstream commits. Then it didn't allow me continuing the merge because 22680 modified files seems to be too many:

$ git merge --continue
/usr/local/bin/git-secrets: line 109: /usr/local/Cellar/git/2.17.0/libexec/git-core/git: Argument list too long

This fixed it for me:

$ git commit --no-verify

Windows: git: 'secrets' is not a git command

I have tried (and tried, and tried) getting git-secrets to work with GitHub Desktop for Windows without luck.

I have put the git-secrets bash script in one location that is now available within the git shell launched from GitHub Desktop (it's also in %PATH%):

curl -o "C:\Program Files\Git\cmd\git-secrets" https://raw.githubusercontent.com/awslabs/git-secrets/master/git-secrets

Running git secrets in cmd, git-bash AND powershell manually all gives me the "usage" output.

However, trying to commit with GitHub Desktop gives me

2017-12-13 16:30:05.7169|INFO|thread: 4|ProcessWrapper|Starting: Process - FileName: 'C:\Users\Stian\AppData\Local\GitHub\PortableGit_f02737a78695063deace08e96d5042710d3e32db\cmd\git.exe
...
2017-12-13 16:30:06.1735|WARN|thread: 1|StandardUserErrors|Showing user error Failed to create a new commit.
GitHub.IO.ProcessException: git: 'secrets' is not a git command. See 'git --help'.

I get the option to view error log and also "Open Git Shell". When I do Open Git Shell and execute git secrets, that works and gives me the "usage" output again.

Manually running the git.exe file in question with "secrets" also works:

C:\Users\Stian>C:\Users\Stian\AppData\Local\GitHub\PortableGit_f02737a78695063deace08e96d5042710d3e32db\cmd\git.exe secrets
usage: git secrets --scan [-r|--recursive] [--cached] [--no-index] [--untracked] [<files>...]

Have tried setting Default shell in GitHub Desktop to Cmd, Git Bash and Powershell. They all fail.

New release?

There hasn't been a release for over 2 years. The current released version does not work on my Windows machine due to #40 (which actually fixes an issue that is not OS-specific, but tends to affect Windows users more often) not being in the release. It would be nice to have a new release to make it easier for Windows users.

How to edit an already added patterns?

I already added a regex pattern to match for potential keys, but I realised that the pattern is wrong. How can I edit the pattern? Is there a text file I can access to edit it directly? Or?

Thanks!

Appending to allowed literal will pass the check

I ran the following to add somethingsecret as an allowed password in literal form:

git secrets --add 'password\s*=\s*.+'
git secrets --add --allowed --literal 'somethingsecret'

But I found that password=somethingsecret1, will also pass the check.

Git Commit Message is always prohibited

Running this tool and no matter the git commit message entered it is prevented from committing.
Rem'ing out the git hook for the commit-msg allows it to pass - post this action it picks up any AWS Keys which is the primary objective.
Is this the correct behaviour?

Not scanned except the first file

  • Arch Linux
  • bash 4.4.012
  • git 2.16.1
  • git-secrets at master

Here is how to reproduce.

$ echo harmless > some.crt
$ echo forbidden > some.key # should be matched
$ git add -A
$ git secrets --scan some.crt some.key
(cause no errors)

pre-commit hook has same problem, since the internal behavior is almost the same as this.

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   some.crt
    new file:   some.key

$ git commit -m 'commit'
 2 files changed, 2 insertions(+)
 create mode 100644 some.crt
 create mode 100644 some.key
(secret was committed)

I have fixed this problem so I will send a pull request soon.

P.S.
I have also passed test/pre-commit-hook.bats and found a small error. After this fix, all tests are passed successfully. But why did this fail while others are succeeded?

How do you add a pattern that begins with '-'?

So, I'm trying to add a pattern that looks like this:

-----BEGIN RSA PRIVATE KEY-----

However, I keep getting the following error, regardless of the options I provide:

$ git secrets --add --literal --global '-----BEGIN RSA PRIVATE KEY-----'
error: unknown option `---BEGIN RSA PRIVATE KEY-----'
usage: git secrets --scan [-r|--recursive] [--cached] [--no-index] [--untracked] [<files>...]
   or: git secrets --scan-history
   or: git secrets --install [-f|--force] [<target-directory>]
   or: git secrets --list [--global]
   or: git secrets --add [-a|--allowed] [-l|--literal] [--global] <pattern>
   or: git secrets --add-provider [--global] <command> [arguments...]
   or: git secrets --register-aws [--global]
   or: git secrets --aws-provider [<credentials-file>]

    --scan                Scans <files> for prohibited patterns
    --scan-history        Scans repo for prohibited patterns
    --install             Installs git hooks for Git repository or Git template directory
    --list                Lists secret patterns
    --add                 Adds a prohibited or allowed pattern, ensuring to de-dupe with existing patterns
    --add-provider        Adds a secret provider that when called outputs secret patterns on new lines
    --aws-provider        Secret provider that outputs credentials found in an ini file
    --register-aws        Adds common AWS patterns to the git config and scans for ~/.aws/credentials
    -r, --recursive       --scan scans directories recursively
    --cached              --scan scans searches blobs registered in the index file
    --no-index            --scan searches files in the current directory that is not managed by Git
    --untracked           In addition to searching in the tracked files in the working tree, --scan also in untracked files
    -f, --force           --install overwrites hooks if the hook already exists
    -l, --literal         --add and --add-allowed patterns are escaped so that they are literal
    -a, --allowed         --add adds an allowed pattern instead of a prohibited pattern
    --global              Uses the --global git config

"Argument list too long" error on some repos

I'm getting the following error when scanning some repos:

/usr/local/bin/git-secrets: line 56: /usr/bin/grep: Argument list too long

I'm guessing that the repos in question are too large. The two that fail have a size-pack of 205,724 and 106,999 (generated with this command: git count-objects -v)

git secrets --clone

Hi Git Secrets folk.

It would be nice if I could do:

  git secrets --clone <clone url> <clone-args>

and that would clone, then install the hook, then add some configurable default list of rules.

macOS's grep is not compatible gnu grep

macOS's grep (BSD grep 2.5.1-FreeBSD) is not compatible gnu grep.
So, commit-msg hook is always ERROR.

git secrets --commit_msg_hook -- foo.txt
test1.txt:1:test1

[ERROR] Matched one or more prohibited patterns

Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive

Fails on bash 4 during pre-commit hook

Hello,

we noticed a problem on bash 4 when multiple files have been changed by a commit.
When getting called in a pre-commit hook we get this error:

fatal: ambiguous argument 'slides/Container_Network_Model/Body.md slides/Container_Network_Model/Cover.md': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'

On bash 3 it works.

It seems like in bash 4 the files argument is passed to the git_grep function with quotes
git grep -nwHEI --cached '...mypattern...' 'slides/Container_Network_Model/Body.md slides/Container_Network_Model/Cover.md'

in bash 3 the quotes are not there
git grep -nwHEI --cached '...mypattern...' slides/Container_Network_Model/Body.md slides/Container_Network_Model/Cover.md

fail with SourceTree, Tower client

This script is fail when using with SourceTree, Tower and other git UI Client,
Please add "export PATH=$PATH:/usr/local/bin:/usr/local/sbin" into top of "pre-" files when run install git secret

Carriage return breaks the load_patterns function in Windows 10 Bash

I ran into an issue when trying to run git-secrets on a repo in the Windows 10 Bash (not git bash, but the dev linux bash console for Windows). When I run git secrets --scan it fails and doesn't even give an error. After some digging I found that in the load_patterns() function the resulting list of patterns has carriage returns instead of spaces. Just carriage returns. The carriage returns then break the git grep command without returning even an error. So then the pre-commit hook thinks it succeeded when in fact it never attempted the process.

I was able to get it to work by changing line 55 in git-secrets:
echo "$result"
to:
echo "$result" | tr -d "\r"

This seemed to work on both the Windows 10 Bash, as well as Git Bash (and even windows Command Line).

Now, I'm not sure if this is more of an issue with Windows 10 Bash (probably is), but since it was a fairly simple code fix, I thought it'd be good to document this just in case anyone else might be testing the Windows 10 Bash.

Tests failing on bash 4.4

I just downloaded git-secrets via git (commit b296988), ran make test and 3 tests fail:

  • Rejects commits with prohibited patterns in changeset
  • Scans staged files
  • Rejects commits with prohibited patterns in changeset when AWS provider is enabled

Details:

$ bash --version | head -1
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)

$ grep --version | head -1
grep (GNU grep) 3.1

$ make test 
test/bats/bin/bats test/
 ✓ Rejects commit messages with prohibited patterns
 ✓ Allows commit messages that do not match a prohibited pattern
 ✓ no arguments prints usage instructions
 ✓ -h prints help
 ✓ Invalid scan filename fails
 ✓ Does not require secrets
 ✓ No prohibited matches exits 0
 ✓ Scans all files when no file provided
 ✓ Scans all files including history
 ✓ Scans all files when no file provided with secret in history
 ✓ Scans all files including history with secret in history
 ✓ Scans history with secrets distributed among branches in history
 ✓ Scans recursively
 ✓ Scans recursively only if -r is given
 ✓ Excludes allowed patterns from failures
 ✓ Prohibited matches exits 1
 ✓ Only matches on word boundaries
 ✓ Can scan from stdin using -
 ✓ installs hooks for repo
 ✓ fails if hook exists and no -f
 ✓ Overwrites hooks if -f is given
 ✓ installs hooks for repo with Debian style directories
 ✓ installs hooks to template directory
 ✓ Scans using keys from credentials file
 ✓ Lists secrets for a repo
 ✓ Adds secrets to a repo and de-dedupes
 ✓ Adds allowed patterns to a repo and de-dedupes
 ✓ Empty lines must be ignored in .gitallowed files
 ✓ Comment lines must be ignored in .gitallowed files
 ✓ Scans all files and allowing none of the bad patterns in .gitallowed
 ✓ Scans all files and allowing all bad patterns in .gitallowed
 ✓ Adds common AWS patterns
 ✓ Adds providers
 ✓ Strips providers that return nothing
 ✓ --recursive cannot be used with SCAN_*
 ✓ --recursive can be used with --scan
 ✓ --recursive can't be used with --list
 ✓ -f can only be used with --install
 ✓ -a can only be used with --add
 ✓ -l can only be used with --add
 ✓ --cached can only be used with --scan
 ✓ --no-index can only be used with --scan
 ✓ --untracked can only be used with --scan
 ✗ Rejects commits with prohibited patterns in changeset
   (in test file test/pre-commit.bats, line 9)
     `[ $status -eq 1 ]' failed
   Initialized empty Git repository in /tmp/test-repo/.git/
   /home/dserodio/code/git-secrets
   /tmp/test-repo
   /tmp/test-repo
 ✓ Rejects commits with prohibited patterns in changeset with filename that contain spaces
 ✗ Scans staged files
   (in test file test/pre-commit.bats, line 32)
     `[ $status -eq 1 ]' failed
   Initialized empty Git repository in /tmp/test-repo/.git/
   /home/dserodio/code/git-secrets
   /tmp/test-repo
 ✓ Allows commits that do not match prohibited patterns
 ✗ Rejects commits with prohibited patterns in changeset when AWS provider is enabled
   (in test file test/pre-commit.bats, line 56)
     `[ $status -eq 1 ]' failed
   Initialized empty Git repository in /tmp/test-repo/.git/
   /home/dserodio/code/git-secrets
   /tmp/test-repo
   /tmp/test-repo
   /tmp/test-repo
 ✓ Rejects merges with prohibited patterns in history
 ✓ Allows merges that do not match prohibited patterns

50 tests, 3 failures
Makefile:12: recipe for target 'test' failed
make: *** [test] Error 1

redirect error output to stderr

Stderr should be separated from stdout on error.

I'm opening a PR to make it do this properly:

`[mbacchi@hostname git-secrets]$ ./git-secrets --scan -r . 2>err 1>out
[mbacchi@hostname git-secrets]$ cat out
[mbacchi@hostname git-secrets]$ cat err
./creds:1:AKIAISITMFSJISKWFAJQ

[ERROR] Matched one or more prohibited patterns

Possible mitigations:

  • Mark false positives as allowed using: git config --add secrets.allowed ...
  • Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
  • List your configured patterns: git config --get-all secrets.patterns
  • List your configured allowed patterns: git config --get-all secrets.allowed
  • List your configured allowed patterns in .gitallowed at repository's root directory
  • Use --no-verify if this is a one-time false positive`

Allowed pattern matches override all other prohibited pattern matches

When a single line matches both a prohibited pattern and an allowed pattern, then the entire line is allowed, regardless of whether they match the same string. As a simple test you can repro this with the following:

echo 'THIS_IS_SECRET but THIS_IS_NOT' > ./test-file
git secrets --add --literal THIS_IS_SECRET
git secrets --add --allowed THIS_IS_NOT
git secrets --scan ./test-file

My expectation is that since the prohibited and allowed matches are not for the same string, that the file is still flagged as containing a secret, but instead the entire line is ignored even though the allowed match is not the same as the prohibited match. This makes creating allowed patterns very difficult since you must test extensively to ensure the allowed pattern does not create false negatives, hiding legitimate secrets that you want to prevent from being checked in.

Global hooks

Any way to set this at a Global Level with Github Enterprise? Or does it have to be installed locally?

[macOS] Unable to commit more than one file at a time

Splitting this out from #32 for easier discovery and to perhaps highlight the need for a fix or workaround.


I am also seeing this problem.

Note that I can commit one file at a time. But if I try to commit several files, I get an error message like

fatal: ambiguous argument 'file1 file2': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git [...] -- [...]'

My versions:

  • macOS 10.13.3 (17D47)
  • git-secrets 1.2.1
  • grep (BSD grep) 2.5.1-FreeBSD
  • git version 2.16.1
  • hub version 2.2.9

would be nice to support dotnev

Would be nice to tell secrets to look for anything in a .env file in the root of a project. Or any file that is gitignored. Or best yet, any file with VAR=value\nVAR2=value2 format

pre-commit hook scans working directory instead of staging area?

The pre_commit_hook() searches for staged files.

pre_commit_hook() {
  local file found_match=0 rev="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
  # Diff against HEAD if this is not the first commit in the repo.
  git rev-parse --verify HEAD >/dev/null 2>&1 && rev="HEAD"
  # Filter out deleted files using --diff-filter
  scan_or_die "$(git diff-index --diff-filter 'ACMU' --name-only --cached $rev --)"
}

But scan() is operating on the working directory.

scan() {
  local files="$1" action='skip' patterns=$(load_patterns)
  local allowed=$(git config --get-all secrets.allowed)
  [ -z "${patterns}" ] && return 0
  if [ -z "${files}" ]; then
    output=$(GREP_OPTIONS= LC_ALL=C git grep -nwHE "${patterns}")
  else
    # -r only applies when file paths are provided.
    [ "${RECURSIVE}" -eq 1 ] && action="recurse"
    output=$(GREP_OPTIONS= LC_ALL=C grep -d $action -nwHE "${patterns}" $files)
  fi
  local status=$?
  case "$status" in
    0)
      [ -z "${allowed}" ] && echo "${output}" && return 1
      # Determine with a negative grep if the found matches are allowed
      echo "${output}" | GREP_OPTIONS= LC_ALL=C grep -Ev "${allowed}" \
        && return 1 || return 0
      ;;
    1) return 0 ;;
    *) exit $status
  esac
}

That means the pre-commit hook might not scan through the changes that will be committed.

Do I miss something? Do you agree, this is a problem? If so I would like to send you PR fixing that problem.

Recursive scan is broken

@mtdowling @michaelwittig

See commit 513af41#diff-9bcd3f161947f1bdee06e4b12046cb65

I believe that the recursive function is now broken with the latest commit.

There is a test that shows it should work called Scan recursively:

@test "Scans recursively" {
setup_bad_repo
mkdir -p $TEST_REPO/foo/bar/baz
echo '@todo more stuff' > $TEST_REPO/foo/bar/baz/data.txt
repo_run git-secrets --scan -r $TEST_REPO/foo
[ $status -eq 1 ]
}

And a test named -recursive can only be used with --scan:

@test "-recursive can only be used with --scan" {
repo_run git-secrets --list -r
[ $status -eq 1 ]
}

I think this is broken and should replace --list with --scan as I've done here:

@test "-recursive can only be used with --scan" {
  repo_run git-secrets --scan -r
  [ $status -eq 1 ]
}

But a new test was added to ensure this fails named -recursive is mutual exclusive with --scan:

@test "-recursive is mutual exclusive with --scan" {
repo_run git-secrets --scan -r
[ $status -eq 0 ]
}

Can you clarify that this was intended or fix the broken behavior? Thank you very much.

get secret --add existing regex pattern returns exit code 1

We have scripts to set up our machines. But whenever we run it a second time with git secrets, it will fail on adding the same pattern matcher.

Apparently running git secret --add --global "<existing pattern>" to a pattern already configured will return an exit code 1 thus causing our script to fail.

brew installation

Hi Michael, first THANKS for providing this tool - i have installed it and it is working great. i am sure this will be an invaluable help to a lot of people.

I did want to mention that this tool was not found amongst the Brew packages, and is unable to be installed via Brew as directed. it did install perfectly fine, however, through the make install process.

i apologize if this is an inappropriate means to get this information to you - i was unaware of another way to contact you. please feel free to close this out at your convenience.

thank you again!
bill

Email address pattern

Hi there,

I'm trying to get it to match email addresses (RFC 5322), which I don't want to commit.

(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\[\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))

The above works great when tested in JavaScript. But git secrets --scan fails with the following output:

fatal: command line, '(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()[]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))': Invalid range end

Addition of `IFS=$'\n'` caused ugly warnings if `--register-aws` set

Commit 9fa6d45 added IFS=$'\n' here which causes problems in the load_patterns function on line 52. With IFS=$'\n' and --register-aws set we see the following error when committing:

/usr/local/bin/git-secrets: line 52: git secrets --aws-provider: command not found

We suspect (but did not verify) that this breaks the scanning of credentials found in ~/.aws/credentials.

Adding the following test-case to test/pre-commit.bats demonstrates the error:

@test "Rejects commits with prohibited patterns in changeset when AWS provider is enabled" {
  setup_bad_repo
  repo_run git-secrets --install $TEST_REPO
  repo_run git-secrets --register-aws $TEST_REPO
  cd $TEST_REPO
  run git commit -m 'Contents are bad not the message'
  [ $status -eq 1 ]
  echo "${lines}" | grep -vq 'git secrets --aws-provider: command not found'

  [ "${lines[0]}" == "data.txt:1:@todo more stuff" ]
  [ "${lines[1]}" == "failure1.txt:1:another line... forbidden" ]
  [ "${lines[2]}" == "failure2.txt:1:me" ]
}

Setting IFS=$'\n ' resolves this issue above but breaks the Rejects commits with prohibited patterns in changeset with filename that contain spaces test case.

-- Chris (@xoebus) and Aram (@aramprice)

Scan History does nothing in CentOS/RHEL

Hi all,
I'm using latest release in a Mac and scan-history works well (both in bash and zsh), but if I run the same in other environments (a RHEL 7.5 vm, but even in some Docker containers like CentOS) the exit code is 0 but the command terminates immediately without doing anythins ... very strange.
I get 'git-secrets' from a git clone so this happens on latest code ... but same issue if I do a ceckout back to latest release (1.2.1).
There is something that I can do to enable DEBUG and understand what's happening (to help fix) ?

Note: in an Alpine (latest release) Docker container when run I had an error on a wrong -w flag used in grep, but only there.

I'm testing it with a sample test repository with committed some passwords, AWS_ACCESS_KEY, etc added and deleted, in different branches.

Thanks a lot for the help.
Regards, Sandro

Providers with no output cause everything to fail to verify

If you have a provider that only produces "\n" and another provider that produces patterns, a blank line will be added to the list of patterns causing every line to be matched and every file to fail to verify. This causes issues particularly when git secrets --aws-provider produces no output.

Example config

[secrets]
    providers = echo
    providers = echo bad

Pattern Causes Invalid preceding regular Expression Error

I'm trying to add a pattern for Basic Auth headers but they result in Invalid preceding regular expression errors
Regex
(Basic\ )(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)

Adding it to .git/config and trying to scan

mark@mark-VirtualBox:~/git/gitsecrets-test$ git secrets --add '(Basic\ )(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)'
mark@mark-VirtualBox:~/git/gitsecrets-test$ cat .git/config | grep patterns
	patterns = (Basic\\ )(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)
mark@mark-VirtualBox:~/git/gitsecrets-test$ git secrets --scan
fatal: command line, '[A-Z0-9]{20}|("|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)("|')?\s*(:|=>|=)\s*("|')?[A-Za-z0-9/\+=]{40}("|')?|("|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')?\s*(:|=>|=)\s*("|')?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}("|')?|(Basic\|)(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)': Invalid preceding regular expression

Any thoughts?

Mention in README that grep is invoked with -w

You might want to mention in the README that grep is invoked with the -w command line option. I was a little puzzled (ok, frustrated, it had been a long day :) about why I couldn't get any patterns to work until I looked at the source and saw how grep was being invoked.

Adding to GitHub Desktop for OSX

No issue, just a note.

If you installed this via homebrew and you use Github Desktop, you can add this like so:

cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/git/bin/git-secrets

Add support for serverside hooks

Client side hooks are great, but rely on developers properly setting them up and not taking shortcuts. Server side hooks provide an opportunity to enforce security policies at a more global level. Let's get support for server side hooks!

`git secrets --scan` on repo where files have spaces in their names fails

This results in treating each space delimited segment of the filename as a separate file, causing file not found errors with grep.

When calling --scan with no arguments, we scan all files returned by git ls-files. We might need to re-think this or to escape these filenames when passing them to grep. We could also look into using git grep in this case.

Maybe word-regexp is not needed?

Hi, I've just tried git secrets and it took me quite a while to understand what my regex is not working.

For example:

engine = create_engine('postgresql://admin:password@db-url/db-name')

And from man grep:

-w, --word-regexp
Select only those lines containing matches that form whole words.  The test is that the matching substring  must  either be at the  beginning of the line, or preceded by a non-word constituent
character.  Similarly, it must be either at the  end  of  the  line  or  followed  by  a  non-word constituent character.  Word-constituent characters are letters, digits, and the underscore.

And I've used this regex postgresql:\/\/[a-z]*_(ro|rw|admin):[a-z0-9]+@, which was not working.

Maybe I don't understand, but it seems that with -w grep care about the code context.
But I think git secrets should not care about entire line, but only about matching regex in the line.

Thanks, you've created very helpful tool

git-secrets fails with "repetition-operator operand invalid"

echo "0680bbe3-69e9-e763-e043-1250030aa31e" > broken.txt
git-secrets --scan broken.txt
grep: repetition-operator operand invalid

But this works (without last char e):

echo "0680bbe3-69e9-e763-e043-1250030aa31" > broken.txt
git-secrets --scan broken.txt
 git --version
git version 2.7.2
$ grep --version
grep (BSD grep) 2.5.1-FreeBSD
$ uname -a
Darwin .... 14.5.0 Darwin Kernel Version 14.5.0: Mon Jan 11 18:48:35 PST 2016; root:xnu-2782.50.2~1/RELEASE_X86_64 x86_64

High false positive rate for secrets.patterns=[A-Z0-9]{20}

Twenty upper case characters happen all the time- in data files, in binaries, everywhere. Removing this rule is remarkably difficult, requiring reading the source code and then formulating a regex that matches [A-Z0-9]{20} (see git-config man for what I was reading on unsetting a value with a repeated key name https://schacon.github.io/git/git-config.html)

My team is responding to these challenges by uninstalling it or using the no-verify.

I think this is a very bad default, or if it is a good default, the difficultly level for turning it off is too high.

git-secrets don't commits my changes/modification in git repository

after modification i have commit my changes and there was 12 modified files and after commit 4 files left to commit because of git-secrets and i have checked that there is no any password, secret credentials or any other secrets. then why git-secret prevents my commits?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.