Writing Client-Side Pre-Commit Git Hooks

Question

How do I write a non-blocking, client-side pre-commit Git hook to make sure Fortify is being used? It should also make sure that I’m aware of the current state of the scan as I commit files.

Answer

Git has a way to fire off custom scripts when certain important actions occur. There are two groups of these hooks: client-side and server-side. Client-side hooks are triggered by operations such as committing and merging.

To write a pre-commit Fortify Git hook on Windows for example, you can create a Bash script called “pre-commit” that is then copied to the “.git\hooks” directory of your cloned repository.

After the “git add” command is then used for a file or files for the cloned repository, when the “git commit” command is subsequently called, it is at that point that the pre-commit Fortify Git hook will fire.

The listing for the sample pre-commit Fortify Git hook is below. The sample will need to be customized for your Fortify installation and cloned repository location on your machine in order to run.

Further customizations could also for example call a predefined Fortify script that performs the Fortify clean, translation and scan phases, such as what the Fortify Scan Wizard generates.

Also, the Fortify translation options for FORTIFY_DO_BUILD need to be customized according to the language the application is written in, as specified in the Fortify SCA User Guide.

Note: Before proceeding please make sure to follow all applicable policies and procedures with regards to customizing your Git installation.

#!/bin/bash

#This is a "hello world" client-side Git hook to make sure Fortify is being used

#It needs to be copied into "\.git\hooks" and named "pre-commit" on your local machine

MY_WORKSPACE="C:\Users\youruserid\Documents\your-workspace\github.com\your-organization\your-repo"
FORTIFY_SCAN_FILE="fortify-sample.fpr"
FORTIFY_HOME="/c/Fortify/Fortify_SCA_and_Apps_22.1.0/bin"
FORTIFY_UTILITY="$FORTIFY_HOME/FPRUtility.bat"
FORTIFY_SOURCEANALYZER="$FORTIFY_HOME/sourceanalyzer.exe"
FORTIFY_BUILD_ID="fortify-sample"
FORTIFY_DO_CLEAN="-b $FORTIFY_BUILD_ID -clean"
FORTIFY_DO_BUILD="-b $FORTIFY_BUILD_ID -cp $MY_WORKSPACE/**/*.jar -source 1.8 $MY_WORKSPACE"
FORTIFY_DO_SCAN="-b $FORTIFY_BUILD_ID -scan -format fpr -f $MY_WORKSPACE/$FORTIFY_SCAN_FILE"

DIVIDER="======================================================="

echo $DIVIDER
echo "Checking Fortify scan..."
echo $DIVIDER

#Check for a scan as evidence that Fortify is being used
if test -f ./$FORTIFY_SCAN_FILE; then
    echo "Checking Fortify scan $FORTIFY_SCAN_FILE"
else
	#If no scan file, perform scan
    echo "Fortify scan file not found"
    echo "Running Fortify scan..."

    echo "Fortify clean..."
    clean="$FORTIFY_SOURCEANALYZER $FORTIFY_DO_CLEAN"
    echo $clean
    $clean

    echo "Fortify build..."
    build="$FORTIFY_SOURCEANALYZER $FORTIFY_DO_BUILD"
    echo $build
    $build

    echo "Fortify scan..."
    scan="$FORTIFY_SOURCEANALYZER $FORTIFY_DO_SCAN"
    echo $scan
    $scan

fi

#Provide information about the scan
echo "Fortify software and rulepacks used:"
$FORTIFY_UTILITY -information  -versions -project ./$FORTIFY_SCAN_FILE | sed -n -e '/[Vv]ersion/ p' - | xargs

#Warn if there are potential security issues or scan errors
echo "Checking Fortify scan for security issues reported..."
#$FORTIFY_UTILITY -information -listIssues -categoryIssueCounts -project ./$FORTIFY_SCAN_FILE

criticalIssueCounts=`$FORTIFY_UTILITY -information -search -query "[fortify priority order]:Critical" -categoryIssueCounts -project ./$FORTIFY_SCAN_FILE`
highIssueCounts=`$FORTIFY_UTILITY -information -search -query "[fortify priority order]:High" -categoryIssueCounts -project ./$FORTIFY_SCAN_FILE`

echo "Critical severity issues: $criticalIssueCounts" | sed -n '1p' -
echo "High severity issue: $highIssueCounts" | sed -n '1p' -
$FORTIFY_UTILITY -information -errors -project ./$FORTIFY_SCAN_FILE  | xargs

#Wrap things up, don't block on client-side Git hooks, server-side should enforce policies
echo $DIVIDER
echo "Pre-commit Fortify scan analysis completed."
echo -e "$DIVIDER\n"

#Use exit 1 for debugging purposes
exit 1

Sample output for the above is below, note the scanned code is a sample that is included as part of the Fortify installation.

git commit README.md
=======================================================
Checking Fortify scan...
=======================================================
Checking Fortify scan fortify-sample.fpr
Fortify software and rulepacks used:
Engine Version: 22.1.0.0166 Fortify Secure Coding Rules, Community, Cloud; version: 2022.1.0.0007 Fortify Secure Coding Rules, Community, Universal; version: 2022.1.0.0007 Fortify Secure Coding Rules, Core, Android; version: 2022.1.0.0007 Fortify Secure Coding Rules, Core, Annotations; version: 2022.1.0.0007 Fortify Secure Coding Rules, Core, Java; version: 2022.1.0.0007 Fortify Secure Coding Rules, Core, Universal; version: 2022.1.0.0007 Fortify Secure Coding Rules, Extended, Configuration; version: 2022.1.0.0007 Fortify Secure Coding Rules, Extended, Content; version: 2022.1.0.0007 Fortify Secure Coding Rules, Extended, Java; version: 2022.1.0.0007 Fortify Secure Coding Rules, Extended, JSP; version: 2022.1.0.0007
Checking Fortify scan for security issues reported...
Critical severity issues: No issues matched search query.
High severity issue: 2 issues of 2 matched search query.
No warnings occurred during analysis
=======================================================
Pre-commit Fortify scan analysis completed.
=======================================================

References