Vulnerability Skill
Security vulnerability management for GitLab using glab api raw endpoint calls.
Quick Reference
| Operation | Command Pattern | Risk |
|---|---|---|
| List vulnerabilities | glab api projects/:id/vulnerabilities | - |
| Get vulnerability | glab api projects/:id/vulnerabilities/:vuln_id | - |
| Confirm vulnerability | glab api projects/:id/vulnerabilities/:vuln_id/confirm -X POST | ⚠️ |
| Dismiss vulnerability | glab api projects/:id/vulnerabilities/:vuln_id/dismiss -X POST -f ... | ⚠️ |
| Resolve vulnerability | glab api projects/:id/vulnerabilities/:vuln_id/resolve -X POST | ⚠️ |
| Revert to detected | glab api projects/:id/vulnerabilities/:vuln_id/revert -X POST | ⚠️ |
| List findings | glab api projects/:id/vulnerability_findings | - |
Risk Legend: - Safe | ⚠️ Caution | ⚠️⚠️ Warning | ⚠️⚠️⚠️ Danger
When to Use This Skill
ALWAYS use when:
- User mentions "vulnerability", "security issue", "CVE"
- User wants to view security scan results
- User mentions "SAST", "DAST", "dependency scanning", "container scanning"
- User wants to dismiss or resolve security findings
- User asks about security dashboard
NEVER use when:
- User wants to run security scans (use gitlab-ci)
- User wants to configure security settings (use project settings)
- User wants general issue tracking (use gitlab-issue)
API Prerequisites
Required Token Scopes: read_api or api
Permissions:
- Read vulnerabilities: Developer+
- Manage vulnerabilities: Developer+
GitLab Tier: Ultimate required for full vulnerability management features
Vulnerability States
| State | Description |
|---|---|
detected | New, unreviewed vulnerability |
confirmed | Verified as real vulnerability |
dismissed | Marked as false positive or won't fix |
resolved | Fixed and no longer present |
Severity Levels
| Severity | Description |
|---|---|
critical | Highest severity, immediate action needed |
high | Significant risk |
medium | Moderate risk |
low | Minor risk |
info | Informational finding |
unknown | Severity not determined |
Available Commands
List Project Vulnerabilities
# List all vulnerabilities
glab api projects/123/vulnerabilities --method GET
# Filter by state
glab api "projects/123/vulnerabilities?state=detected" --method GET
# Filter by severity
glab api "projects/123/vulnerabilities?severity=critical,high" --method GET
# Filter by multiple criteria
glab api "projects/123/vulnerabilities?state=detected&severity=critical,high" --method GET
# With pagination
glab api projects/123/vulnerabilities --paginate
# Using project path
glab api "projects/$(echo 'mygroup/myproject' | jq -Rr @uri)/vulnerabilities"
Get Vulnerability Details
# Get specific vulnerability
glab api projects/123/vulnerabilities/456 --method GET
Confirm Vulnerability
Marks a detected vulnerability as confirmed (real security issue).
# Confirm vulnerability
glab api projects/123/vulnerabilities/456/confirm --method POST
Dismiss Vulnerability
Marks a vulnerability as dismissed (false positive or accepted risk).
# Dismiss as false positive
glab api projects/123/vulnerabilities/456/dismiss --method POST \
-f comment="False positive - this code path is not reachable"
# Dismiss as acceptable risk
glab api projects/123/vulnerabilities/456/dismiss --method POST \
-f comment="Accepted risk - mitigated by network controls"
# Dismiss with dismissal reason (if available)
glab api projects/123/vulnerabilities/456/dismiss --method POST \
-f comment="Not applicable to our use case" \
-f dismissal_reason="used_in_tests"
Resolve Vulnerability
Marks a vulnerability as resolved (fixed).
# Resolve vulnerability
glab api projects/123/vulnerabilities/456/resolve --method POST
Revert to Detected State
Reverts a vulnerability back to detected state.
# Revert to detected
glab api projects/123/vulnerabilities/456/revert --method POST
List Vulnerability Findings
Findings are the raw results from security scanners.
# List all findings
glab api projects/123/vulnerability_findings --method GET
# Filter by severity
glab api "projects/123/vulnerability_findings?severity=critical,high" --method GET
# Filter by scanner
glab api "projects/123/vulnerability_findings?scanner=sast" --method GET
# Filter by pipeline
glab api "projects/123/vulnerability_findings?pipeline_id=789" --method GET
# With pagination
glab api projects/123/vulnerability_findings --paginate
Security Dashboard (Group Level)
# Get security statistics for group
glab api groups/456/vulnerability_exports --method POST \
-f export_format="csv"
# Get group vulnerability statistics
glab api "groups/456/vulnerability_statistics" --method GET
Common Workflows
Workflow 1: Triage New Vulnerabilities
project_id=123
# Get all detected (new) vulnerabilities
glab api "projects/$project_id/vulnerabilities?state=detected" --paginate | \
jq -r '.[] | "[\(.severity)] \(.title) - \(.id)"'
# Review critical/high first
glab api "projects/$project_id/vulnerabilities?state=detected&severity=critical,high" | \
jq -r '.[] | "ID: \(.id)\nTitle: \(.title)\nSeverity: \(.severity)\nScanner: \(.scanner.name)\nLocation: \(.location | @json)\n---"'
Workflow 2: Generate Security Report
project_id=123
# Summary by severity
echo "=== Vulnerability Summary ==="
glab api "projects/$project_id/vulnerabilities" --paginate | \
jq -r 'group_by(.severity) | map({severity: .[0].severity, count: length}) | .[] | "\(.severity): \(.count)"'
# Summary by state
echo ""
echo "=== By State ==="
glab api "projects/$project_id/vulnerabilities" --paginate | \
jq -r 'group_by(.state) | map({state: .[0].state, count: length}) | .[] | "\(.state): \(.count)"'
# Summary by scanner
echo ""
echo "=== By Scanner ==="
glab api "projects/$project_id/vulnerabilities" --paginate | \
jq -r 'group_by(.scanner.name) | map({scanner: .[0].scanner.name, count: length}) | .[] | "\(.scanner): \(.count)"'
Workflow 3: Bulk Dismiss False Positives
project_id=123
# Dismiss all info-level findings from specific scanner
glab api "projects/$project_id/vulnerabilities?severity=info&state=detected" --paginate | \
jq -r '.[].id' | while read vuln_id; do
echo "Dismissing $vuln_id"
glab api projects/$project_id/vulnerabilities/$vuln_id/dismiss --method POST \
-f comment="Bulk dismissed - info level findings"
done
Workflow 4: Track Critical Vulnerabilities
project_id=123
# List critical vulnerabilities with details
glab api "projects/$project_id/vulnerabilities?severity=critical" --paginate | \
jq -r '.[] | {
id: .id,
title: .title,
state: .state,
detected_at: .detected_at,
scanner: .scanner.name,
identifiers: [.identifiers[]?.name] | join(", ")
}'
Workflow 5: Check for CVEs
project_id=123
cve="CVE-2021-44228"
# Search for specific CVE
glab api "projects/$project_id/vulnerabilities" --paginate | \
jq -r ".[] | select(.identifiers[]?.name == \"$cve\") | \"ID: \(.id), State: \(.state), Title: \(.title)\""
Workflow 6: Export Vulnerabilities
project_id=123
# Export to JSON
glab api "projects/$project_id/vulnerabilities" --paginate > vulnerabilities.json
# Export to CSV format
glab api "projects/$project_id/vulnerabilities" --paginate | \
jq -r '["id","title","severity","state","scanner","detected_at"],
(.[] | [.id, .title, .severity, .state, .scanner.name, .detected_at]) | @csv' > vulnerabilities.csv
Workflow 7: Compare Pipeline Results
project_id=123
# Get findings from specific pipeline
pipeline_id=789
glab api "projects/$project_id/vulnerability_findings?pipeline_id=$pipeline_id" | \
jq -r '.[] | "\(.severity): \(.name)"'
Scanner Types
| Scanner | Report Type | Description |
|---|---|---|
sast | SAST | Static Application Security Testing |
dast | DAST | Dynamic Application Security Testing |
dependency_scanning | Dependency Scanning | Third-party dependency vulnerabilities |
container_scanning | Container Scanning | Container image vulnerabilities |
secret_detection | Secret Detection | Hardcoded secrets in code |
coverage_fuzzing | Coverage Fuzzing | Fuzzing test results |
api_fuzzing | API Fuzzing | API fuzzing results |
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| 403 Forbidden | Ultimate required or no access | Check GitLab tier and permissions |
| Empty results | No scans run | Configure and run security scanners in CI |
| Old vulnerabilities | No recent pipeline | Run new pipeline with security jobs |
| Can't dismiss | Already dismissed or resolved | Check current state |
| Missing scanner type | Scanner not configured | Add scanner to CI configuration |
Best Practices
- Triage regularly: Review new vulnerabilities frequently
- Document dismissals: Always add comments explaining why
- Track critical issues: Monitor critical/high severity closely
- Integrate with issues: Create issues for confirmed vulnerabilities
- Automate where possible: Use CI to fail on new critical findings