Git Hooks with Xygeni
A git hook is a custom action that is launched when certain events occur in the Git version control system.
Hooks are stored in the .git/hooks
directory. Hooks could be run client-side or server-side. Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits. The hook is a script named under the event that triggers its execution. For example, pre-commit
runs for git commit command, before the commit message is set.
Server side hooks like pre-receive
could be useful for scanning changes for security issues before a push is accepted, but they could be registered only when you operate the Git remote host.
The client-side hooks useful for our purposes are:
pre-commit
, which could be used to inspect the snapshot that is about to be committed, by running the scanner at the client-side. This is the recommended way to perform a scan and block commits with important security issues.post-commit
, where results from a previous scan could be processed or sent to some recipients. This could be also done in the pre-commit hook, but here the commit was complete.pre-push
runs duringgit push
, before transferring any objects. It could be used to scan a repository before a reference is pushed to a remote.
The server-side events useful for our purposes are:
pre-receive
, when handling a push from a client. The Xygeni scanner can reject a push based on issues found. The stdin contains a line for each ref to update: <old-value> <new-value> <ref-name>
Hook scripts typically follow the convention on exit codes: 0 means 'success', non-zero means 'failure' and often aborts the git operation.
Client-side pre-commit
hooks are recommended to detect and block unintentional severity issues like secret leaks. Server side pre-receive
hooks can block the repository to integrate commits pushed, but often cloud-based source code management (SCM) systems like GitHub do not allow hooking on such events. You may add the scan as a 'detector'. This is a limitation of the on-cloud SCM itself, and not a limitation of the Xygeni scanner. Server-side hooks are usually limited to self-managed or on-premises editions.
Sharing Git Hooks
Please remind that git hooks are not copied when a repository is cloned.
To share hook scripts it is necessary to (1) have a convention for sharing tooling data at the project and organization scopes, and (2) a mechanism to sync the tooling data in each developer workstation.
For example, you may keep tooling under a ./dev
project directory as a matter of convention, placed under version control.
Take special care of not hard-coding secrets and other sensitive information in the tooling configuration files.
Git hook scripts are critical code that needs to be protected against code tampering. It is recommended to use special measures when changes are needed, like security reviews before allowing mergeing any commit with modifications.
If the Git hook scripts are stored e.g. in ./dev/hooks
directory, and not too old git version is used (git >= 2.9), you may set the git core.hooksPath
configuration, with git config core.hooksPath ./dev/hooks
or a function like this:
Refer to Keeping Git Hooks in Sync blog for more details.
Running scanner as a gate in a git hook
To run Xygeni scanner at client-side, before a commit is applied, you may add a simple pre-commit
executable script like this (example for Linux and macOS):
The --fail-on
option is configured to make the build fail when at least one issue with critical or high severity is found (so the scanner acts as a security gate
).
For running the scan as an optional pipeline check, use --fail-on=never
instead.
The --no-stdin
option is recommended to avoid the scanner to get the files to process from the standard input. Under some environments, this could make the scanner to analyze no files at all.
This example is a similar security gatekeeper, but commits are allowed only when no scan of the given types has a critical issue (only the scanner execution is shown, for brevity):
When a critical issue is detected in any of the scans for secrets, misconfigurations or IaC flaws, the commit will be aborted.
Using pre-commit framework
There are some popular frameworks for improving the hook mechanism provided by Git, mainly aimed at sharing the scripts and simplifying the configuration when multiple actions need to be added for a git event.
One of the most popular frameworks is pre-commit
. The list of actions required are listed in a YAML file, and `pre-commit
manages the installation and execution of scripts written in any language.
Follow the instructions given in pre-commit quick start for installing the framework. Essentially you need python
and pip
, and run pip install pre-commit
in the node where the git commit
will be intercepted.
Then add the following entry to you .pre-commit-config.yaml
:
Or, for running the scanner Docker image:
Then install the git hook scripts using
Xygeni scanner will run before each commit. The configuration given above works for setting Xygeni as a security gate to avoid commits having critical security issues. To avoid break the builds, --fail-on=never
could be used instead.
To disable the pre-commit
hook, for example when after analysis the findings found were deemed as false positives or on inactive / no-risk issues, use SKIP=xygeni
in front of the git command: ---
Last updated