GitLab Security Scanning

GitLab can automatically scan your code, dependencies, containers, and infrastructure for security vulnerabilities every time a pipeline runs. It catches problems before they reach production — without requiring a separate security tool.

Why Automated Security Scanning Matters

  Traditional security process:
  ─────────────────────────────────────────────────────
  Code written → shipped to production → security team
  audits weeks later → vulnerabilities found → costly fix

  GitLab security scanning:
  ─────────────────────────────────────────────────────
  Code written → pipeline runs → vulnerabilities flagged
  in merge request → developer fixes before merge ✅

Finding a bug after release costs up to 15 times more to fix than catching it during development.

The Five Main Scan Types

Scan TypeWhat It ChecksExample Finding
SASTYour source code for logic flawsSQL injection in login function
Dependency ScanningThird-party libraries for known CVEslodash 4.17.11 has a prototype pollution bug
Container ScanningDocker images for OS-level vulnerabilitiesOpenSSL 1.1.0 in base image has critical CVE
DASTRunning app from the outside like a hackerMissing security headers on login page
Secret DetectionCode for accidentally committed secretsAWS access key found in config.js

SAST — Static Application Security Testing

SAST reads your source code without running it and looks for patterns that commonly lead to security vulnerabilities. It works like a spell checker but for security flaws.

  Code GitLab SAST flags:
  ──────────────────────────────────────────────────────────
  ❌  query = "SELECT * FROM users WHERE id = " + userId
      Problem: SQL Injection — attacker can manipulate userId

  ✅  query = "SELECT * FROM users WHERE id = ?"
      parameters = [userId]
      Safe: parameterized query prevents injection
  ──────────────────────────────────────────────────────────

Enabling SAST

Add the SAST template to your .gitlab-ci.yml:

  include:
    - template: Security/SAST.gitlab-ci.yml

  stages:
    - test

  # SAST jobs are added automatically by the template

GitLab detects your programming language and picks the right analyser automatically (Semgrep for Python/JavaScript, SpotBugs for Java, Brakeman for Ruby on Rails, etc.).

Dependency Scanning

Your project likely uses dozens of open-source libraries. Each library can carry known vulnerabilities catalogued in public databases (CVEs). Dependency scanning checks your package.json, requirements.txt, pom.xml, and other lock files against these databases.

  include:
    - template: Security/Dependency-Scanning.gitlab-ci.yml
  Scan result example:
  ──────────────────────────────────────────────────────────
  Vulnerability: CVE-2023-26115
  Package:       word-wrap 1.2.3
  Severity:      High
  Fix:           Upgrade to word-wrap 1.2.4
  ──────────────────────────────────────────────────────────

Secret Detection

Developers sometimes accidentally commit API keys, passwords, or tokens directly into code. Secret Detection scans every commit — including the full git history — for these patterns.

  include:
    - template: Security/Secret-Detection.gitlab-ci.yml
  Finding example:
  ──────────────────────────────────────────────────────────
  File:     config/database.js   Line 12
  Type:     AWS Access Key
  Severity: Critical
  Value:    AKIA••••••••••••••••  (masked in display)
  Action:   Revoke key immediately and rotate it
  ──────────────────────────────────────────────────────────

If a secret is found, revoke it immediately even if you delete the commit. Git history is visible to anyone with repository access, and the secret may already have been seen.

Container Scanning

Docker base images contain an operating system and dozens of pre-installed packages. Any of these packages can have unpatched vulnerabilities. Container scanning inspects the layers of your built image.

  include:
    - template: Security/Container-Scanning.gitlab-ci.yml

  container_scanning:
    variables:
      CS_IMAGE: registry.gitlab.com/acme/my-webapp:latest
  Scan result:
  ──────────────────────────────────────────────────────────────────
  Base image: node:18-alpine
  Finding: CVE-2023-38545  zlib 1.2.11
  Severity: Critical
  Fix: Update base image to node:20-alpine (zlib patched)
  ──────────────────────────────────────────────────────────────────

DAST — Dynamic Application Security Testing

DAST runs your application and probes it from the outside, sending crafted requests to find weaknesses that only appear at runtime.

  DAST process:
  ─────────────────────────────────────────────────────
  App deployed to review environment
           ↓
  DAST scanner sends hundreds of test requests
  (like an automated hacker probing your app)
           ↓
  Reports: missing headers, open redirects,
           XSS vulnerabilities, insecure cookies
  include:
    - template: DAST.gitlab-ci.yml

  dast:
    variables:
      DAST_WEBSITE: https://staging.myapp.com

The Security Dashboard

All scan results aggregate in one place: Secure → Vulnerability Report. Every vulnerability shows:

  • Severity (Critical, High, Medium, Low, Info)
  • The scanner that found it
  • The affected file, line, or package
  • A description and recommended fix
  • Status (Detected, Confirmed, Dismissed, Resolved)
  Vulnerability Report
  ──────────────────────────────────────────────────────────────────
  Severity  Name                        Scanner      Status
  ──────────────────────────────────────────────────────────────────
  Critical  AWS key in config.js        Secret Det.  Detected
  High      SQL Injection — login.py    SAST         Confirmed
  High      CVE-2023-26115 word-wrap    Dep. Scan    Resolved ✅
  Medium    Missing X-Frame-Options     DAST         Dismissed
  ──────────────────────────────────────────────────────────────────

Merge Request Security Widget

When scanning runs in an MR pipeline, GitLab shows a summary of new vulnerabilities directly inside the merge request page. Reviewers see security findings alongside the code diff without switching to a separate dashboard.

  Merge Request #48 — Add payment integration
  ────────────────────────────────────────────────────
  ✅ Pipeline passed
  ⚠️  Security scanning detected 1 new vulnerability:
      HIGH: Hardcoded secret detected in payment.js:34
  ────────────────────────────────────────────────────
  [ View vulnerabilities ]   [ Approve ]   [ Merge ]

Dismissing a False Positive

Scanners occasionally flag safe code as a vulnerability. Open the finding in the Vulnerability Report, read the explanation, and click Dismiss vulnerability with a reason. Dismissed findings are hidden from the active list but preserved for audit purposes.

Leave a Comment

Your email address will not be published. Required fields are marked *