Skip to content

jt24680/gha-exploit-guard-for-gitlab

Repository files navigation

Exploit Guard for GitLab

Scans GitHub Actions YAML files for 225 vulnerabilities, attack paths, and security anti-patterns in under 10 seconds.

This is a GitLab Component port of gha-exploit-guard. Includes the most up-to-date real-world attacks and defenses.

Table of Contents

Requirements

  • GitLab 15.0 or later — required for SARIF support in artifacts:reports:sast.
  • GitLab 16.6 or later — required for spec.inputs.regex validation on component inputs. On older versions, input constraints are silently ignored.
  • GitLab 17.0 or later — required if using CI/CD Component inclusion (include: component:). For older GitLab versions, use include: project: instead (see examples below).

Back to top

GitLab Component Usage

Include the template in your .gitlab-ci.yml using include: project::

include:
  - project: 'your-org/exploit-guard-for-gitlab'
    ref: main  # pin to a commit SHA or tag for production
    file: '/templates/exploit-guard.yml'

The template defines an exploit-guard-scan job that clones this repository, installs dependencies, runs the scanner against your project, and uploads SARIF results.

Important: When using include: project:, the spec.inputs regex validations and default values do not apply. You must set all EXPLOIT_GUARD_* variables explicitly. For full input validation, use include: component: on GitLab 17.0+.

Override defaults using CI/CD variables:

include:
  - project: 'your-org/exploit-guard-for-gitlab'
    ref: main  # pin to a commit SHA or tag for production
    file: '/templates/exploit-guard.yml'

exploit-guard-scan:
  variables:
    EXPLOIT_GUARD_TARGET_DIR: '.'
    EXPLOIT_GUARD_FAIL_ON_FINDINGS: 'true'
    EXPLOIT_GUARD_EXCLUDE: 'EG085,EG042'

On GitLab 17.0+, you can also use CI/CD Component syntax:

include:
  - component: gitlab.com/your-org/exploit-guard-for-gitlab/exploit-guard@main
    inputs:
      exploit-guard-project: 'your-org/exploit-guard-for-gitlab'
      target-dir: '.'
      fail-on-findings: 'true'

Security: For production pipelines, pin the ref (or component @ref) to a specific commit SHA or tag rather than main to prevent supply-chain attacks via branch compromise.

Back to top

Inputs

When using include: component:, pass these as component inputs:

Input Default Description
target-dir . Directory to scan, relative to project root
fail-on-findings false Fail the job when scanner reports findings
exclude (empty) Comma-separated check IDs to skip (e.g. EG001,EG035)
warn-only false Report findings without failing the job
sarif-file exploit-guards.sarif SARIF output file path
image python:3 Docker image (must have bash, python3, pip, and git)
exploit-guard-project (required) GitLab project path of this repo (e.g. your-org/exploit-guard-for-gitlab)
exploit-guard-ref main Git ref of the exploit-guard repo to use

When using include: project:, set these as CI/CD variables prefixed with EXPLOIT_GUARD_:

Variable Default Maps to
EXPLOIT_GUARD_TARGET_DIR . target-dir
EXPLOIT_GUARD_FAIL_ON_FINDINGS false fail-on-findings
EXPLOIT_GUARD_EXCLUDE (empty) exclude
EXPLOIT_GUARD_WARN_ONLY false warn-only
EXPLOIT_GUARD_SARIF exploit-guards.sarif sarif-file

Back to top

Runner Requirements

  • bash (version 4.0 or later) must be available on PATH.
  • python3 (version 3.11 or later) with pip must be available. PyYAML is installed automatically via pip install in the default image.
  • git must be available (the component clones this repo at runtime).
  • openssl must be available on PATH (used for clone integrity verification in the component template).
  • Works on any GitLab Runner with Docker or shell executor.

Tip: For production, pin the image input to a SHA digest (e.g. python:3@sha256:abc...) to prevent supply-chain attacks via mutable Docker tags.

CI_JOB_TOKEN Permissions

The component uses CI_JOB_TOKEN to clone the exploit-guard repo. The token needs read access to the exploit-guard-project repository. If the scanner repo is in a different group/project:

  1. In the scanner repo settings: go to Settings > CI/CD > Token Access and add the consumer project to the allowlist.
  2. The consumer's CI_JOB_TOKEN only needs read_repository scope on the scanner project — no write access is required.

Keep token permissions minimal to reduce blast radius if a runner is compromised.

Back to top

CLI Usage

gha-exploit-guard.sh /path/to/github-actions/repo/
gha-exploit-guard.sh .
gha-exploit-guard.sh --warn-only
gha-exploit-guard.sh --exclude EG085,EG042
gha-exploit-guard.sh --help

Excluding Checks

Use --exclude with a comma-separated list of check IDs to skip specific checks:

gha-exploit-guard.sh . --exclude EG085,EG042

Invalid IDs produce a warning but do not block the scan.

Inline Suppression

Add a YAML comment to any workflow file to suppress specific checks for that file only:

# exploit-guard-disable: EG085
# exploit-guard-disable: EG085,EG042
name: my-workflow
on: push

When a file contains an inline suppression comment, the scanner returns empty content for that file during the suppressed check, effectively skipping it.

Back to top

SARIF and Security Dashboard

The scanner produces two output files:

  • exploit-guards.txt — human-readable text output
  • exploit-guards.sarif — machine-readable SARIF 2.1.0 JSON

When using the GitLab Component, the SARIF file is automatically uploaded as a SAST artifact. Findings appear in:

  • The Security Dashboard (project and group level)
  • The Merge Request security widget
  • The Vulnerability Report

Note: SARIF support in artifacts:reports:sast requires GitLab 15.0 or later.

The scanner produces SARIF 2.1.0 output with fields required by GitLab's SAST report ingestion: runs[].tool.driver.name, runs[].tool.driver.rules[], results[].level, and results[].locations[].physicalLocation. GitLab silently drops findings that lack these fields.

Exit code semantics:

  • 0: all checks passed
  • 1: one or more checks failed (findings)
  • >1: scanner/runtime failure

Note: When warn-only is enabled, the job exits 0 but SARIF findings are still reported at "level": "error". GitLab's Security Dashboard will display them as vulnerabilities regardless of the exit code.

CLI users can generate SARIF with --sarif FILE:

gha-exploit-guard.sh /path/to/repo --sarif exploit-guards.sarif

Back to top

Local Testing

From repo root:

bash ./gha-exploit-guard.sh --help
# expected final status: 0 or 1; 2 indicates runtime/test harness failure
./tests/test-workflow-exploit-guards.sh .
# static contract checks for script wiring
./tests/test-offline.sh
# list and filter available checks
./tests/test-offline.sh --list
./tests/test-workflow-exploit-guards.sh --list
./tests/test-workflow-exploit-guards.sh --filter fixture --junit test-results.xml

Back to top

Maintainer Branch Protection Policy

Configure in GitLab project settings under Settings > Repository > Protected branches:

  • Protect the default branch (main).
  • Set Allowed to merge to Maintainers.
  • Set Allowed to push and merge to No one (enforce merge requests).
  • Require at least one approval in Settings > Merge requests > Approval rules.
  • Require these CI jobs to pass before merge:
    • regression
    • integration

Back to top

About

GitLab Component that scans GitHub Actions YAMLs for 180+ vulnerabilities, attack paths, and security anti-patterns in less than 10 seconds

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages