Secret scanning
Scan and prevent secret leaks in your code base
Building upon its core functionality of fetching and injecting secrets into your applications, Hanzo KMS now takes a significant step forward in bolstering your code security. We've enhanced our CLI tool to include a powerful scanning feature, capable of identifying more than 140 different types of secret leaks in your codebase. In addition to scanning for past leaks, this new addition also actively aids in preventing future leaks.
Scanning
kms scan
# Display the full secret findings
kms scan --verboseThe kms scan command serves to scan repositories, directories, and files. It's compatible with both individual developer machines and Continuous Integration (CI) environments.
When you run kms scan on a Git repository, Hanzo KMS will parses the output of a git log -p command. This command generates patches that Hanzo KMS uses to identify secrets in your code.
You can configure the range of commits that git log will cover using the --log-opts flag.
Any options you can use with git log -p are valid for --log-opts.
For instance, to instruct Hanzo KMS to scan a specific range of commits, use the following command: kms scan --log-opts="--all commitA..commitB". For more details, refer to the Git log documentation.
To scan individual files and directories, use the --no-git flag.
View full details for this command
kms scan git-changes
# Display the full secret findings
kms scan git-changes --verboseScanning for secrets before you commit your changes is great way to prevent leaks. Hanzo KMS makes this easy with the sub command git-changes.
The git-changes scans for uncommitted changes in a Git repository, and is especially designed for use on developer machines, aligning with the 'shift left' security approach.
When git-changes is run on a Git repository, Hanzo KMS parses the output from a git diff command.
To scan changes in commits that have been staged via git add, you can add the --staged flag to the sub command. This flag is particularly useful when using KMS CLI as a pre-commit tool.
View full details for this command
git-changes command is only for Git repositories; using it on files or directories will result in an error.
Automatically scan changes before you commit
To lower the risk of committing hardcoded secrets to your code repository, we have designed a custom git pre-commit hook. This hook scans the changes you're about to commit for any exposed secrets. If any hardcoded secrets are detected, it will block your commit.
Install pre-commit hook
To install this git hook, go into your local git repository and run the following command.
kms scan install --pre-commit-hookTo disable this hook after installing it, run the command git config --bool hooks.kms-scan false
Third party hooks management
If you would rather handle your pre-commit hook outside of the standard .git/hooks directory, you can quickly achieve this by adding the following command into your pre-commit script.
For instance, if you utilize Husky for managing your Git hooks, you can insert the command provided below into your .husky/pre-commit file.
kms scan git-changes --staged --verboseCreating a baseline
When scanning large repositories or repositories with a long history, it can be helpful to use a baseline.
A baseline allows Hanzo KMS to ignore any old findings that are already present in the baseline findings. You can create a kms scan report by running kms scan with the --report-path flag.
To create a Hanzo KMS scan report and save it in a file called leaks-report.json, use the following command:
kms scan --report-path leaks-report.jsonOnce a baseline is created, you can apply it when running the kms scan command again. Use the following command:
kms scan --baseline-path leaks-report.json --report-path findings.jsonAfter running the scan command with the --baseline-path flag, the report output in findings.json will only contain new issues.
Configuration file
To customize the scan, such as specifying your own rules or establishing exceptions for certain files or paths that should not be flagged as risks, you can define these specifications in the configuration file.
# Title for the configuration file
title = "Some title"
# This configuration is the foundation that can be expanded. If there are any overlapping rules
# between this base and the expanded configuration, the rules in this base will take priority.
# Another aspect of extending configurations is the ability to link multiple files, up to a depth of 2.
# "Allowlist" arrays get appended and may have repeated elements.
# "useDefault" and "path" cannot be used simultaneously. Please choose one.
[extend]
# useDefault will extend the base configuration with the default config:
# https://raw.githubusercontent.com/Hanzo KMS/kms/main/cli/config/kms-scan.toml
useDefault = true
# or you can supply a path to a configuration. Path is relative to where kms cli
# 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 = "some-identifier-for-rule"
# 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"]
# A regex match may have many groups, this allows you to specify the group that should be used as (which group the secret is contained in)
# 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.
# Shannon entropy measures how random a data is. Since secrets are usually composed of many random characters, they typically have high entropy
entropy = 3.5
# Keywords are used for pre-regex check filtering.
# If rule has keywords but the text fragment being scanned doesn't have at least one of it's keywords, it will be skipped for processing further.
# Ideally these values should either be part of the identifier or unique strings specific to the rule's regex
# (introduced in v8.6.0)
keywords = [
"auth",
"password",
"token",
]
# You can include an allowlist table for a single rule to reduce false positives or ignore commits
# with known/rotated secrets
[rules.allowlist]
description = "ignore commit A"
commits = [ "commit-A", "commit-B"]
paths = [
'''go\.mod''',
'''go\.sum'''
]
# note: (rule) regexTarget defaults to check the _Secret_ in the finding.
# if regexTarget is not specified then _Secret_ will be used.
# Acceptable values for regexTarget are "match" and "line"
regexTarget = "match"
regexes = [
'''process''',
'''getenv''',
]
# note: stopwords targets the extracted secret, not the entire regex match
# if the extracted secret is found in the stopwords list, the finding will be skipped (i.e not included in report)
stopwords = [
'''client''',
'''endpoint''',
]
# This is a global allowlist which has a higher order of precedence than rule-specific allowlists.
# If a commit listed in the `commits` field below is encountered then that commit will be skipped and no
# secrets will be detected for said commit. The same logic applies for regexes and paths.
[allowlist]
description = "global allow list"
commits = [ "commit-A", "commit-B", "commit-C"]
paths = [
'''gitleaks\.toml''',
'''(.*?)(jpg|gif|doc)'''
]
# note: (global) regexTarget defaults to check the _Secret_ in the finding.
# if regexTarget is not specified then _Secret_ will be used.
# Acceptable values for regexTarget are "match" and "line"
regexTarget = "match"
regexes = [
'''219-09-9999''',
'''078-05-1120''',
'''(9[0-9]{2}|666)-\d{2}-\d{4}''',
]
# note: stopwords targets the extracted secret, not the entire regex match
# if the extracted secret is found in the stopwords list, the finding will be skipped (i.e not included in report)
stopwords = [
'''client''',
'''endpoint''',
]Ignoring Known Secrets
If you're intentionally committing a test secret that kms scan might flag, you can instruct Hanzo KMS to overlook that secret with the methods listed below.
kms-scan:ignore
To ignore a secret contained in line of code, simply add kms-scan:ignore at the end of the line as comment in the given programming.
function helloWorld() {
console.log("8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ"); // kms-scan:ignore
}.kmsignore
An alternative method to exclude specific findings involves creating a .kmsignore file at your repository's root. You can then add the fingerprints of the findings you wish to exclude. The Hanzo KMS scan report provides a unique Fingerprint for each secret found. By incorporating these Fingerprints into the .kmsignore file, Hanzo KMS will skip the corresponding secret findings in subsequent scans.
bea0ff6e05a4de73a5db625d4ae181a015b50855:frontend/components/utilities/attemptLogin.js:stripe-access-token:147
bea0ff6e05a4de73a5db625d4ae181a015b50855:backend/src/json/integrations.json:generic-api-key:5
1961b92340e5d2613acae528b886c842427ce5d0:frontend/components/utilities/attemptLogin.js:stripe-access-token:148How is this guide?
Last updated on