Prevent Committing Secrets with a Pre-Commit Hook

It is difficult to remove a secret once committed to a git repo; the following describes how to prevent a commit with a secret (password, key, etc) using a pre-commit hook.

Even when following good practices for managing secrets (such as Secrets-as-a-Service) there is still a risk of accidentally committing secrets to git repositories by mistake. For example, suppose we pull secrets to use locally from Vault or similar, write some code and run “git add –all”; a file not meant to be committed can end up in the commit. If that happens, and especially if the commit is pushed to a remote, we would need to take extensive measures to wipe the secret from git history (see references).

Therefore, it is ideal to prevent committing anything that looks like a secret or password to a repo in the first place. This is possible by looking for high Shannon entropy strings and other techniques.
The detect-secrets project from Yelp is good for this.
Note: we need Docker installed on the system to use this tool.

Install the Node wrapper for detect-secrets globally:

$ npm install -g detect-secrets

Suppose we have a simple JavaScript file like this in index.js:

const output = 'Hello world'

console.log(output)

Run the following to check files for potential secrets:

$ detect-secrets-launcher index.js

Checking file: index.js

No results show for this file.

Now we add a high entropy string that looks like a password or secret key:

const output = 'Hello world'
const pwd = 'i6nrcpoeqzo4vmd0wpsn7j1pdglwv56mxsjggqkczwa'

console.log(output)

Run the secret detection again; the report should show:

$ detect-secrets-launcher index.js

Checking file: index.js
Potential secrets about to be committed to git repo! Please rectify or
explicitly ignore with an inline `pragma: allowlist secret` comment.

Secret Type: Base64 High Entropy String
Location: index.js:2

This shows the tool detected the potential secret.

Note that the scanner needs the file to be known to git; the git add command made this true.

We can add the detect-secrets-launcher command to a git pre-commit hook to detect any attempt to commit secrets and fail the pre-commit hook if any secrets are detected. The command will set the exit status to 1 if any secrets are found.

See this post for instructions on adding a git hook with Husky.

This .huskyrc file will connect detect-secrets to the pre-commit hook:

{
  "hooks": {
    "pre-commit": "detect-secrets-launcher *.js"
  }
}

Now try to commit the index.js file with the secret included:

$ git add .
$ git commit -m "try to commit a secret"

husky > pre-commit (node v11.6.0)

Checking file: index.js
Potential secrets about to be committed to git repo! Please rectify or
explicitly ignore with an inline `pragma: allowlist secret` comment.

Secret Type: Base64 High Entropy String
Location: index.js:2

...

husky > pre-commit hook failed (add --no-verify to bypass)

For larger projects with  more files the command might be:

"pre-commit": "detect-secrets-launcher src/**/*.js"

This can be used in projects as a guard against developers committing secrets, by accident or otherwise.

References

https://github.com/Yelp/detect-secrets

https://www.npmjs.com/package/detect-secrets

https://help.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository

Leave a Reply

Your email address will not be published. Required fields are marked *