Commit 0a718482 authored by Yevgeny Name's avatar Yevgeny Name

Add coverage fuzzing to security dashboard(backend)

This adds database support and graphql

Related MR https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36011
parent 497620d5
......@@ -12063,6 +12063,7 @@ The type of the security scanner.
"""
enum SecurityScannerType {
CONTAINER_SCANNING
COVERAGE_FUZZING
DAST
DEPENDENCY_SCANNING
SAST
......@@ -14937,7 +14938,7 @@ enum VulnerabilityIssueLinkType {
"""
Represents a vulnerability location. The fields with data will depend on the vulnerability report type
"""
union VulnerabilityLocation = VulnerabilityLocationContainerScanning | VulnerabilityLocationDast | VulnerabilityLocationDependencyScanning | VulnerabilityLocationSast | VulnerabilityLocationSecretDetection
union VulnerabilityLocation = VulnerabilityLocationContainerScanning | VulnerabilityLocationCoverageFuzzing | VulnerabilityLocationDast | VulnerabilityLocationDependencyScanning | VulnerabilityLocationSast | VulnerabilityLocationSecretDetection
"""
Represents the location of a vulnerability found by a container security scan
......@@ -14959,6 +14960,36 @@ type VulnerabilityLocationContainerScanning {
operatingSystem: String
}
"""
Represents the location of a vulnerability found by a Coverage Fuzzing scan
"""
type VulnerabilityLocationCoverageFuzzing {
"""
Number of the last relevant line in the vulnerable file
"""
endLine: String
"""
Path to the vulnerable file
"""
file: String
"""
Number of the first relevant line in the vulnerable file
"""
startLine: String
"""
Class containing the vulnerability
"""
vulnerableClass: String
"""
Method containing the vulnerability
"""
vulnerableMethod: String
}
"""
Represents the location of a vulnerability found by a DAST scan
"""
......
......@@ -35342,6 +35342,12 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "COVERAGE_FUZZING",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
......@@ -43978,6 +43984,11 @@
"name": "VulnerabilityLocationContainerScanning",
"ofType": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityLocationCoverageFuzzing",
"ofType": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityLocationDast",
......@@ -44055,6 +44066,89 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityLocationCoverageFuzzing",
"description": "Represents the location of a vulnerability found by a Coverage Fuzzing scan",
"fields": [
{
"name": "endLine",
"description": "Number of the last relevant line in the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "file",
"description": "Path to the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "startLine",
"description": "Number of the first relevant line in the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "vulnerableClass",
"description": "Class containing the vulnerability",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "vulnerableMethod",
"description": "Method containing the vulnerability",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityLocationDast",
......@@ -2246,6 +2246,18 @@ Represents the location of a vulnerability found by a container security scan
| `image` | String | Name of the vulnerable container image |
| `operatingSystem` | String | Operating system that runs on the vulnerable container image |
## VulnerabilityLocationCoverageFuzzing
Represents the location of a vulnerability found by a Coverage Fuzzing scan
| Name | Type | Description |
| --- | ---- | ---------- |
| `endLine` | String | Number of the last relevant line in the vulnerable file |
| `file` | String | Path to the vulnerable file |
| `startLine` | String | Number of the first relevant line in the vulnerable file |
| `vulnerableClass` | String | Class containing the vulnerability |
| `vulnerableMethod` | String | Method containing the vulnerability |
## VulnerabilityLocationDast
Represents the location of a vulnerability found by a DAST scan
......
......@@ -15,7 +15,7 @@ module EE
before_action :whitelist_query_limiting_ee_merge, only: [:merge]
before_action :authorize_read_pipeline!, only: [:container_scanning_reports, :dependency_scanning_reports,
:license_scanning_reports,
:sast_reports, :secret_detection_reports, :dast_reports, :metrics_reports]
:sast_reports, :secret_detection_reports, :dast_reports, :metrics_reports, :coverage_fuzzing_reports]
feature_category :container_scanning, only: [:container_scanning_reports]
feature_category :dependency_scanning, only: [:dependency_scanning_reports]
......@@ -54,6 +54,10 @@ module EE
reports_response(merge_request.compare_metrics_reports)
end
def coverage_fuzzing_reports
reports_response(merge_request.compare_coverage_fuzzing_reports(current_user))
end
private
def whitelist_query_limiting_ee_merge
......
......@@ -3,7 +3,7 @@
# Security::JobsFinder
#
# Abstract class encapsulating common logic for finding jobs (builds) that are related to the Secure products
# SAST, DAST, Dependency Scanning, Container Scanning and License Management
# SAST, DAST, Dependency Scanning, Container Scanning and License Management, Coverage Fuzzing
#
# Arguments:
# params:
......@@ -15,7 +15,7 @@ module Security
attr_reader :pipeline
def self.allowed_job_types
# Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management]
# Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management, :coverage_fuzzing]
raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types'
end
......
......@@ -13,7 +13,7 @@
module Security
class SecurityJobsFinder < JobsFinder
def self.allowed_job_types
[:sast, :dast, :dependency_scanning, :container_scanning, :secret_detection]
[:sast, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing]
end
end
end
# frozen_string_literal: true
module Types
module VulnerabilityLocation
# rubocop: disable Graphql/AuthorizeTypes
class CoverageFuzzingType < BaseObject
graphql_name 'VulnerabilityLocationCoverageFuzzing'
description 'Represents the location of a vulnerability found by a Coverage Fuzzing scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability',
hash_key: :class
field :end_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the last relevant line in the vulnerable file'
field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability',
hash_key: :method
field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file'
end
end
end
......@@ -11,7 +11,8 @@ module Types
VulnerabilityLocation::DependencyScanningType,
VulnerabilityLocation::DastType,
VulnerabilityLocation::SastType,
VulnerabilityLocation::SecretDetectionType
VulnerabilityLocation::SecretDetectionType,
VulnerabilityLocation::CoverageFuzzingType
def self.resolve_type(object, context)
case object[:report_type]
......@@ -25,6 +26,8 @@ module Types
VulnerabilityLocation::SastType
when 'secret_detection'
VulnerabilityLocation::SecretDetectionType
when 'coverage_fuzzing'
VulnerabilityLocation::CoverageFuzzingType
else
raise UnexpectedReportType, "Report type must be one of #{::Vulnerabilities::Occurrence::REPORT_TYPES.keys}"
end
......
......@@ -58,7 +58,7 @@ module EE
with_file_types(METRICS_REPORT_FILE_TYPES)
end
scope :coverage_fuzzing, -> do
scope :coverage_fuzzing_reports, -> do
with_file_types(COVERAGE_FUZZING_REPORT_TYPES)
end
end
......
......@@ -159,7 +159,8 @@ module EE
container_scanning: report_type_enabled?(:container_scanning),
dast: report_type_enabled?(:dast),
dependency_scanning: report_type_enabled?(:dependency_scanning),
license_scanning: report_type_enabled?(:license_scanning)
license_scanning: report_type_enabled?(:license_scanning),
coverage_fuzzing: report_type_enabled?(:coverage_fuzzing)
}
end
......@@ -233,6 +234,16 @@ module EE
compare_reports(::Ci::CompareMetricsReportsService)
end
def has_coverage_fuzzing_reports?
!!actual_head_pipeline&.has_reports?(::Ci::JobArtifact.coverage_fuzzing_reports)
end
def compare_coverage_fuzzing_reports(current_user)
return missing_report_error("coverage fuzzing") unless has_coverage_fuzzing_reports?
compare_reports(::Ci::CompareSecurityReportsService, current_user, 'coverage_fuzzing')
end
def synchronize_approval_rules_from_target_project
return if merged?
......
......@@ -21,12 +21,7 @@ module EE
def expose_security_dashboard?
return false unless can?(current_user, :read_vulnerability, pipeline.project)
batch_lookup_report_artifact_for_file_type(:sast) ||
batch_lookup_report_artifact_for_file_type(:secret_detection) ||
batch_lookup_report_artifact_for_file_type(:dependency_scanning) ||
batch_lookup_report_artifact_for_file_type(:dast) ||
batch_lookup_report_artifact_for_file_type(:container_scanning) ||
batch_lookup_report_artifact_for_file_type(:coverage_fuzzing)
Ci::JobArtifact::SECURITY_REPORT_FILE_TYPES.any? { |file_type| batch_lookup_report_artifact_for_file_type(file_type.to_sym) }
end
def degradation_threshold(file_type)
......
......@@ -12,6 +12,7 @@
window.gl.mrWidgetData.dast_help_path = '#{help_page_path("user/application_security/dast/index")}';
window.gl.mrWidgetData.dependency_scanning_help_path = '#{help_page_path("user/application_security/dependency_scanning/index")}';
window.gl.mrWidgetData.secret_scanning_help_path = '#{help_page_path('user/application_security/sast/index', anchor: 'secret-detection')}';
window.gl.mrWidgetData.coverage_fuzzinghelp_path = '#{help_page_path("user/application_security/coverage_fuzzing/index")}';
window.gl.mrWidgetData.vulnerability_feedback_help_path = '#{help_page_path("user/application_security/index")}';
window.gl.mrWidgetData.visual_review_app_available = '#{@project.feature_available?(:visual_review_app)}' === 'true';
window.gl.mrWidgetData.license_scanning_comparison_path = '#{license_scanning_reports_project_merge_request_path(@project, @merge_request) if @project.feature_available?(:license_scanning)}'
......
---
title: Add coverage fuzzing to security dashboard(backend)
merge_request: 37173
author:
type: added
......@@ -6,7 +6,7 @@ FactoryBot.define do
failure_reason { Ci::Build.failure_reasons[:protected_environment_failure] }
end
%i[codequality container_scanning dast dependency_scanning license_management license_scanning performance browser_performance load_performance sast secret_detection].each do |report_type|
%i[codequality container_scanning dast dependency_scanning license_management license_scanning performance browser_performance load_performance sast secret_detection coverage_fuzzing].each do |report_type|
trait "legacy_#{report_type}".to_sym do
success
artifacts
......
......@@ -32,7 +32,7 @@
},
"category": {
"type": "string",
"enum": ["sast", "dependency_scanning", "container_scanning", "dast"]
"enum": ["sast", "dependency_scanning", "container_scanning", "dast", "coverage_fuzzing"]
},
"project_fingerprint": { "type": "string" },
"branch": { "type": ["string", "null"] },
......
......@@ -30,6 +30,7 @@
"auto_fix_container_scanning": true,
"auto_fix_dast": true,
"auto_fix_dependency_scanning": false,
"auto_fix_sast": false
"auto_fix_sast": false,
"auto_fix_coverage_fuzzing": false
}
}
{"security_setting": {"auto_fix_container_scanning": true,"auto_fix_dast": true,"auto_fix_dependency_scanning": false,"auto_fix_sast": false}}
{"security_setting": {"auto_fix_container_scanning": true,"auto_fix_dast": true,"auto_fix_dependency_scanning": false,"auto_fix_sast": false, "auto_fix_coverage": false}}
......@@ -18,7 +18,8 @@ RSpec.describe Resolvers::SecurityReportSummaryResolver do
dast: [:scanned_resources_count, :vulnerabilities_count],
sast: [:scanned_resources_count, :vulnerabilities_count],
container_scanning: [:scanned_resources_count, :vulnerabilities_count],
dependency_scanning: [:scanned_resources_count, :vulnerabilities_count]
dependency_scanning: [:scanned_resources_count, :vulnerabilities_count],
coverage_fuzzing: [:scanned_resources_count, :vulnerabilities_count]
}
end
......
......@@ -66,7 +66,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: false),
security_scan(:secret_detection, configured: true)
security_scan(:secret_detection, configured: true),
security_scan(:coverage_fuzzing, configured: false)
)
end
end
......@@ -87,7 +88,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: false),
security_scan(:secret_detection, configured: false)
security_scan(:secret_detection, configured: false),
security_scan(:coverage_fuzzing, configured: false)
)
end
end
......@@ -115,7 +117,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: false),
security_scan(:secret_detection, configured: true)
security_scan(:secret_detection, configured: true),
security_scan(:coverage_fuzzing, configured: false)
)
end
......@@ -130,7 +133,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: false),
security_scan(:secret_detection, configured: false)
security_scan(:secret_detection, configured: false),
security_scan(:coverage_fuzzing, configured: false)
)
end
......@@ -151,7 +155,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: false),
security_scan(:secret_detection, configured: false)
security_scan(:secret_detection, configured: false),
security_scan(:coverage_fuzzing, configured: false)
)
end
......@@ -164,7 +169,8 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
security_scan(:container_scanning, configured: false),
security_scan(:dependency_scanning, configured: false),
security_scan(:license_scanning, configured: true),
security_scan(:secret_detection, configured: true)
security_scan(:secret_detection, configured: true),
security_scan(:coverage_fuzzing, configured: false)
)
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment