vulnerability management
GitLab Ultimate Vulnerability Management
This guide covers vulnerability triage, remediation, and tracking workflows in GitLab Ultimate. Vulnerability management provides centralized tracking and remediation of security findings from all scanners.
Overview
GitLab Ultimate provides comprehensive vulnerability management capabilities:
- Security Dashboard - Centralized vulnerability view across projects
- Vulnerability Report - Detailed tracking per project
- Triage Workflows - Status management and assignment
- Remediation Tracking - From detection to resolution
- Trend Analysis - Historical vulnerability metrics
- Integration - Merge request and pipeline integration
All vulnerabilities detected by security scanners (SAST, DAST, Dependency Scanning, Container Scanning, Secret Detection, etc.) flow into vulnerability management for centralized tracking.
Security Dashboard
Overview
The Security Dashboard provides a unified view of all security vulnerabilities across projects, groups, and instances.
Accessing the Dashboard
Project Level:
- Navigate to: Security & Compliance > Security Dashboard
- Shows vulnerabilities for current project only
Group Level:
- Navigate to: Group > Security & Compliance > Security Dashboard
- Shows vulnerabilities across all projects in group
- Ultimate tier required
Instance Level:
- Navigate to: Admin Area > Security & Compliance > Security Dashboard
- Shows vulnerabilities across entire GitLab instance
- Ultimate tier required, admin access required
Dashboard Features
Key Capabilities:
- Vulnerability count by severity (critical, high, medium, low)
- Trend charts showing vulnerability changes over time
- Filter by project, scanner type, severity, status
- Quick access to high-priority issues
- Export capabilities for reporting
Severity Levels:
- Critical - Immediate attention required, exploitable vulnerabilities
- High - Serious issues requiring prompt attention
- Medium - Moderate risk, should be addressed soon
- Low - Minor issues, address as resources allow
- Info - Informational findings, no immediate risk
Using the Dashboard
Filtering Vulnerabilities:
Filters available:
- Project: Select specific projects
- Scanner: SAST, DAST, Dependency Scanning, etc.
- Severity: Critical, High, Medium, Low, Info
- Status: Detected, Confirmed, Dismissed, Resolved
- Activity: Recently detected, long-standing
Bulk Actions:
- Select multiple vulnerabilities
- Change status in bulk (confirm, dismiss)
- Assign to users
- Add to issues
Export Options:
- CSV export for external reporting
- API access for automation
- Integration with external tools
Trend Analysis
Available Metrics:
- New vulnerabilities detected (by time period)
- Vulnerabilities resolved (by time period)
- Mean time to remediation
- Vulnerability backlog growth/reduction
- Scanner effectiveness
Time Ranges:
- 30 days
- 90 days
- 6 months
- 1 year
- Custom date range
Vulnerability Report
Overview
The Vulnerability Report provides detailed information about all vulnerabilities in a specific project. It's the primary tool for vulnerability triage and remediation tracking.
Accessing the Report
Navigation: Project > Security & Compliance > Vulnerability Report
Vulnerability Lifecycle
Status Workflow:
Detected Confirmed Resolved
Dismissed (False Positive)
Status Definitions:
- Detected - Initial state when scanner finds vulnerability
- Confirmed - Team verified vulnerability is real and exploitable
- Dismissed - Marked as false positive or accepted risk
- Resolved - Vulnerability fixed and no longer detected
Vulnerability Details
Information Displayed:
- Title - Vulnerability description
- Severity - Critical, High, Medium, Low, Info
- Status - Detected, Confirmed, Dismissed, Resolved
- Scanner - Which scanner detected it (SAST, DAST, etc.)
- Location - File, line number, or URL where found
- Identifiers - CVE numbers, CWE IDs, internal IDs
- First Detected - When first discovered
- Description - Detailed explanation of vulnerability
- Solution - Remediation recommendations
- Links - External references and documentation
Viewing Vulnerability Details
Detailed View:
Click any vulnerability to see full details:
Vulnerability: SQL Injection in login endpoint
Severity: High
Status: Detected
Scanner: DAST
Location: /api/v1/login
Description:
The login endpoint is vulnerable to SQL injection attacks. User input
is not properly sanitized before being used in database queries.
Evidence:
POST /api/v1/login
Body: {"username": "admin' OR '1'='1", "password": "test"}
Response: 200 OK with admin session token
Solution:
1. Use parameterized queries or prepared statements
2. Implement input validation and sanitization
3. Apply principle of least privilege for database access
References:
- CWE-89: SQL Injection
- OWASP A03:2021 - Injection
- CVE-2023-12345
Triage Workflow
Initial Assessment
When new vulnerabilities are detected:
-
Review Vulnerability
- Read full description
- Understand exploit scenario
- Assess business impact
-
Verify Finding
- Confirm vulnerability is real
- Check if it's exploitable in your context
- Test in staging environment if needed
-
Set Priority
- Consider severity level
- Evaluate business impact
- Factor in exploitability
- Account for affected systems
-
Update Status
- Confirm if real vulnerability
- Dismiss if false positive
- Add comments with reasoning
Confirming Vulnerabilities
When to Confirm:
- Vulnerability is real and exploitable
- Code/configuration is actually vulnerable
- Issue poses legitimate security risk
How to Confirm:
- Open vulnerability details
- Click "Confirm" button
- Add comment explaining confirmation
- Optionally assign to developer
- Set due date if needed
Example Comment:
Confirmed: This SQL injection vulnerability is exploitable in production.
Testing in staging environment successfully extracted sensitive data.
Priority: High
Assignment: @john-doe
Due Date: 2026-01-15
Remediation Plan:
1. Switch to parameterized queries
2. Add input validation
3. Deploy to staging by Jan 10
4. Production deployment Jan 15
Dismissing False Positives
When to Dismiss:
- Scanner incorrectly flagged secure code
- Vulnerability not exploitable in your context
- Accepted risk with documented justification
- Compensating controls in place
Dismissal Reasons:
GitLab provides standard dismissal reasons:
- False Positive - Not actually a vulnerability
- Used in Tests - Only present in test code
- Acceptable Risk - Risk accepted by security team
- Mitigated - Compensating controls in place
How to Dismiss:
- Open vulnerability details
- Click "Dismiss" button
- Select dismissal reason
- Add detailed comment explaining decision
- Optionally require approval
Example Dismissal:
Dismissal Reason: False Positive
Comment:
This SAST finding flags user input being used in SQL query, but the code
actually uses parameterized queries through the ORM. The analyzer doesn't
recognize the ORM abstraction.
Evidence:
- Line 42: db.query("SELECT * FROM users WHERE id = ?", [userId])
- ORM automatically sanitizes parameters
Reviewed by: @security-team
Date: 2026-01-08
Resolving Vulnerabilities
Resolution Process:
Vulnerabilities are automatically marked as Resolved when:
- Scanner no longer detects the issue in subsequent scans
- Vulnerable code is removed or fixed
- Vulnerable dependency is updated
- Container image is rebuilt without vulnerability
Manual Resolution:
You cannot manually mark vulnerabilities as resolved. Resolution happens automatically through remediation and re-scanning.
Verification:
After fixing a vulnerability:
- Push code changes
- Wait for pipeline to run security scans
- Verify vulnerability no longer appears
- Status automatically updates to "Resolved"
Remediation Strategies
SAST Vulnerabilities
Remediation Steps:
-
Locate Vulnerable Code
- Check file and line number in vulnerability details
- Review code context
-
Understand Issue
- Read vulnerability description
- Understand security implication
- Review suggested solution
-
Implement Fix
- Apply recommended remediation
- Follow secure coding practices
- Add input validation, sanitization, or proper API usage
-
Verify Fix
- Run local SAST scan if possible
- Create merge request
- Wait for pipeline SAST scan to confirm
Example: SQL Injection Fix
Before:
// Vulnerable code const userId = req.params.id; const query = `SELECT * FROM users WHERE id = ${userId}`; db.execute(query);
After:
// Fixed code const userId = req.params.id; const query = 'SELECT * FROM users WHERE id = ?'; db.execute(query, [userId]);
Dependency Vulnerabilities
Remediation Steps:
-
Identify Vulnerable Package
- Check dependency name and version
- Review CVE details
-
Find Safe Version
- Check GitLab advisory for recommended version
- Review package changelog for fixes
- Ensure compatibility with your code
-
Update Dependency
- Update package.json, Gemfile, requirements.txt, etc.
- Update lock file
- Test application functionality
-
Verify Fix
- Run dependency scanning locally
- Create merge request
- Verify vulnerability resolved in pipeline
Example: npm Dependency Update
# Check current version npm list lodash # Update to safe version npm install lodash@4.17.21 # Verify no vulnerabilities npm audit # Commit changes git add package.json package-lock.json git commit -m "fix: update lodash to resolve CVE-2023-12345"
Container Vulnerabilities
Remediation Steps:
-
Update Base Image
- Use latest version of base image
- Switch to minimal base images (Alpine, Distroless)
- Remove unnecessary packages
-
Rebuild Image
- Update Dockerfile
- Build new image
- Push to registry
-
Verify Fix
- Run container scanning on new image
- Deploy to staging
- Verify vulnerability resolved
Example: Dockerfile Update
Before:
FROM ubuntu:20.04 RUN apt-get update && apt-get install -y python3
After:
# Use newer base with security patches FROM ubuntu:22.04 RUN apt-get update && apt-get install -y python3 && apt-get clean && rm -rf /var/lib/apt/lists/*
DAST Vulnerabilities
Remediation Steps:
-
Reproduce Issue
- Review DAST evidence
- Test exploit in staging environment
- Understand attack vector
-
Implement Fix
- Add input validation
- Enable security headers
- Fix authentication/authorization issues
- Apply framework security features
-
Deploy Fix
- Deploy to staging
- Run DAST scan again
- Verify vulnerability resolved
- Deploy to production
Example: XSS Fix
Before:
// Vulnerable to XSS app.get('/user', (req, res) => { const name = req.query.name; res.send(`<h1>Hello ${name}</h1>`); });
After:
// Fixed with proper escaping const escapeHtml = require('escape-html'); app.get('/user', (req, res) => { const name = req.query.name; res.send(`<h1>Hello ${escapeHtml(name)}</h1>`); });
Secret Detection
Remediation Steps:
-
Rotate Secret Immediately
- Revoke exposed credential
- Generate new secret
- Update services using the secret
-
Remove from Git History
- Use git filter-branch or BFG Repo-Cleaner
- Force push to remote
- Notify team of history rewrite
-
Store Properly
- Move to CI/CD variables (masked)
- Use HashiCorp Vault or AWS Secrets Manager
- Never commit secrets again
-
Audit Access
- Check logs for unauthorized use
- Verify no security breach occurred
Example: Secret Rotation
# 1. Revoke exposed token # (Use service provider's UI or API) # 2. Remove from git history git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch config/secrets.yml" \ --prune-empty --tag-name-filter cat -- --all # 3. Force push git push origin --force --all # 4. Store in CI/CD variable # Navigate to: Settings > CI/CD > Variables # Add variable: API_TOKEN (masked, protected) # 5. Update code to use variable # In .gitlab-ci.yml: # variables: # API_TOKEN: $API_TOKEN
Assignment and Collaboration
Assigning Vulnerabilities
How to Assign:
- Open vulnerability details
- Click "Assignee" field
- Select team member
- Optionally set due date
- Add comment with context
When to Assign:
- Developer who wrote vulnerable code
- Security team member for review
- Tech lead for prioritization
- DevOps engineer for infrastructure issues
Best Practices:
- Assign based on expertise and ownership
- Set realistic due dates
- Provide context in comments
- Follow up on assignments
Comment Threads
Using Comments:
Vulnerability details support threaded comments for collaboration:
@security-team: This looks like a real SQL injection. Can someone verify?
@john-doe: Confirmed. I tested in staging and was able to extract data.
@security-team: Thanks. Marking as Confirmed and assigning to @dev-team.
@dev-team: Fix deployed. Please verify in next scan.
Comment Uses:
- Verification discussions
- Remediation planning
- Progress updates
- Approval requests
- Knowledge sharing
Creating Issues
Link to GitLab Issues:
Convert vulnerability to GitLab issue for tracking:
- Open vulnerability details
- Click "Create Issue" button
- Pre-filled issue created with vulnerability details
- Issue automatically linked to vulnerability
- Track remediation in issue workflow
Issue Template:
## Vulnerability: SQL Injection in Login API **Severity:** High **Status:** Confirmed **Scanner:** DAST **First Detected:** 2026-01-08 ### Description The login endpoint is vulnerable to SQL injection attacks... ### Location - URL: /api/v1/login - Method: POST ### Evidence POST /api/v1/login Body: {"username": "admin' OR '1'='1", "password": "test"} ### Remediation 1. Implement parameterized queries 2. Add input validation 3. Test in staging 4. Deploy to production ### References - Vulnerability Report: [Link] - CWE-89: SQL Injection - OWASP A03:2021 - Injection
Merge Request Integration
Vulnerability Widget
MR Widget Display:
Merge requests automatically display security findings:
Security Scanning
SAST: 2 new vulnerabilities
- High: SQL Injection in user_controller.rb
- Medium: Path Traversal in file_upload.rb
Dependency Scanning: 1 new vulnerability
- High: CVE-2023-12345 in lodash 4.17.15
Secret Detection: No vulnerabilities found
Container Scanning: Not run (no container changes)
Widget Features:
- Summary of new vulnerabilities
- Comparison to target branch
- Expandable details for each finding
- Direct link to vulnerability details
- Approve/block merge based on findings
Approval Rules
Security Approvals:
Configure merge request approval rules based on security findings:
- Navigate to: Settings > Merge Requests > Approval Rules
- Create rule: "Security Approval"
- Configure conditions:
- Require approval if critical/high vulnerabilities detected
- Specify approvers (security team)
- Number of approvals required
Example Rule:
Rule Name: Security Team Approval
Conditions:
- Critical or High severity vulnerabilities detected
- Any security scanner finds new issues
Approvers:
- @security-team
Approvals Required: 1
Blocking Merges:
Use Scan Result Policies to automatically block merges:
# .gitlab/scan-result-policy.yml scan_result_policy: - name: "Block Critical Vulnerabilities" enabled: true rules: - type: scan_finding branches: - main - production scanners: - sast - dependency_scanning - container_scanning severity_levels: - critical vulnerabilities_allowed: 0 actions: - type: require_approval approvals_required: 1 approvers: - @security-team
Developer Workflow
Handling Security Findings in MRs:
-
Create Merge Request
- Push changes to feature branch
- Create MR to main branch
- Pipeline runs security scans
-
Review Security Findings
- Check MR widget for vulnerabilities
- Review severity and details
- Determine if introduced by your changes
-
Remediate or Justify
- Fix real vulnerabilities in MR
- Dismiss false positives with explanation
- Request security team review if needed
-
Get Approval
- Address all blocking vulnerabilities
- Obtain security team approval if required
- Merge once approved
Example Workflow:
1. Push feature branch
2. Create MR: "feat: add user search API"
3. Pipeline runs, SAST detects SQL injection
4. Review finding: Real vulnerability in new code
5. Fix vulnerability: Use parameterized queries
6. Push fix to same MR
7. Pipeline runs again, vulnerability resolved
8. MR approved and merged
Advanced Features
False Positive Detection (GitLab Duo)
Ultimate with GitLab Duo Add-on:
GitLab Duo provides automatic false positive detection:
- Runs after each security scan
- Analyzes vulnerability context
- Provides confidence score (0-100%)
- Explains reasoning for assessment
Example Output:
Vulnerability: Hardcoded Secret in config.js
Severity: High
Confidence Score: 25% (Low Confidence)
Assessment:
This appears to be a false positive. The flagged string "API_KEY"
is actually a constant name used for environment variable lookup,
not a hardcoded secret. The actual value is retrieved from
process.env.API_KEY at runtime.
Recommendation: Dismiss as False Positive
Vulnerability Tracking
Advanced Vulnerability Tracking (Ultimate):
GitLab's proprietary technology tracks vulnerabilities as they move through the codebase:
- Tracks same vulnerability across file moves
- Recognizes vulnerability after refactoring
- Maintains history even with code changes
- Prevents duplicate vulnerability entries
Example:
Vulnerability: XSS in user_profile.rb
First Detected: 2025-12-01
History:
- 2025-12-01: Detected in app/controllers/user_profile.rb:42
- 2025-12-15: File moved to app/controllers/users/profile.rb:42
- 2026-01-05: Code refactored, still present at line 58
- 2026-01-08: Still detected (not fixed)
GitLab tracks this as the same vulnerability across all changes.
Automated Remediation
GitLab Duo Code Suggestions:
For some vulnerabilities, GitLab Duo can suggest automated fixes:
- Open vulnerability details
- Click "Suggest Fix" (if available)
- Review AI-generated remediation code
- Apply suggestion or edit as needed
- Create MR with fix
Dependency Update Automation:
Configure automatic dependency updates:
- Enable Dependency Scanning
- Configure auto-update bot (Renovate, Dependabot)
- Bot creates MRs for vulnerable dependencies
- Review and merge automated updates
Reporting and Metrics
Exporting Vulnerabilities
CSV Export:
- Navigate to Vulnerability Report or Security Dashboard
- Apply desired filters
- Click "Export as CSV"
- Download file with all visible vulnerabilities
CSV Fields:
- Title
- Severity
- Status
- Scanner
- Location
- Identifiers (CVE, CWE)
- First Detected
- Last Detected
API Export:
Use GitLab API for programmatic access:
# Get vulnerabilities for project curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.com/api/v4/projects/123/vulnerabilities" # Filter by severity curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.com/api/v4/projects/123/vulnerabilities?severity=high" # Get vulnerability details curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.com/api/v4/projects/123/vulnerabilities/456"
Metrics and KPIs
Key Metrics:
- Total Vulnerabilities - Current vulnerability count
- New Vulnerabilities - Detected in time period
- Resolved Vulnerabilities - Fixed in time period
- Mean Time to Remediation (MTTR) - Average time from detection to resolution
- Vulnerability Backlog - Total unresolved vulnerabilities
- Critical/High Backlog - High-priority unresolved issues
Tracking Progress:
Monthly Security Metrics - December 2025
Total Vulnerabilities: 45
Critical: 2
High: 8
Medium: 20
Low: 15
New This Month: 12
Resolved This Month: 18
Net Change: -6 (improvement)
Mean Time to Remediation: 14 days
Critical: 2 days
High: 7 days
Medium: 21 days
Low: 45 days
Backlog Trend: Decreasing (down 13% from last month)
Compliance Reporting
Security Reports for Audits:
Generate compliance reports:
- Navigate to Security Dashboard
- Apply filters (date range, severity, etc.)
- Export CSV
- Include in compliance documentation
Evidence Collection:
For compliance frameworks (SOC 2, GDPR, HIPAA):
- Vulnerability detection evidence
- Remediation timeline documentation
- Approval and sign-off records
- Trend analysis showing improvement
- Policy compliance verification
Best Practices
Triage Process
- Daily Review - Check Security Dashboard daily for new findings
- Prioritize Critical/High - Address severe vulnerabilities first
- Verify Findings - Confirm vulnerabilities are real before spending effort
- Fast Response - Fix critical issues within 24-48 hours
- Track Progress - Monitor remediation metrics weekly
Team Coordination
- Clear Ownership - Assign vulnerabilities to appropriate team members
- Set Due Dates - Establish realistic remediation timelines
- Regular Check-ins - Review vulnerability backlog in team meetings
- Knowledge Sharing - Document remediation approaches for similar issues
- Celebrate Progress - Recognize teams that improve security posture
Automation
- Enable All Scanners - Run comprehensive security scans on every commit
- Automated Policies - Use scan execution and result policies
- Auto-update Dependencies - Configure bots for dependency updates
- Scheduled DAST - Run expensive scans on schedule
- Integration - Connect to external tools (Jira, Slack, etc.)
Documentation
- Document Dismissals - Always explain why vulnerabilities are dismissed
- Track Decisions - Record security decisions in comments
- Share Solutions - Document remediation approaches for team
- Maintain History - Keep vulnerability history for compliance
- Regular Reports - Share security metrics with stakeholders
Troubleshooting
Common Issues
Vulnerabilities not appearing in Dashboard:
- Verify pipeline jobs completed successfully
- Check that scanner artifacts were generated
- Ensure proper GitLab tier (Ultimate required)
- Verify project is included in group dashboard
False positives:
- Use dismissal workflow with detailed explanation
- Enable GitLab Duo false positive detection
- Configure scanner exclusions for known false positive patterns
- Review analyzer configuration
Duplicate vulnerabilities:
- Advanced Vulnerability Tracking should prevent this
- Check if multiple scanners detect same issue
- Review vulnerability identifiers (may be different aspects)
Resolved vulnerabilities still showing:
- Wait for next pipeline scan to confirm fix
- Verify fix actually addresses the vulnerability
- Check if vulnerability exists in different location
- Review vulnerability tracking history
References
Next Steps
- Security Scanning - Configure security scanners
- Security Policies - Enforce security requirements
- Compliance - Meet regulatory requirements