Checkmarx SAST: Complete Guide for Application Security Teams

Checkmarx SAST: Complete Guide for Application Security Teams

Checkmarx is one of the most widely deployed SAST platforms globally, known for its extensive language support, customizable queries, and strong developer workflow integrations. If your organization has a formal AppSec program, Checkmarx SAST (now part of Checkmarx One) is likely on the shortlist.

This guide covers how Checkmarx works, how to set it up, and how to use it without drowning your developers in false-positive noise.

What Checkmarx SAST Does

Checkmarx builds a full graph representation of your code — Abstract Syntax Trees (ASTs), Control Flow Graphs (CFGs), and Data Flow Graphs (DFGs) — then queries those graphs to find vulnerability patterns.

The query engine is written in CxQL (Checkmarx Query Language), a proprietary language for traversing code graphs. This is what distinguishes Checkmarx from many competitors: you can write custom queries to find vulnerabilities specific to your framework, coding patterns, or internal libraries.

Supported languages: Java, C#, JavaScript, TypeScript, Python, C/C++, Go, Kotlin, Swift, PHP, Ruby, Scala, Apex, COBOL, and more — over 30 languages total.

Vulnerability coverage: OWASP Top 10, CWE Top 25, SANS Top 25, PCI-DSS, HIPAA, and custom categories.

Deployment Options

Checkmarx One (SaaS/cloud): The current recommended platform. Connect your Git repository, configure scans, view results in the portal. No infrastructure to manage.

CxSAST (on-premises): The legacy enterprise product. Self-hosted on Windows Server with SQL Server. Still widely used in regulated environments that can't use cloud platforms.

CxIAST (IAST): Instrumented analysis — runs inside your application during testing to detect vulnerabilities with precise context. Separate product.

Getting Started with Checkmarx One

Connect Your Repository

  1. Log into Checkmarx One portal
  2. Go to Projects > Create Project
  3. Connect your GitHub, GitLab, Bitbucket, or Azure DevOps repository
  4. Checkmarx clones the repo and runs an initial scan

Configure the Scan

# .checkmarx/cx.yml — project scan configuration
scan:
  engines:
    sast:
      enabled: true
      preset: "Checkmarx Default"    # or "OWASP Top 10"
      incremental: true              # scan only changed files
    sca:
      enabled: true                  # software composition analysis
    kics:
      enabled: true                  # IaC scanning

Presets determine which vulnerability categories are checked. Common options:

  • Checkmarx Default — broad coverage, more findings
  • OWASP Top 10 — focused on the most critical web vulnerabilities
  • High and Medium — only high/medium severity findings
  • Custom presets — define your own set of queries

Incremental Scans

Full scans take 15–60+ minutes depending on codebase size. Incremental scans (only changed files) take 2–5 minutes — suitable for PR/branch scans.

scan:
  engines:
    sast:
      incremental: true
      incremental-threshold: 50  # fall back to full scan if >50% of files changed

CI/CD Integration

GitHub Actions

name: Checkmarx SAST
on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main]

jobs:
  checkmarx-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Checkmarx SAST Scan
        uses: checkmarx/ast-github-action@main
        with:
          cx_base_uri: ${{ secrets.CX_BASE_URI }}
          cx_tenant: ${{ secrets.CX_TENANT }}
          cx_client_id: ${{ secrets.CX_CLIENT_ID }}
          cx_client_secret: ${{ secrets.CX_CLIENT_SECRET }}
          project_name: ${{ github.repository }}
          branch: ${{ github.ref_name }}
          additional_params: "--scan-types sast,sca --sast-preset-name 'Checkmarx Default'"

GitLab CI

checkmarx-sast:
  stage: security
  image: checkmarx/ast-cli:latest
  script:
    - cx scan create
        --cx-base-uri $CX_BASE_URI
        --cx-tenant $CX_TENANT
        --cx-client-id $CX_CLIENT_ID
        --cx-client-secret $CX_CLIENT_SECRET
        --project-name $CI_PROJECT_PATH
        --branch $CI_COMMIT_REF_NAME
        --source .
        --scan-types sast
        --wait
  allow_failure: false
  only:
    - main
    - merge_requests

Breaking the Build

Configure a threshold for build failure:

additional_params: >
  --threshold "sast-high=0"
  --threshold "sast-critical=0"

This fails the CI build if any critical or high SAST findings are introduced. Medium and low findings generate warnings without blocking.

Working with Results

The Checkmarx Portal

Results are organized by:

  • Query name — e.g., "SQL_Injection", "Reflected_XSS_All_Clients"
  • Severity — Critical, High, Medium, Low, Info
  • Status — New, Confirmed, Not Exploitable, Proposed Not Exploitable

Reading Data Flow Traces

Each finding shows a data flow trace:

[Source] Line 24: userInput = request.getParameter("id")
  ↓ [Propagation] Line 45: processId(userInput)
  ↓ [Propagation] Line 12: query = "SELECT * FROM orders WHERE id=" + id
  [Sink] Line 13: stmt.execute(query)

Follow the source → sink path to understand how tainted data reaches a dangerous operation. The fix is usually at the sink (parameterize the query) or at the source (validate/sanitize the input).

Marking Results

Status When to Use
Confirmed Real vulnerability, needs a fix
Not Exploitable False positive — data is sanitized, path is unreachable, etc.
Proposed Not Exploitable Likely false positive, awaiting confirmation
Urgent Critical finding that needs immediate attention

Mark false positives with a justification comment. Checkmarx persists these across rescans — you won't re-triage the same false positive next sprint.

Custom Queries with CxQL

CxQL lets you write custom rules to find vulnerabilities specific to your codebase. This is Checkmarx's biggest differentiator.

Example: Finding Hardcoded API Keys

CxList hardcodedApiKeys = Find_Hardcoded_Data_Custom();

result = hardcodedApiKeys;
/* Custom method: Find strings that look like API keys */
CxList Find_Hardcoded_Data_Custom() {
    CxList stringLiterals = All.FindByType(typeof(StringLiteral));
    
    CxList apiKeyPattern = stringLiterals.FindByRegex(
        @"(?i)(api[_-]?key|secret[_-]?key|access[_-]?token)\s*=\s*[""'][a-zA-Z0-9]{20,}[""']"
    );
    
    return apiKeyPattern;
}

Example: Custom Taint Source (Internal Framework)

If your app uses an internal request-parsing framework that Checkmarx doesn't know about:

/* Extend the default SQL injection query to include your custom taint source */
override result = base.SQL_Injection();

CxList customSources = Find_Internal_UserInput();
result.Add(base.SQL_Injection().InfluencedBy(customSources));

Custom queries are stored in the Checkmarx portal under Queries > Custom and apply to your project automatically.

Software Composition Analysis (SCA)

Checkmarx One includes SCA alongside SAST. SCA scans your dependency manifests:

package.json, package-lock.json
pom.xml, build.gradle
requirements.txt, Pipfile.lock
Gemfile.lock
go.mod

For each dependency, SCA reports:

  • Known CVEs with CVSS scores
  • License types (flag GPL/LGPL in commercial software)
  • Fix version availability
  • Reachability (is the vulnerable function actually called in your code?)

The reachability analysis is valuable — it filters out CVEs in dependencies your code never actually calls.

Checkmarx IDE Plugin

Developers can scan from VS Code or IntelliJ before committing:

# VS Code
ext install Checkmarx.ast-results

# IntelliJ
# Install from JetBrains Marketplace: "Checkmarx"

The plugin shows inline results in the editor — developers see findings without switching to a portal. This shifts security left more effectively than portal-only workflows.

Metrics and Reporting

Checkmarx One's dashboards show:

  • Mean Time to Remediate (MTTR) by severity and team
  • New vs. recurring findings — are you improving or treading water?
  • Coverage — what percentage of your codebase is being scanned?
  • False positive rate — are developers marking things correctly?

Export reports for:

  • OWASP Top 10 compliance status
  • PCI-DSS 6.3.2 requirements (automated code review evidence)
  • SOC2 Type II audit evidence

Developer Experience Tips

IDE integration is non-negotiable. If findings only exist in a portal, developers won't look at them. The VS Code/IntelliJ plugins are worth the setup effort.

Tune false positives aggressively. A 30% false positive rate is normal for a new deployment. Drive it down by marking results and reviewing quarterly. Most teams reach < 15% within 6 months.

Use incremental scans in PRs. Full scans on every commit kill CI performance. Incremental scans on PRs + weekly full scans on main is the right balance.

Weekly team reviews for backlog. Schedule 30 minutes per week where the security champion and lead developer review new High/Critical findings together. This builds security literacy and keeps the backlog from growing.

Checkmarx and Runtime Testing

Checkmarx finds what could be exploited in code. Functional and regression tests verify that fixes don't break existing behavior and that the application behaves correctly under normal conditions.

Tools like HelpMeTest run 24/7 regression checks — so when a security fix is deployed, you know within minutes if something broke. This tight feedback loop is essential when shipping security patches on short timelines.

Summary

Checkmarx SAST is a powerful, flexible tool for teams serious about application security. Its CxQL query engine and strong CI/CD integrations make it particularly well-suited for organizations with custom frameworks or specific compliance requirements.

Start with the default preset, integrate into PR checks, drive down false positives over 60 days, then layer in custom queries for your internal patterns. The investment pays off in measurably lower defect density and faster remediation cycles.

Read more

Start now free