Configure code scanning on GitHub

Table of Contents

Prepearing for GitHub Advanced Security certification - Configure code scanning on GitHub

What is Code Scanning?

  • Code scanning uses CodeQL to analyze the code in a GitHub repository to find security vulnerabilities and coding errors
  • Is available for all public repositories, and for private repositories owned by organizations where GitHub Advanced Security is enabled.
  • If error or potential vulnerability is found then alert is displayed in the repos security tab.
  • Use code scanning to find, triage, and prioritize fixes for existing problems in your code.
  • Scans can be
    • Triggerd
    • Scheduled
    • when specific event occurs

About code scanning with CodeQL

  • Is code analyze Engine to automate security checks
  • Can use to analyze code
  • Display results as code scanning alerts

Two ways to use :

  • Add the CodeQL workflow to your repository. This uses the github/codeql-action to run the CodeQL CLI.
  • Run the CodeQL CLI directly in an external CI system and upload the results to GitHub.

How it works:

  • Generate a CodeQL database to represent your codebase,
  • Run CodeQL queries on that database to identify problems in the codebase.

CodeQL supports both compiled and interpreted languages:

  • C/C++
  • C#
  • Go
  • Java
  • JavaScript/TypeScript
  • Python
  • Ruby

Add the CodeQL workflow to your repository

Need write permissions to repo! How to setup:

  1. Security > Setup code scanning
    • If not avaible then turn on GHAS

  1. Click Set up this workflow

Note:

  • Workflows are displayed if they are relevant for the programming language detected in the repo.
  • Set up this workflow is only available for supported languages.
  1. You can customize the workflow to your liking.
  2. Commit the changes.

Note

  • Running code scanning with GitHub Actions will affect your monthly billing minutes.

About Billing for Actions

  • GitHub Actions usage is free for both public repositories and self-hosted runners.
  • For private repositories, certain amount of free minutes and storage depending on account used.

Enable code scanning with third party tools

  • Can run code scanning outside GitHub and publish results to GitHub.
  • Externaly run code scanning alerts are displayed same way as running withing GitHub.
  • Need to be Static Analysis Results Interchange Format (SARIF) file format.

About SARIF file uploads for code scanning

  • Code scanning result must use SARIF version 2.1.0.
  • Can upload result using API, CodeQL CLI or GH actions.

Code scanning API

  • Lets you retrieve and update code scanning alerts from a repositor
  • Can use the endpoints to create automated reports for the code scanning alerts in an organization
  • Upload analysis results
  • API can be accessed over HTTPS from https://api.github.com.
  • Data is in JSON format
  • Supported custom media type: application/sarif+json.
  • Can use this media type with GET requests sent to the /analyses/{analysis_id} endpoint.
    • The response includes a subset of the actual data that was uploaded for the specified analysis.
  • The response also includes additional data such as the github/alertNumber and github/alertUrl properties.
  • Data is formated as SARIF version 2.1.0

CodeQL CLI

  • Standalone product that can be used to analyze code.
  • Purpose is to generate a database representation of a codebase, a CodeQL database.
  • When DB is ready
    • can query it interactivly
    • run a suite of queries to generate SARIF format results
    • Upload results to GH
  • It is free to use on public repos
  • Available to use on private repositories that are owned by customers with an Advanced Security license
  • Download the CodeQL bundle from https://github.com/github/codeql-action/releases. The bundle contains:
    • CodeQL CLI product
    • A compatible version of the queries and libraries from https://github.com/github/codeql
    • Precompiled versions of all the queries included in the bundle

Its recommended to use CodeQL bundle to ensure compatibitlity.

Code scanning analysis with GitHub Actions

  • To use GitHub Actions to upload a third-party SARIF file to a repository, you’ll need a GitHub Actions workflow.
  • Workflow uses the upload-sarif action (part of the github/codeql-action repository)
    • Contains input paramters
  • Main input parameter is sarif-file
  • upload-sarif action can be configured to run when the push and scheduled event.
  • Example:

{% highlight yml %} name: ‘Code Scanning : Upload SARIF’ description: ‘Upload the analysis results’ author: ‘GitHub’ inputs: sarif_file: description: | The SARIF file or directory of SARIF files to be uploaded to GitHub code scanning. See https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/ uploading-a-sarif-file-to-github#uploading-a-code-scanning-analysis-with-github-actions for information on the maximum number of results and maximum file size supported by code scanning. required: false default: ‘../results’ checkout_path: description: “The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file.” required: false default: ${{ github.workspace }} token: default: ${{ github.token }} matrix: default: ${{ toJson(matrix) }} category: description: String used by Code Scanning for matching the analyses required: false wait-for-processing: description: If true, the Action will wait for the uploaded SARIF to be processed before completing. required: true default: “false” runs: using: ‘node12’ main: ‘../lib/upload-sarif-action.js’

{% endhighlight %}

  • To prevent duplicate alerts for the same problem, code scanning uses fingerprints to match results across various runs so they only appear once in the latest run for the selected branch.
  • SARIF files created by the CodeQL analysis workflow include this fingerprint data in the partialFingerprints field.
    • If its missing GitHub attempts to populate the field from source files.
    • If its not included in SARIF file, then the action will calculate the partialFingerprints for you and attempt to prevent duplicate alerts.
      • partialFingerprints can only be create if repo contains both SARIF and source code is used in the static analysis
  • SARIF upload supports 120 MB for the gzip-compressed SARIF file.

Upload SARIF files generated outside your repository

  • Can also create a new workflow that uploads SARIF files after you commit them to your repository
  • Useful when the SARIF file is generated as an artifact outside of your repository.

  • Follwing example is triggered on pushed commits and a schedule once per week
name: "Upload SARIF"



// Run workflow each time code is pushed to your repository and on a schedule. 

//The scheduled workflow runs every Thursday at 15:45 UTC.


on:

push:

schedule:

  - cron: '45 15 * * 4'



jobs:

build:

  runs-on: ubuntu-latest

  permissions:

    security-events: write

  steps:

    # This step checks out a copy of your repository.

    - name: Checkout repository

      uses: actions/checkout@v2

    - name: Upload SARIF file

      uses: github/codeql-action/upload-sarif@v1

      with:

        # Path to SARIF file relative to the root of the repository

        sarif_file: results.sarif

Upload SARIF files generated as part of a CI workflow

  • If SARIF file is generated by thirdparty tool as part of CI then the upload-sarif action could be a step after running CI tests

This example shows the ESLint static analysis tool as a step in a workflow. The Run ESLint step runs the ESLint tool and outputs the results.sarif file. The workflow then uploads the results.sarif file to GitHub using the upload-sarif action.

  name: "ESLint analysis"



// Run workflow each time code is pushed to your repository and on a schedule.

// The scheduled workflow runs every Wednesday at 15:45 UTC.

on:

  push:

  schedule:

    - cron: '45 15 * * 3'



jobs:

  build:

    runs-on: ubuntu-latest

    permissions:

      security-events: write

    steps:

      - uses: actions/checkout@v2

      - name: Run npm install

        run: npm install

      // Runs the ESlint code analysis

      - name: Run ESLint

        // eslint exits 1 if it finds anything to report

        run: node_modules/.bin/eslint build docs lib script spec-main -f node_modules/@microsoft/eslint-formatter-sarif/sarif.js -o results.sarif || true

      // Uploads results.sarif to GitHub repository using the upload-sarif action

      - uses: github/codeql-action/upload-sarif@v1

        with:

          // Path to SARIF file relative to the root of the repository

          sarif_file: results.sarif

Configure code scanning

For example you can configure:

  • specify the frequency of scans.
  • the languages or directories to scan.
  • what CodeQL code scanning looks for in your code.

Edit code scanning workflow

  • Edit the workflow CodeQL yaml file.

Configure frequency

  • Adjust frequency. eg On scedule or on events.
  • Scan on Push
  • Scan on PR
    • if a pull request is from a private fork, the pull_request event will only be triggered if you’ve selected the “Run workflows from fork pull requests” option in the repository settings.
    • trigger on merge commit

Define the severities causing pull request check failure

  • By default severity level of Error or security severity level of Critical or High will cause a pull request check failure.
  • PR failure doesnt stop code scan but block the code merging
  • Can configure severity level you would like to trigger a pull request check failure.

Avoid unnecessary scans of pull requests

  • Can configure this by specifying on:pull_request:paths-ignore or on:pull_request:paths in the code scanning workflow.
  • For example, if the only changes in a pull request are to files with the file extensions .md or .txt you can use the following paths-ignore array.
on:

   push:

      branches: [main, protected]

   pull_request:

      branches: [main]

      paths-ignore:

         - '**/*.md'

         - '**/*.txt'

Adjust scanning schedule

  • Default CodeQL analysis runs once a week
  • To adjust schedule edit cron value in workflow
on:

   push:

      branches: [main, protected]

   pull_request:

      branches: [main]

   schedule:

      - cron: '20 14 * * 1'

Configure code scanning exercise

Here