Fix NoMethodError when security report has no scanner information
Summary
The Security::StoreScanService raises a NoMethodError when processing security reports that lack scanner information, causing scan ingestion to fail.
Sentry Error: https://new-sentry.gitlab.net/organizations/gitlab/issues/3010954
Error Details
NoMethodError: undefined method `external_id' for nil:NilClass (NoMethodError)
project.vulnerability_scanners.safe_find_or_create_by!(external_id: security_report.scanner.external_id) do |scanner|
^^^^^^^^^^^^
from security/store_scan_service.rb:154:in `vulnerability_scanner'
from security/store_scan_service.rb:97:in `store_findings'
from security/store_scan_service.rb:38:in `execute'
Root Cause
In ee/app/services/security/store_scan_service.rb, the vulnerability_scanner method (line 154) attempts to access security_report.scanner.external_id without checking if security_report.scanner is nil.
Security reports can have missing scanner information when:
- The report JSON lacks both top-level scanner data (
scan.scanner) and finding-level scanner data - The scanner data is malformed and fails validation during parsing
The parser in lib/gitlab/ci/parsers/security/common.rb only sets report.scanner if valid scanner data exists, otherwise it remains nil.
Proposed Solution
1. Add nil check in vulnerability_scanner method
def vulnerability_scanner
return unless security_report.scanner
project.vulnerability_scanners.safe_find_or_create_by!(external_id: security_report.scanner.external_id) do |scanner|
scanner.assign_attributes(security_report.scanner.to_hash)
end
end
2. Handle nil scanner in store_findings method
def store_findings
scanner = vulnerability_scanner
if scanner.nil?
mark_scan_as_failed!
Gitlab::AppLogger.warn(
message: "Security scan missing scanner information",
scan_id: security_scan.id,
report_type: security_report.type
)
return
end
StoreFindingsService.execute(security_scan, scanner, security_report, register_finding_keys).then do |result|
update_deduplicated_findings if result[:status] == :error && deduplicate_findings?
end
security_scan.succeeded!
rescue StandardError => error
mark_scan_as_failed!
Gitlab::ErrorTracking.track_exception(error)
end
Testing
Add test coverage in ee/spec/services/security/store_scan_service_spec.rb using the existing :sast_with_missing_scanner fixture (spec/fixtures/security_reports/master/gl-sast-missing-scanner.json).
The test should verify:
- No
NoMethodErroris raised - Scan is marked as
preparation_failed -
StoreFindingsServiceis not called - Processing error is added to the scan
- No vulnerability scanner record is created
- Error is tracked via
Gitlab::ErrorTracking
Impact
This bug prevents security scan ingestion for reports with missing scanner information, resulting in:
- Failed security scans not being recorded properly
- Missing vulnerability data in the vulnerability report
- Incomplete security posture visibility
Related Files
ee/app/services/security/store_scan_service.rbee/spec/services/security/store_scan_service_spec.rblib/gitlab/ci/parsers/security/common.rbspec/fixtures/security_reports/master/gl-sast-missing-scanner.json