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
- Log into Checkmarx One portal
- Go to Projects > Create Project
- Connect your GitHub, GitLab, Bitbucket, or Azure DevOps repository
- 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 scanningPresets 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 changedCI/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_requestsBreaking 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.modFor 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.