Skip to main content

Customize Semgrep in pre-commit

Semgrep offers two standard pre-commit hooks outlined here.

  • The semgrep hook is optimized to run with a provided set of rules, either local rules or rules from the Semgrep Registry.
  • The semgrep-ci hook is optimized to run with the rules from your organization in the Semgrep AppSec Platform, without sending results to the platform, since results from pre-commit are temporary and not linked to the final code in the repository.
    • This hook requires the user be logged in locally to fetch the rules from the organization.

You can also create your own Semgrep hooks for pre-commit if you have particular needs or preferences, such as if you want users to see the output of the Semgrep scan even if it passed, or if you want to limit the scan to a particular Semgrep product.

Show the scan output

By default, pre-commit does not show the scan output if the hook passes. If you want your developers to see the output even if non-blocking findings are found, you can set the verbose option to print the output. To limit output to findings only (no scan information or diagnostics), redirect stderr to /dev/null, or use --quiet.

This example is based on the semgrep-ci hook, but a similar adjustment would also work with the semgrep hook.

repos:
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.101.0'
hooks:
- id: semgrep-verbose
entry: semgrep
args: ["ci", "--dry-run", "--baseline-commit", "HEAD" "2>/dev/null"]
verbose: true
pass_filenames: false

Limit the scan to a particular product

Semgrep Secrets is an ideal product to run before commit, since it can help prevent secrets from ever making it into the Git history, even locally. To run only Secrets in pre-commit, add the product flag to the args:

- repo: https://github.com/semgrep/pre-commit
rev: 'v1.101.0'
hooks:
- id: semgrep-secrets
pass_filenames: false
args: ["ci", "--dry-run", "--baseline-commit", "HEAD", "--secrets"]

Scan with Pro rules and cross-function analysis

The semgrep-ci hook requires the user to be logged in locally and runs with the engine configured in the organization, but the standard semgrep hook can also take advantage of local login to run with Pro rules and cross-function analysis.

- id: semgrep
name: semgrep
entry: semgrep
args: ["--pro", "--disable-version-check", "--quiet", "--skip-unknown-extensions"]

This provides analysis across modified files during the pre-commit scan, which may catch additional vulnerabilities, or prevent false positives.

Customization tips

Useful arguments

The provided hooks include useful arguments for Semgrep that you may want to include in your hooks as well.

For example, for the semgrep hook that runs with a provided --config, the arguments also include:

  • --disable-version-check: skip checking whether there's a new version of Semgrep (speeds up the check and avoids irrelevant output)
  • --quiet: only print findings, not other messages
  • --skip-unknown-extensions: if files are modified that aren't in a recognized language, skip them

The semgrep-ci hook runs with the pre-commit option pass_filenames: false. This is important because semgrep ci doesn't expect a list of filenames; it just expects to scan the folder, so you should preserve this option in your usage.

Adding baseline-commit HEAD performs a diff scan; this diff scan only scans the changes being added in the current commit (as intended for a pre-commit hook). It uses --dry-run so that findings that have no existence except in the local filesystem aren't added to the platform, which would otherwise result in clutter.

Entry point

Both of the default hooks use semgrep as the entry, which means the command executed is just semgrep with the args provided. However, you can write your own entry point. This approach is used in the less commonly used semgrep-docker hook also available in the semgrep/pre-commit repository.

It can also be used with a standard Semgrep execution to set environment variables in addition to (or instead of) arguments:

 entry: sh -c 'env SEMGREP_RULES=<SEMGREP_RULESET_URL> semgrep scan --code --no-suppress-errors --baseline-commit HEAD'

In this case, setting SEMGREP_RULES=<SEMGREP_RULESET_URL> substitutes for supplying --config and <SEMGREP_RULESET_URL> in the args.


Not finding what you need in this doc? Ask questions in our Community Slack group, or see Support for other ways to get help.