Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
commit6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch)
treedc4d20fe6064752c0bd323187252c77e0a89144b /lib/gitlab/ci
parent9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff)
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'lib/gitlab/ci')
-rw-r--r--lib/gitlab/ci/ansi2html.rb10
-rw-r--r--lib/gitlab/ci/ansi2json/parser.rb10
-rw-r--r--lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb61
-rw-r--r--lib/gitlab/ci/build/context/build.rb13
-rw-r--r--lib/gitlab/ci/build/rules/rule/clause/exists.rb2
-rw-r--r--lib/gitlab/ci/config/entry/current_variables.rb49
-rw-r--r--lib/gitlab/ci/config/entry/environment.rb2
-rw-r--r--lib/gitlab/ci/config/entry/image.rb7
-rw-r--r--lib/gitlab/ci/config/entry/imageable.rb5
-rw-r--r--lib/gitlab/ci/config/entry/legacy_variables.rb46
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb4
-rw-r--r--lib/gitlab/ci/config/entry/root.rb3
-rw-r--r--lib/gitlab/ci/config/entry/service.rb9
-rw-r--r--lib/gitlab/ci/config/entry/variable.rb98
-rw-r--r--lib/gitlab/ci/config/entry/variables.rb40
-rw-r--r--lib/gitlab/ci/jwt_v2.rb2
-rw-r--r--lib/gitlab/ci/parsers/sbom/cyclonedx.rb14
-rw-r--r--lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb10
-rw-r--r--lib/gitlab/ci/parsers/security/common.rb24
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schema_validator.rb16
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/cluster-image-scanning-report-format.json977
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/container-scanning-report-format.json911
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/coverage-fuzzing-report-format.json874
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dast-report-format.json1287
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dependency-scanning-report-format.json968
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/sast-report-format.json869
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/secret-detection-report-format.json892
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json946
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json880
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json836
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json1241
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json944
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json831
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json854
-rw-r--r--lib/gitlab/ci/parsers/test/junit.rb4
-rw-r--r--lib/gitlab/ci/pipeline/chain/assign_partition.rb31
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb12
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content.rb23
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/source.rb1
-rw-r--r--lib/gitlab/ci/pipeline/chain/ensure_environments.rb4
-rw-r--r--lib/gitlab/ci/pipeline/chain/validate/external.rb9
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb4
-rw-r--r--lib/gitlab/ci/pipeline/seed/environment.rb16
-rw-r--r--lib/gitlab/ci/pipeline/seed/stage.rb3
-rw-r--r--lib/gitlab/ci/processable_object_hierarchy.rb33
-rw-r--r--lib/gitlab/ci/project_config.rb52
-rw-r--r--lib/gitlab/ci/project_config/auto_devops.rb28
-rw-r--r--lib/gitlab/ci/project_config/bridge.rb19
-rw-r--r--lib/gitlab/ci/project_config/external_project.rb45
-rw-r--r--lib/gitlab/ci/project_config/parameter.rb21
-rw-r--r--lib/gitlab/ci/project_config/remote.rb21
-rw-r--r--lib/gitlab/ci/project_config/repository.rb32
-rw-r--r--lib/gitlab/ci/project_config/source.rb41
-rw-r--r--lib/gitlab/ci/reports/coverage_report_generator.rb2
-rw-r--r--lib/gitlab/ci/reports/sbom/component.rb8
-rw-r--r--lib/gitlab/ci/reports/sbom/report.rb4
-rw-r--r--lib/gitlab/ci/reports/sbom/source.rb8
-rw-r--r--lib/gitlab/ci/reports/security/scanner.rb4
-rw-r--r--lib/gitlab/ci/status/build/failed.rb4
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml244
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/License-Scanning.latest.gitlab-ci.yml48
-rw-r--r--lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml58
-rw-r--r--lib/gitlab/ci/templates/Jobs/SAST.latest.gitlab-ci.yml90
-rw-r--r--lib/gitlab/ci/templates/Katalon.gitlab-ci.yml65
-rw-r--r--lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml6
-rw-r--r--lib/gitlab/ci/templates/Security/Container-Scanning.latest.gitlab-ci.yml68
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/npm.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/trace.rb11
-rw-r--r--lib/gitlab/ci/variables/builder.rb4
-rw-r--r--lib/gitlab/ci/variables/helpers.rb28
-rw-r--r--lib/gitlab/ci/yaml_processor/feature_flags.rb27
-rw-r--r--lib/gitlab/ci/yaml_processor/result.rb10
76 files changed, 14500 insertions, 333 deletions
diff --git a/lib/gitlab/ci/ansi2html.rb b/lib/gitlab/ci/ansi2html.rb
index 10233cf4228..2ab702aa4f9 100644
--- a/lib/gitlab/ci/ansi2html.rb
+++ b/lib/gitlab/ci/ansi2html.rb
@@ -19,11 +19,11 @@ module Gitlab
}.freeze
STYLE_SWITCHES = {
- bold: 0x01,
- italic: 0x02,
- underline: 0x04,
- conceal: 0x08,
- cross: 0x10
+ bold: 0x01,
+ italic: 0x02,
+ underline: 0x04,
+ conceal: 0x08,
+ cross: 0x10
}.freeze
def self.convert(ansi, state = nil)
diff --git a/lib/gitlab/ci/ansi2json/parser.rb b/lib/gitlab/ci/ansi2json/parser.rb
index 79b42a5f5bf..fdd49df1e24 100644
--- a/lib/gitlab/ci/ansi2json/parser.rb
+++ b/lib/gitlab/ci/ansi2json/parser.rb
@@ -20,11 +20,11 @@ module Gitlab
}.freeze
STYLE_SWITCHES = {
- bold: 0x01,
- italic: 0x02,
- underline: 0x04,
- conceal: 0x08,
- cross: 0x10
+ bold: 0x01,
+ italic: 0x02,
+ underline: 0x04,
+ conceal: 0x08,
+ cross: 0x10
}.freeze
def self.bold?(mask)
diff --git a/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb b/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb
deleted file mode 100644
index 690a47097c6..00000000000
--- a/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Ci
- module Build
- module Artifacts
- module Adapters
- class ZipStream
- MAX_DECOMPRESSED_SIZE = 100.megabytes
- MAX_FILES_PROCESSED = 50
-
- attr_reader :stream
-
- InvalidStreamError = Class.new(StandardError)
-
- def initialize(stream)
- raise InvalidStreamError, "Stream is required" unless stream
-
- @stream = stream
- @files_processed = 0
- end
-
- def each_blob
- Zip::InputStream.open(stream) do |zio|
- while entry = zio.get_next_entry
- break if at_files_processed_limit?
- next unless should_process?(entry)
-
- @files_processed += 1
-
- yield entry.get_input_stream.read
- end
- end
- end
-
- private
-
- def should_process?(entry)
- file?(entry) && !too_large?(entry)
- end
-
- def file?(entry)
- # Check the file name as a workaround for incorrect
- # file type detection when using InputStream
- # https://github.com/rubyzip/rubyzip/issues/533
- entry.file? && !entry.name.end_with?('/')
- end
-
- def too_large?(entry)
- entry.size > MAX_DECOMPRESSED_SIZE
- end
-
- def at_files_processed_limit?
- @files_processed >= MAX_FILES_PROCESSED
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/ci/build/context/build.rb b/lib/gitlab/ci/build/context/build.rb
index 641aa71fb4e..a1a8e9288c7 100644
--- a/lib/gitlab/ci/build/context/build.rb
+++ b/lib/gitlab/ci/build/context/build.rb
@@ -32,7 +32,18 @@ module Gitlab
end
def build_attributes
- attributes.merge(pipeline_attributes)
+ attributes.merge(pipeline_attributes, ci_stage_attributes)
+ end
+
+ def ci_stage_attributes
+ {
+ ci_stage: ::Ci::Stage.new(
+ name: attributes[:stage],
+ position: attributes[:stage_idx],
+ pipeline: pipeline_attributes[:pipeline],
+ project: pipeline_attributes[:project]
+ )
+ }
end
end
end
diff --git a/lib/gitlab/ci/build/rules/rule/clause/exists.rb b/lib/gitlab/ci/build/rules/rule/clause/exists.rb
index e2b54797dc8..aebd81e7b07 100644
--- a/lib/gitlab/ci/build/rules/rule/clause/exists.rb
+++ b/lib/gitlab/ci/build/rules/rule/clause/exists.rb
@@ -24,7 +24,7 @@ module Gitlab
private
def worktree_paths(context)
- return unless context.project
+ return [] unless context.project
if @top_level_only
context.top_level_worktree_paths
diff --git a/lib/gitlab/ci/config/entry/current_variables.rb b/lib/gitlab/ci/config/entry/current_variables.rb
new file mode 100644
index 00000000000..3b6721ec92d
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/current_variables.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents CI/CD variables.
+ # The class will be renamed to `Variables` when removing the FF `ci_variables_refactoring_to_variable`.
+ #
+ class CurrentVariables < ::Gitlab::Config::Entry::ComposableHash
+ include ::Gitlab::Config::Entry::Validatable
+
+ validations do
+ validates :config, type: Hash
+ end
+
+ # Enable these lines when removing the FF `ci_variables_refactoring_to_variable`
+ # and renaming this class to `Variables`.
+ # def self.default(**)
+ # {}
+ # end
+
+ def value
+ @entries.to_h do |key, entry|
+ [key.to_s, entry.value]
+ end
+ end
+
+ def value_with_data
+ @entries.to_h do |key, entry|
+ [key.to_s, entry.value_with_data]
+ end
+ end
+
+ private
+
+ def composable_class(_name, _config)
+ Entry::Variable
+ end
+
+ def composable_metadata
+ { allowed_value_data: opt(:allowed_value_data) }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/environment.rb b/lib/gitlab/ci/config/entry/environment.rb
index 96ba3553b46..a727da87308 100644
--- a/lib/gitlab/ci/config/entry/environment.rb
+++ b/lib/gitlab/ci/config/entry/environment.rb
@@ -54,7 +54,7 @@ module Gitlab
validates :on_stop, type: String, allow_nil: true
validates :kubernetes, type: Hash, allow_nil: true
- validates :auto_stop_in, duration: { parser: ::Gitlab::Ci::Build::DurationParser }, allow_nil: true
+ validates :auto_stop_in, type: String, allow_nil: true
end
end
diff --git a/lib/gitlab/ci/config/entry/image.rb b/lib/gitlab/ci/config/entry/image.rb
index 613f7ff3370..84e31ca1fc6 100644
--- a/lib/gitlab/ci/config/entry/image.rb
+++ b/lib/gitlab/ci/config/entry/image.rb
@@ -11,10 +11,7 @@ module Gitlab
include ::Gitlab::Ci::Config::Entry::Imageable
validations do
- validates :config, allowed_keys: IMAGEABLE_ALLOWED_KEYS,
- if: :ci_docker_image_pull_policy_enabled?
- validates :config, allowed_keys: IMAGEABLE_LEGACY_ALLOWED_KEYS,
- unless: :ci_docker_image_pull_policy_enabled?
+ validates :config, allowed_keys: IMAGEABLE_ALLOWED_KEYS
end
def value
@@ -25,7 +22,7 @@ module Gitlab
name: @config[:name],
entrypoint: @config[:entrypoint],
ports: (ports_value if ports_defined?),
- pull_policy: (ci_docker_image_pull_policy_enabled? ? pull_policy_value : nil)
+ pull_policy: pull_policy_value
}.compact
else
{}
diff --git a/lib/gitlab/ci/config/entry/imageable.rb b/lib/gitlab/ci/config/entry/imageable.rb
index f045ee3d549..1aecfee9ab9 100644
--- a/lib/gitlab/ci/config/entry/imageable.rb
+++ b/lib/gitlab/ci/config/entry/imageable.rb
@@ -13,7 +13,6 @@ module Gitlab
include ::Gitlab::Config::Entry::Configurable
IMAGEABLE_ALLOWED_KEYS = %i[name entrypoint ports pull_policy].freeze
- IMAGEABLE_LEGACY_ALLOWED_KEYS = %i[name entrypoint ports].freeze
included do
include ::Gitlab::Config::Entry::Validatable
@@ -47,10 +46,6 @@ module Gitlab
opt(:with_image_ports)
end
- def ci_docker_image_pull_policy_enabled?
- ::Feature.enabled?(:ci_docker_image_pull_policy)
- end
-
def skip_config_hash_validation?
true
end
diff --git a/lib/gitlab/ci/config/entry/legacy_variables.rb b/lib/gitlab/ci/config/entry/legacy_variables.rb
new file mode 100644
index 00000000000..5379f707537
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/legacy_variables.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents environment variables.
+ # This is legacy implementation and will be removed with the FF `ci_variables_refactoring_to_variable`.
+ #
+ class LegacyVariables < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+
+ ALLOWED_VALUE_DATA = %i[value description].freeze
+
+ validations do
+ validates :config, variables: { allowed_value_data: ALLOWED_VALUE_DATA }, if: :use_value_data?
+ validates :config, variables: true, unless: :use_value_data?
+ end
+
+ def value
+ @config.to_h { |key, value| [key.to_s, expand_value(value)[:value]] }
+ end
+
+ def value_with_data
+ @config.to_h { |key, value| [key.to_s, expand_value(value)] }
+ end
+
+ def use_value_data?
+ opt(:use_value_data)
+ end
+
+ private
+
+ def expand_value(value)
+ if value.is_a?(Hash)
+ { value: value[:value].to_s, description: value[:description] }.compact
+ else
+ { value: value.to_s }
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index 78794f524f4..2d2032b1d8c 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -29,7 +29,7 @@ module Gitlab
in: %i[only except start_in],
message: 'key may not be used with `rules`'
},
- if: :has_rules?
+ if: :has_rules?
with_options allow_nil: true do
validates :extends, array_of_strings_or_string: true
@@ -120,7 +120,7 @@ module Gitlab
stage: stage_value,
extends: extends,
rules: rules_value,
- job_variables: variables_value.to_h,
+ job_variables: variables_entry.value_with_data,
root_variables_inheritance: root_variables_inheritance,
only: only_value,
except: except_value,
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index ff11c757dfa..57e89bd7bc5 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -48,9 +48,10 @@ module Gitlab
description: 'Script that will be executed after each job.',
reserved: true
+ # use_value_data will be removed with the FF ci_variables_refactoring_to_variable
entry :variables, Entry::Variables,
description: 'Environment variables that will be used.',
- metadata: { use_value_data: true },
+ metadata: { use_value_data: true, allowed_value_data: %i[value description] },
reserved: true
entry :stages, Entry::Stages,
diff --git a/lib/gitlab/ci/config/entry/service.rb b/lib/gitlab/ci/config/entry/service.rb
index 0e19447dff8..4b3a9990df4 100644
--- a/lib/gitlab/ci/config/entry/service.rb
+++ b/lib/gitlab/ci/config/entry/service.rb
@@ -11,14 +11,9 @@ module Gitlab
include ::Gitlab::Ci::Config::Entry::Imageable
ALLOWED_KEYS = %i[command alias variables].freeze
- LEGACY_ALLOWED_KEYS = %i[command alias variables].freeze
validations do
- validates :config, allowed_keys: ALLOWED_KEYS + IMAGEABLE_ALLOWED_KEYS,
- if: :ci_docker_image_pull_policy_enabled?
- validates :config, allowed_keys: LEGACY_ALLOWED_KEYS + IMAGEABLE_LEGACY_ALLOWED_KEYS,
- unless: :ci_docker_image_pull_policy_enabled?
-
+ validates :config, allowed_keys: ALLOWED_KEYS + IMAGEABLE_ALLOWED_KEYS
validates :command, array_of_strings: true, allow_nil: true
validates :alias, type: String, allow_nil: true
validates :alias, type: String, presence: true, unless: ->(record) { record.ports.blank? }
@@ -43,7 +38,7 @@ module Gitlab
{ name: @config }
elsif hash?
@config.merge(
- pull_policy: (pull_policy_value if ci_docker_image_pull_policy_enabled?)
+ pull_policy: pull_policy_value
).compact
else
{}
diff --git a/lib/gitlab/ci/config/entry/variable.rb b/lib/gitlab/ci/config/entry/variable.rb
new file mode 100644
index 00000000000..253888aadeb
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/variable.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents a CI/CD variable.
+ #
+ class Variable < ::Gitlab::Config::Entry::Simplifiable
+ strategy :SimpleVariable, if: -> (config) { SimpleVariable.applies_to?(config) }
+ strategy :ComplexVariable, if: -> (config) { ComplexVariable.applies_to?(config) }
+
+ class SimpleVariable < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+
+ class << self
+ def applies_to?(config)
+ Gitlab::Config::Entry::Validators::AlphanumericValidator.validate(config)
+ end
+ end
+
+ validations do
+ validates :key, alphanumeric: true
+ validates :config, alphanumeric: true
+ end
+
+ def value
+ @config.to_s
+ end
+
+ def value_with_data
+ { value: @config.to_s }
+ end
+ end
+
+ class ComplexVariable < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+
+ class << self
+ def applies_to?(config)
+ config.is_a?(Hash)
+ end
+ end
+
+ validations do
+ validates :key, alphanumeric: true
+ validates :config_value, alphanumeric: true, allow_nil: false, if: :config_value_defined?
+ validates :config_description, alphanumeric: true, allow_nil: false, if: :config_description_defined?
+
+ validate do
+ allowed_value_data = Array(opt(:allowed_value_data))
+
+ if allowed_value_data.any?
+ extra_keys = config.keys - allowed_value_data
+
+ errors.add(:config, "uses invalid data keys: #{extra_keys.join(', ')}") if extra_keys.present?
+ else
+ errors.add(:config, "must be a string")
+ end
+ end
+ end
+
+ def value
+ config_value.to_s
+ end
+
+ def value_with_data
+ { value: value, description: config_description }.compact
+ end
+
+ def config_value
+ @config[:value]
+ end
+
+ def config_description
+ @config[:description]
+ end
+
+ def config_value_defined?
+ config.key?(:value)
+ end
+
+ def config_description_defined?
+ config.key?(:description)
+ end
+ end
+
+ class UnknownStrategy < ::Gitlab::Config::Entry::Node
+ def errors
+ ["variable definition must be either a string or a hash"]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/variables.rb b/lib/gitlab/ci/config/entry/variables.rb
index efb469ee32a..0284958d9d4 100644
--- a/lib/gitlab/ci/config/entry/variables.rb
+++ b/lib/gitlab/ci/config/entry/variables.rb
@@ -5,43 +5,21 @@ module Gitlab
class Config
module Entry
##
- # Entry that represents environment variables.
+ # Entry that represents CI/CD variables.
+ # CurrentVariables will be renamed to this class when removing the FF `ci_variables_refactoring_to_variable`.
#
- class Variables < ::Gitlab::Config::Entry::Node
- include ::Gitlab::Config::Entry::Validatable
-
- ALLOWED_VALUE_DATA = %i[value description].freeze
-
- validations do
- validates :config, variables: { allowed_value_data: ALLOWED_VALUE_DATA }, if: :use_value_data?
- validates :config, variables: true, unless: :use_value_data?
- end
-
- def value
- @config.to_h { |key, value| [key.to_s, expand_value(value)[:value]] }
+ class Variables
+ def self.new(...)
+ if YamlProcessor::FeatureFlags.enabled?(:ci_variables_refactoring_to_variable)
+ CurrentVariables.new(...)
+ else
+ LegacyVariables.new(...)
+ end
end
def self.default(**)
{}
end
-
- def value_with_data
- @config.to_h { |key, value| [key.to_s, expand_value(value)] }
- end
-
- def use_value_data?
- opt(:use_value_data)
- end
-
- private
-
- def expand_value(value)
- if value.is_a?(Hash)
- { value: value[:value].to_s, description: value[:description] }
- else
- { value: value.to_s, description: nil }
- end
- end
end
end
end
diff --git a/lib/gitlab/ci/jwt_v2.rb b/lib/gitlab/ci/jwt_v2.rb
index 278353220e4..4e01688a955 100644
--- a/lib/gitlab/ci/jwt_v2.rb
+++ b/lib/gitlab/ci/jwt_v2.rb
@@ -8,7 +8,7 @@ module Gitlab
def reserved_claims
super.merge(
iss: Settings.gitlab.base_url,
- sub: "project_path:#{project.full_path}:ref_type:#{ref_type}:ref:#{source_ref}",
+ sub: "project_path:#{project.full_path}:ref_type:#{ref_type}:ref:#{source_ref}",
aud: Settings.gitlab.base_url
)
end
diff --git a/lib/gitlab/ci/parsers/sbom/cyclonedx.rb b/lib/gitlab/ci/parsers/sbom/cyclonedx.rb
index deb20a2138c..aa594ca4049 100644
--- a/lib/gitlab/ci/parsers/sbom/cyclonedx.rb
+++ b/lib/gitlab/ci/parsers/sbom/cyclonedx.rb
@@ -6,7 +6,6 @@ module Gitlab
module Sbom
class Cyclonedx
SUPPORTED_SPEC_VERSIONS = %w[1.4].freeze
- COMPONENT_ATTRIBUTES = %w[type name version].freeze
def parse!(blob, sbom_report)
@report = sbom_report
@@ -62,10 +61,17 @@ module Gitlab
end
def parse_components
- data['components']&.each do |component|
- next unless supported_component_type?(component['type'])
+ data['components']&.each do |component_data|
+ type = component_data['type']
+ next unless supported_component_type?(type)
- report.add_component(component.slice(*COMPONENT_ATTRIBUTES))
+ component = ::Gitlab::Ci::Reports::Sbom::Component.new(
+ type: type,
+ name: component_data['name'],
+ version: component_data['version']
+ )
+
+ report.add_component(component)
end
end
diff --git a/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb b/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb
index ad04b3257f9..00ca723b258 100644
--- a/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb
+++ b/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb
@@ -21,11 +21,11 @@ module Gitlab
def source
return unless required_attributes_present?
- {
- 'type' => :dependency_scanning,
- 'data' => data,
- 'fingerprint' => fingerprint
- }
+ ::Gitlab::Ci::Reports::Sbom::Source.new(
+ type: :dependency_scanning,
+ data: data,
+ fingerprint: fingerprint
+ )
end
private
diff --git a/lib/gitlab/ci/parsers/security/common.rb b/lib/gitlab/ci/parsers/security/common.rb
index 13a159f3745..da7faaab6ff 100644
--- a/lib/gitlab/ci/parsers/security/common.rb
+++ b/lib/gitlab/ci/parsers/security/common.rb
@@ -7,16 +7,16 @@ module Gitlab
class Common
SecurityReportParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
- def self.parse!(json_data, report, vulnerability_finding_signatures_enabled = false, validate: false)
- new(json_data, report, vulnerability_finding_signatures_enabled, validate: validate).parse!
+ def self.parse!(json_data, report, signatures_enabled: false, validate: false)
+ new(json_data, report, signatures_enabled: signatures_enabled, validate: validate).parse!
end
- def initialize(json_data, report, vulnerability_finding_signatures_enabled = false, validate: false)
+ def initialize(json_data, report, signatures_enabled: false, validate: false)
@json_data = json_data
@report = report
@project = report.project
@validate = validate
- @vulnerability_finding_signatures_enabled = vulnerability_finding_signatures_enabled
+ @signatures_enabled = signatures_enabled
end
def parse!
@@ -26,7 +26,7 @@ module Gitlab
raise SecurityReportParserError, "Invalid report format" unless report_data.is_a?(Hash)
- create_scanner
+ create_scanner(top_level_scanner_data)
create_scan
create_analyzer
@@ -77,7 +77,7 @@ module Gitlab
report_data,
report.version,
project: @project,
- scanner: top_level_scanner
+ scanner: top_level_scanner_data
)
end
@@ -89,8 +89,8 @@ module Gitlab
@report_version ||= report_data['version']
end
- def top_level_scanner
- @top_level_scanner ||= report_data.dig('scan', 'scanner')
+ def top_level_scanner_data
+ @top_level_scanner_data ||= report_data.dig('scan', 'scanner')
end
def scan_data
@@ -119,7 +119,7 @@ module Gitlab
evidence = create_evidence(data['evidence'])
signatures = create_signatures(tracking_data(data))
- if @vulnerability_finding_signatures_enabled && !signatures.empty?
+ if @signatures_enabled && !signatures.empty?
# NOT the signature_sha - the compare key is hashed
# to create the project_fingerprint
highest_priority_signature = signatures.max_by(&:priority)
@@ -138,7 +138,7 @@ module Gitlab
evidence: evidence,
severity: parse_severity_level(data['severity']),
confidence: parse_confidence_level(data['confidence']),
- scanner: create_scanner(data['scanner']),
+ scanner: create_scanner(top_level_scanner_data || data['scanner']),
scan: report&.scan,
identifiers: identifiers,
flags: flags,
@@ -149,7 +149,7 @@ module Gitlab
details: data['details'] || {},
signatures: signatures,
project_id: @project.id,
- vulnerability_finding_signatures_enabled: @vulnerability_finding_signatures_enabled))
+ vulnerability_finding_signatures_enabled: @signatures_enabled))
end
def create_signatures(tracking)
@@ -208,7 +208,7 @@ module Gitlab
report.analyzer = ::Gitlab::Ci::Reports::Security::Analyzer.new(**params)
end
- def create_scanner(scanner_data = top_level_scanner)
+ def create_scanner(scanner_data)
return unless scanner_data.is_a?(Hash)
report.add_scanner(
diff --git a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
index c075ada725a..28d6620e5c4 100644
--- a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
+++ b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
@@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
- cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
- secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2]
+ cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0]
}.freeze
VERSIONS_TO_REMOVE_IN_16_0 = [].freeze
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/cluster-image-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/cluster-image-scanning-report-format.json
new file mode 100644
index 00000000000..db4c7ab1425
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/cluster-image-scanning-report-format.json
@@ -0,0 +1,977 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab Cluster Image Scanning",
+ "description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "cluster_image_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "image",
+ "kubernetes_resource"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The analyzed Docker image.",
+ "examples": [
+ "index.docker.io/library/nginx:1.21"
+ ]
+ },
+ "kubernetes_resource": {
+ "type": "object",
+ "description": "The specific Kubernetes resource that was scanned.",
+ "required": [
+ "namespace",
+ "kind",
+ "name",
+ "container_name"
+ ],
+ "properties": {
+ "namespace": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes namespace the resource that had its image scanned.",
+ "examples": [
+ "default",
+ "staging",
+ "production"
+ ]
+ },
+ "kind": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes kind the resource that had its image scanned.",
+ "examples": [
+ "Deployment",
+ "DaemonSet"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the resource that had its image scanned.",
+ "examples": [
+ "nginx-ingress"
+ ]
+ },
+ "container_name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the container that had its image scanned.",
+ "examples": [
+ "nginx"
+ ]
+ },
+ "agent_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
+ "examples": [
+ "1234"
+ ]
+ },
+ "cluster_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
+ "examples": [
+ "1234"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/container-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/container-scanning-report-format.json
new file mode 100644
index 00000000000..641cfc82e48
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/container-scanning-report-format.json
@@ -0,0 +1,911 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab Container Scanning",
+ "description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "container_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "operating_system",
+ "image"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+(:[^:]+)?$",
+ "description": "The analyzed Docker image."
+ },
+ "default_branch_image": {
+ "type": "string",
+ "maxLength": 255,
+ "pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$",
+ "description": "The name of the image on the default branch."
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/coverage-fuzzing-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/coverage-fuzzing-report-format.json
new file mode 100644
index 00000000000..59aa172444d
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/coverage-fuzzing-report-format.json
@@ -0,0 +1,874 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab Fuzz Testing",
+ "description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "coverage_fuzzing"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "description": "The location of the error",
+ "type": "object",
+ "properties": {
+ "crash_address": {
+ "type": "string",
+ "description": "The relative address in memory were the crash occurred.",
+ "examples": [
+ "0xabababab"
+ ]
+ },
+ "stacktrace_snippet": {
+ "type": "string",
+ "description": "The stack trace recorded during fuzzing resulting the crash.",
+ "examples": [
+ "func_a+0xabcd\nfunc_b+0xabcc"
+ ]
+ },
+ "crash_state": {
+ "type": "string",
+ "description": "Minimised and normalized crash stack-trace (called crash_state).",
+ "examples": [
+ "func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
+ ]
+ },
+ "crash_type": {
+ "type": "string",
+ "description": "Type of the crash.",
+ "examples": [
+ "Heap-Buffer-overflow",
+ "Division-by-zero"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dast-report-format.json
new file mode 100644
index 00000000000..0e4c866794a
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dast-report-format.json
@@ -0,0 +1,1287 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab DAST",
+ "description": "This schema provides the the report format for Dynamic Application Security Testing (https://docs.gitlab.com/ee/user/application_security/dast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanned_resources",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dast",
+ "api_fuzzing"
+ ]
+ },
+ "scanned_resources": {
+ "type": "array",
+ "description": "The attack surface scanned by DAST.",
+ "items": {
+ "type": "object",
+ "required": [
+ "method",
+ "url",
+ "type"
+ ],
+ "properties": {
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method of the scanned resource.",
+ "examples": [
+ "GET",
+ "POST",
+ "HEAD"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the scanned resource.",
+ "examples": [
+ "http://my.site.com/a-page"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Type of the scanned resource, for DAST, this must be 'url'.",
+ "examples": [
+ "url"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "evidence": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "type": "object",
+ "description": "Source of evidence",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique source identifier",
+ "examples": [
+ "assert:LogAnalysis",
+ "assert:StatusCode"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Source display name",
+ "examples": [
+ "Log Analysis",
+ "Status Code"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "Link to additional information",
+ "examples": [
+ "https://docs.gitlab.com/ee/development/integrations/secure.html"
+ ]
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "description": "Human readable string containing evidence of the vulnerability.",
+ "examples": [
+ "Credit card 4111111111111111 found",
+ "Server leaked information nginx/1.17.6"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ },
+ "supporting_messages": {
+ "type": "array",
+ "description": "Array of supporting http messages.",
+ "items": {
+ "type": "object",
+ "description": "A supporting http message.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Message display name.",
+ "examples": [
+ "Unmodified",
+ "Recorded"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The protocol, domain, and port of the application where the vulnerability was found."
+ },
+ "method": {
+ "type": "string",
+ "description": "The HTTP method that was used to request the URL where the vulnerability was found."
+ },
+ "param": {
+ "type": "string",
+ "description": "A value provided by a vulnerability rule related to the found vulnerability. Examples include a header value, or a parameter used in a HTTP POST."
+ },
+ "path": {
+ "type": "string",
+ "description": "The path of the URL where the vulnerability was found. Typically, this would start with a forward slash."
+ }
+ }
+ },
+ "assets": {
+ "type": "array",
+ "description": "Array of build assets associated with vulnerability.",
+ "items": {
+ "type": "object",
+ "description": "Describes an asset associated with vulnerability.",
+ "required": [
+ "type",
+ "name",
+ "url"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The type of asset",
+ "enum": [
+ "http_session",
+ "postman"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Display name for asset",
+ "examples": [
+ "HTTP Messages",
+ "Postman Collection"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Link to asset in build artifacts",
+ "examples": [
+ "https://gitlab.com/gitlab-org/security-products/dast/-/jobs/626397001/artifacts/file//output/zap_session.data"
+ ]
+ }
+ }
+ }
+ },
+ "discovered_at": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss.sss, representing when the vulnerability was discovered",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{3}$",
+ "examples": [
+ "2020-01-28T03:26:02.956"
+ ]
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dependency-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dependency-scanning-report-format.json
new file mode 100644
index 00000000000..652c2f48fe4
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/dependency-scanning-report-format.json
@@ -0,0 +1,968 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab Dependency Scanning",
+ "description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "dependency_files",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dependency_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "file",
+ "dependency"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
+ },
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ },
+ "dependency_files": {
+ "type": "array",
+ "description": "List of dependency files identified in the project.",
+ "items": {
+ "type": "object",
+ "required": [
+ "path",
+ "package_manager",
+ "dependencies"
+ ],
+ "properties": {
+ "path": {
+ "type": "string",
+ "minLength": 1
+ },
+ "package_manager": {
+ "type": "string",
+ "minLength": 1
+ },
+ "dependencies": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/sast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/sast-report-format.json
new file mode 100644
index 00000000000..40d4d9f5287
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/sast-report-format.json
@@ -0,0 +1,869 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab SAST",
+ "description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "sast"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability."
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located."
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located."
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/secret-detection-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/secret-detection-report-format.json
new file mode 100644
index 00000000000..cfde126dd7b
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/14.1.3/secret-detection-report-format.json
@@ -0,0 +1,892 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Report format for GitLab Secret Detection",
+ "description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "14.1.3"
+ },
+ "required": [
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "secret_detection"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "format": "uri"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "category",
+ "cve",
+ "identifiers",
+ "location",
+ "scanner"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "message": {
+ "type": "string",
+ "description": "A short text section that describes the vulnerability. This may include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "confidence": {
+ "type": "string",
+ "description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Ignore",
+ "Unknown",
+ "Experimental",
+ "Low",
+ "Medium",
+ "High",
+ "Confirmed"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "scanner": {
+ "description": "Describes the scanner used to find this vulnerability.",
+ "type": "object",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The scanner's ID, as a snake_case string."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Human-readable name of the scanner."
+ }
+ }
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "format": "uri"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "format": "uri"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "required": [
+ "commit"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located"
+ },
+ "commit": {
+ "type": "object",
+ "description": "Represents the commit in which the vulnerability was detected",
+ "required": [
+ "sha"
+ ],
+ "properties": {
+ "author": {
+ "type": "string"
+ },
+ "date": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "sha": {
+ "type": "string",
+ "minLength": 1
+ }
+ }
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability"
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability"
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located"
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located"
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "cve"
+ ],
+ "properties": {
+ "cve": {
+ "type": "string",
+ "description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json
new file mode 100644
index 00000000000..7ccb39a2b8e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json
@@ -0,0 +1,946 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/cluster-image-scanning-report-format.json",
+ "title": "Report format for GitLab Cluster Image Scanning",
+ "description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "cluster_image_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "image",
+ "kubernetes_resource"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The analyzed Docker image.",
+ "examples": [
+ "index.docker.io/library/nginx:1.21"
+ ]
+ },
+ "kubernetes_resource": {
+ "type": "object",
+ "description": "The specific Kubernetes resource that was scanned.",
+ "required": [
+ "namespace",
+ "kind",
+ "name",
+ "container_name"
+ ],
+ "properties": {
+ "namespace": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes namespace the resource that had its image scanned.",
+ "examples": [
+ "default",
+ "staging",
+ "production"
+ ]
+ },
+ "kind": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes kind the resource that had its image scanned.",
+ "examples": [
+ "Deployment",
+ "DaemonSet"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the resource that had its image scanned.",
+ "examples": [
+ "nginx-ingress"
+ ]
+ },
+ "container_name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the container that had its image scanned.",
+ "examples": [
+ "nginx"
+ ]
+ },
+ "agent_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
+ "examples": [
+ "1234"
+ ]
+ },
+ "cluster_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
+ "examples": [
+ "1234"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json
new file mode 100644
index 00000000000..2517832853e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json
@@ -0,0 +1,880 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/container-scanning-report-format.json",
+ "title": "Report format for GitLab Container Scanning",
+ "description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "container_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "operating_system",
+ "image"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+(:[^:]+)?$",
+ "description": "The analyzed Docker image."
+ },
+ "default_branch_image": {
+ "type": "string",
+ "maxLength": 255,
+ "pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$",
+ "description": "The name of the image on the default branch."
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json
new file mode 100644
index 00000000000..a2f9eb12992
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json
@@ -0,0 +1,836 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/coverage-fuzzing-report-format.json",
+ "title": "Report format for GitLab Fuzz Testing",
+ "description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "coverage_fuzzing"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "description": "The location of the error",
+ "type": "object",
+ "properties": {
+ "crash_address": {
+ "type": "string",
+ "description": "The relative address in memory were the crash occurred.",
+ "examples": [
+ "0xabababab"
+ ]
+ },
+ "stacktrace_snippet": {
+ "type": "string",
+ "description": "The stack trace recorded during fuzzing resulting the crash.",
+ "examples": [
+ "func_a+0xabcd\nfunc_b+0xabcc"
+ ]
+ },
+ "crash_state": {
+ "type": "string",
+ "description": "Minimised and normalized crash stack-trace (called crash_state).",
+ "examples": [
+ "func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
+ ]
+ },
+ "crash_type": {
+ "type": "string",
+ "description": "Type of the crash.",
+ "examples": [
+ "Heap-Buffer-overflow",
+ "Division-by-zero"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json
new file mode 100644
index 00000000000..10fafaf8975
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json
@@ -0,0 +1,1241 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dast-report-format.json",
+ "title": "Report format for GitLab DAST",
+ "description": "This schema provides the the report format for Dynamic Application Security Testing (https://docs.gitlab.com/ee/user/application_security/dast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanned_resources",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dast",
+ "api_fuzzing"
+ ]
+ },
+ "scanned_resources": {
+ "type": "array",
+ "description": "The attack surface scanned by DAST.",
+ "items": {
+ "type": "object",
+ "required": [
+ "method",
+ "url",
+ "type"
+ ],
+ "properties": {
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method of the scanned resource.",
+ "examples": [
+ "GET",
+ "POST",
+ "HEAD"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the scanned resource.",
+ "examples": [
+ "http://my.site.com/a-page"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Type of the scanned resource, for DAST, this must be 'url'.",
+ "examples": [
+ "url"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "evidence": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "type": "object",
+ "description": "Source of evidence",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique source identifier",
+ "examples": [
+ "assert:LogAnalysis",
+ "assert:StatusCode"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Source display name",
+ "examples": [
+ "Log Analysis",
+ "Status Code"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "Link to additional information",
+ "examples": [
+ "https://docs.gitlab.com/ee/development/integrations/secure.html"
+ ]
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "description": "Human readable string containing evidence of the vulnerability.",
+ "examples": [
+ "Credit card 4111111111111111 found",
+ "Server leaked information nginx/1.17.6"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ },
+ "supporting_messages": {
+ "type": "array",
+ "description": "Array of supporting http messages.",
+ "items": {
+ "type": "object",
+ "description": "A supporting http message.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Message display name.",
+ "examples": [
+ "Unmodified",
+ "Recorded"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The protocol, domain, and port of the application where the vulnerability was found."
+ },
+ "method": {
+ "type": "string",
+ "description": "The HTTP method that was used to request the URL where the vulnerability was found."
+ },
+ "param": {
+ "type": "string",
+ "description": "A value provided by a vulnerability rule related to the found vulnerability. Examples include a header value, or a parameter used in a HTTP POST."
+ },
+ "path": {
+ "type": "string",
+ "description": "The path of the URL where the vulnerability was found. Typically, this would start with a forward slash."
+ }
+ }
+ },
+ "assets": {
+ "type": "array",
+ "description": "Array of build assets associated with vulnerability.",
+ "items": {
+ "type": "object",
+ "description": "Describes an asset associated with vulnerability.",
+ "required": [
+ "type",
+ "name",
+ "url"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The type of asset",
+ "enum": [
+ "http_session",
+ "postman"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Display name for asset",
+ "examples": [
+ "HTTP Messages",
+ "Postman Collection"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Link to asset in build artifacts",
+ "examples": [
+ "https://gitlab.com/gitlab-org/security-products/dast/-/jobs/626397001/artifacts/file//output/zap_session.data"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json
new file mode 100644
index 00000000000..ade1ce9ea8f
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json
@@ -0,0 +1,944 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dependency-scanning-report-format.json",
+ "title": "Report format for GitLab Dependency Scanning",
+ "description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "dependency_files",
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dependency_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "file",
+ "dependency"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
+ },
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ },
+ "dependency_files": {
+ "type": "array",
+ "description": "List of dependency files identified in the project.",
+ "items": {
+ "type": "object",
+ "required": [
+ "path",
+ "package_manager",
+ "dependencies"
+ ],
+ "properties": {
+ "path": {
+ "type": "string",
+ "minLength": 1
+ },
+ "package_manager": {
+ "type": "string",
+ "minLength": 1
+ },
+ "dependencies": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json
new file mode 100644
index 00000000000..9fae45d728e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json
@@ -0,0 +1,831 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/sast-report-format.json",
+ "title": "Report format for GitLab SAST",
+ "description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "sast"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability."
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located."
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located."
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json
new file mode 100644
index 00000000000..fca00e17f26
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json
@@ -0,0 +1,854 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/secret-detection-report-format.json",
+ "title": "Report format for GitLab Secret Detection",
+ "description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "secret_detection"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "required": [
+ "commit"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located"
+ },
+ "commit": {
+ "type": "object",
+ "description": "Represents the commit in which the vulnerability was detected",
+ "required": [
+ "sha"
+ ],
+ "properties": {
+ "author": {
+ "type": "string"
+ },
+ "date": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "sha": {
+ "type": "string",
+ "minLength": 1
+ }
+ }
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability"
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability"
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located"
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located"
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb
index 999ffff85d2..d95ecff85cd 100644
--- a/lib/gitlab/ci/parsers/test/junit.rb
+++ b/lib/gitlab/ci/parsers/test/junit.rb
@@ -8,7 +8,9 @@ module Gitlab
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
- def parse!(xml_data, test_suite, job:)
+ def parse!(xml_data, test_report, job:)
+ test_suite = test_report.get_suite(job.test_suite_name)
+
root = Hash.from_xml(xml_data)
total_parsed = 0
max_test_cases = job.max_test_cases_per_report
diff --git a/lib/gitlab/ci/pipeline/chain/assign_partition.rb b/lib/gitlab/ci/pipeline/chain/assign_partition.rb
new file mode 100644
index 00000000000..4b8efe13d44
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/chain/assign_partition.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ module Chain
+ class AssignPartition < Chain::Base
+ include Chain::Helpers
+
+ def perform!
+ @pipeline.partition_id = find_partition_id
+ end
+
+ def break?
+ @pipeline.errors.any?
+ end
+
+ private
+
+ def find_partition_id
+ if @command.creates_child_pipeline?
+ @command.parent_pipeline_partition_id
+ else
+ ::Ci::Pipeline.current_partition_value
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 0a6f6fd740c..14c320f77bf 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -80,6 +80,10 @@ module Gitlab
bridge&.parent_pipeline
end
+ def parent_pipeline_partition_id
+ parent_pipeline.partition_id if creates_child_pipeline?
+ end
+
def creates_child_pipeline?
bridge&.triggers_child_pipeline?
end
@@ -117,8 +121,14 @@ module Gitlab
end
def observe_jobs_count_in_alive_pipelines
+ jobs_count = if Feature.enabled?(:ci_limit_active_jobs_early, project)
+ project.all_pipelines.jobs_count_in_alive_pipelines
+ else
+ project.all_pipelines.builds_count_in_alive_pipelines
+ end
+
metrics.active_jobs_histogram
- .observe({ plan: project.actual_plan_name }, project.all_pipelines.jobs_count_in_alive_pipelines)
+ .observe({ plan: project.actual_plan_name }, jobs_count)
end
def increment_pipeline_failure_reason_counter(reason)
diff --git a/lib/gitlab/ci/pipeline/chain/config/content.rb b/lib/gitlab/ci/pipeline/chain/config/content.rb
index 3c150ca26bb..a14dec48619 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content.rb
@@ -7,6 +7,7 @@ module Gitlab
module Config
class Content < Chain::Base
include Chain::Helpers
+ include ::Gitlab::Utils::StrongMemoize
SOURCES = [
Gitlab::Ci::Pipeline::Chain::Config::Content::Parameter,
@@ -18,10 +19,10 @@ module Gitlab
].freeze
def perform!
- if config = find_config
- @pipeline.build_pipeline_config(content: config.content)
- @command.config_content = config.content
- @pipeline.config_source = config.source
+ if pipeline_config&.exists?
+ @pipeline.build_pipeline_config(content: pipeline_config.content)
+ @command.config_content = pipeline_config.content
+ @pipeline.config_source = pipeline_config.source
else
error('Missing CI config file')
end
@@ -33,7 +34,19 @@ module Gitlab
private
- def find_config
+ def pipeline_config
+ strong_memoize(:pipeline_config) do
+ next legacy_find_config if ::Feature.disabled?(:ci_project_pipeline_config_refactoring, project)
+
+ ::Gitlab::Ci::ProjectConfig.new(
+ project: project, sha: @pipeline.sha,
+ custom_content: @command.content,
+ pipeline_source: @command.source, pipeline_source_bridge: @command.bridge
+ )
+ end
+ end
+
+ def legacy_find_config
sources.each do |source|
config = source.new(@pipeline, @command)
return config if config.exists?
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/source.rb b/lib/gitlab/ci/pipeline/chain/config/content/source.rb
index 8bc172f93d3..69dca1568b6 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content/source.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content/source.rb
@@ -6,6 +6,7 @@ module Gitlab
module Chain
module Config
class Content
+ # When removing ci_project_pipeline_config_refactoring, this and its subclasses will be removed.
class Source
include Gitlab::Utils::StrongMemoize
diff --git a/lib/gitlab/ci/pipeline/chain/ensure_environments.rb b/lib/gitlab/ci/pipeline/chain/ensure_environments.rb
index 245ef32f06b..3dd9b85d9b2 100644
--- a/lib/gitlab/ci/pipeline/chain/ensure_environments.rb
+++ b/lib/gitlab/ci/pipeline/chain/ensure_environments.rb
@@ -18,7 +18,9 @@ module Gitlab
def ensure_environment(build)
return unless build.instance_of?(::Ci::Build) && build.has_environment?
- environment = ::Gitlab::Ci::Pipeline::Seed::Environment.new(build).to_resource
+ environment = ::Gitlab::Ci::Pipeline::Seed::Environment
+ .new(build, merge_request: @command.merge_request)
+ .to_resource
if environment.persisted?
build.persisted_environment = environment
diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb
index 6e95c7988fc..915e48828d2 100644
--- a/lib/gitlab/ci/pipeline/chain/validate/external.rb
+++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb
@@ -57,7 +57,8 @@ module Gitlab
}.compact
Gitlab::HTTP.post(
- validation_service_url, timeout: validation_service_timeout,
+ validation_service_url,
+ timeout: validation_service_timeout,
headers: headers,
body: validation_service_payload.to_json
)
@@ -96,13 +97,17 @@ module Gitlab
last_sign_in_ip: current_user.last_sign_in_ip,
sign_in_count: current_user.sign_in_count
},
+ credit_card: {
+ similar_cards_count: current_user.credit_card_validation&.similar_records&.count.to_i,
+ similar_holder_names_count: current_user.credit_card_validation&.similar_holder_names_count.to_i
+ },
pipeline: {
sha: pipeline.sha,
ref: pipeline.ref,
type: pipeline.source
},
builds: builds_validation_payload,
- total_builds_count: current_user.pipelines.jobs_count_in_alive_pipelines
+ total_builds_count: current_user.pipelines.builds_count_in_alive_pipelines
}
end
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index 93106b96af2..2e4267e986b 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -148,7 +148,9 @@ module Gitlab
ref: @pipeline.ref,
tag: @pipeline.tag,
trigger_request: @pipeline.legacy_trigger,
- protected: @pipeline.protected_ref?
+ protected: @pipeline.protected_ref?,
+ partition_id: @pipeline.partition_id,
+ metadata_attributes: { partition_id: @pipeline.partition_id }
}
end
diff --git a/lib/gitlab/ci/pipeline/seed/environment.rb b/lib/gitlab/ci/pipeline/seed/environment.rb
index 6bcc71a808b..8353bc523bf 100644
--- a/lib/gitlab/ci/pipeline/seed/environment.rb
+++ b/lib/gitlab/ci/pipeline/seed/environment.rb
@@ -5,17 +5,21 @@ module Gitlab
module Pipeline
module Seed
class Environment < Seed::Base
- attr_reader :job
+ attr_reader :job, :merge_request
- def initialize(job)
+ delegate :simple_variables, to: :job
+
+ def initialize(job, merge_request: nil)
@job = job
+ @merge_request = merge_request
end
def to_resource
environments.safe_find_or_create_by(name: expanded_environment_name) do |environment|
# Initialize the attributes at creation
- environment.auto_stop_in = auto_stop_in
+ environment.auto_stop_in = expanded_auto_stop_in
environment.tier = deployment_tier
+ environment.merge_request = merge_request
end
end
@@ -36,6 +40,12 @@ module Gitlab
def expanded_environment_name
job.expanded_environment_name
end
+
+ def expanded_auto_stop_in
+ return unless auto_stop_in
+
+ ExpandVariables.expand(auto_stop_in, -> { simple_variables.sort_and_expand_all })
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/seed/stage.rb b/lib/gitlab/ci/pipeline/seed/stage.rb
index 7cf6466cf4b..1c4247bd5ee 100644
--- a/lib/gitlab/ci/pipeline/seed/stage.rb
+++ b/lib/gitlab/ci/pipeline/seed/stage.rb
@@ -25,7 +25,8 @@ module Gitlab
{ name: @attributes.fetch(:name),
position: @attributes.fetch(:index),
pipeline: @pipeline,
- project: @pipeline.project }
+ project: @pipeline.project,
+ partition_id: @pipeline.partition_id }
end
def seeds
diff --git a/lib/gitlab/ci/processable_object_hierarchy.rb b/lib/gitlab/ci/processable_object_hierarchy.rb
new file mode 100644
index 00000000000..1122361e27e
--- /dev/null
+++ b/lib/gitlab/ci/processable_object_hierarchy.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProcessableObjectHierarchy < ::Gitlab::ObjectHierarchy
+ private
+
+ def middle_table
+ ::Ci::BuildNeed.arel_table
+ end
+
+ def from_tables(cte)
+ [objects_table, cte.table, middle_table]
+ end
+
+ def parent_id_column(_cte)
+ middle_table[:name]
+ end
+
+ def ancestor_conditions(cte)
+ middle_table[:name].eq(objects_table[:name]).and(
+ middle_table[:build_id].eq(cte.table[:id])
+ )
+ end
+
+ def descendant_conditions(cte)
+ middle_table[:build_id].eq(objects_table[:id]).and(
+ middle_table[:name].eq(cte.table[:name])
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config.rb b/lib/gitlab/ci/project_config.rb
new file mode 100644
index 00000000000..ded6877ef29
--- /dev/null
+++ b/lib/gitlab/ci/project_config.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ # Locates project CI config
+ class ProjectConfig
+ # The order of sources is important:
+ # - EE uses Compliance first since it must be used first if compliance templates are enabled.
+ # (see ee/lib/ee/gitlab/ci/project_config.rb)
+ # - Parameter is used by on-demand security scanning which passes the actual CI YAML to use as argument.
+ # - Bridge is used for downstream pipelines since the config is defined in the bridge job. If lower in priority,
+ # it would evaluate the project's YAML file instead.
+ # - Repository / ExternalProject / Remote: their order is not important between each other.
+ # - AutoDevops is used as default option if nothing else is found and if AutoDevops is enabled.
+ SOURCES = [
+ ProjectConfig::Parameter,
+ ProjectConfig::Bridge,
+ ProjectConfig::Repository,
+ ProjectConfig::ExternalProject,
+ ProjectConfig::Remote,
+ ProjectConfig::AutoDevops
+ ].freeze
+
+ def initialize(project:, sha:, custom_content: nil, pipeline_source: nil, pipeline_source_bridge: nil)
+ @config = find_config(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
+ end
+
+ delegate :content, :source, to: :@config, allow_nil: true
+
+ def exists?
+ !!@config&.exists?
+ end
+
+ private
+
+ def find_config(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
+ sources.each do |source|
+ config = source.new(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
+ return config if config.exists?
+ end
+
+ nil
+ end
+
+ def sources
+ SOURCES
+ end
+ end
+ end
+end
+
+Gitlab::Ci::ProjectConfig.prepend_mod_with('Gitlab::Ci::ProjectConfig')
diff --git a/lib/gitlab/ci/project_config/auto_devops.rb b/lib/gitlab/ci/project_config/auto_devops.rb
new file mode 100644
index 00000000000..c6905f480a2
--- /dev/null
+++ b/lib/gitlab/ci/project_config/auto_devops.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class AutoDevops < Source
+ def content
+ strong_memoize(:content) do
+ next unless project&.auto_devops_enabled?
+
+ template = Gitlab::Template::GitlabCiYmlTemplate.find(template_name)
+ YAML.dump('include' => [{ 'template' => template.full_name }])
+ end
+ end
+
+ def source
+ :auto_devops_source
+ end
+
+ private
+
+ def template_name
+ 'Auto-DevOps'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/bridge.rb b/lib/gitlab/ci/project_config/bridge.rb
new file mode 100644
index 00000000000..c342ab2c215
--- /dev/null
+++ b/lib/gitlab/ci/project_config/bridge.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class Bridge < Source
+ def content
+ return unless pipeline_source_bridge
+
+ pipeline_source_bridge.yaml_for_downstream
+ end
+
+ def source
+ :bridge_source
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/external_project.rb b/lib/gitlab/ci/project_config/external_project.rb
new file mode 100644
index 00000000000..0ed5d6fa226
--- /dev/null
+++ b/lib/gitlab/ci/project_config/external_project.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class ExternalProject < Source
+ def content
+ strong_memoize(:content) do
+ next unless external_project_path?
+
+ path_file, path_project, ref = extract_location_tokens
+
+ config_location = { 'project' => path_project, 'file' => path_file }
+ config_location['ref'] = ref if ref.present?
+
+ YAML.dump('include' => [config_location])
+ end
+ end
+
+ def source
+ :external_project_source
+ end
+
+ private
+
+ # Example: path/to/.gitlab-ci.yml@another-group/another-project
+ def external_project_path?
+ ci_config_path =~ /\A.+(yml|yaml)@.+\z/
+ end
+
+ # Example: path/to/.gitlab-ci.yml@another-group/another-project:refname
+ def extract_location_tokens
+ path_file, path_project = ci_config_path.split('@', 2)
+
+ if path_project.include? ":"
+ project, ref = path_project.split(':', 2)
+ [path_file, project, ref]
+ else
+ [path_file, path_project]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/parameter.rb b/lib/gitlab/ci/project_config/parameter.rb
new file mode 100644
index 00000000000..69e699c27f1
--- /dev/null
+++ b/lib/gitlab/ci/project_config/parameter.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class Parameter < Source
+ def content
+ strong_memoize(:content) do
+ next unless custom_content.present?
+
+ custom_content
+ end
+ end
+
+ def source
+ :parameter_source
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/remote.rb b/lib/gitlab/ci/project_config/remote.rb
new file mode 100644
index 00000000000..cf1292706d2
--- /dev/null
+++ b/lib/gitlab/ci/project_config/remote.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class Remote < Source
+ def content
+ strong_memoize(:content) do
+ next unless ci_config_path =~ URI::DEFAULT_PARSER.make_regexp(%w[http https])
+
+ YAML.dump('include' => [{ 'remote' => ci_config_path }])
+ end
+ end
+
+ def source
+ :remote_source
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/repository.rb b/lib/gitlab/ci/project_config/repository.rb
new file mode 100644
index 00000000000..435ad4d42fe
--- /dev/null
+++ b/lib/gitlab/ci/project_config/repository.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class Repository < Source
+ def content
+ strong_memoize(:content) do
+ next unless file_in_repository?
+
+ YAML.dump('include' => [{ 'local' => ci_config_path }])
+ end
+ end
+
+ def source
+ :repository_source
+ end
+
+ private
+
+ def file_in_repository?
+ return unless project
+ return unless sha
+
+ project.repository.gitlab_ci_yml_for(sha, ci_config_path).present?
+ rescue GRPC::NotFound, GRPC::Internal
+ nil
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/project_config/source.rb b/lib/gitlab/ci/project_config/source.rb
new file mode 100644
index 00000000000..ebe5728163b
--- /dev/null
+++ b/lib/gitlab/ci/project_config/source.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class ProjectConfig
+ class Source
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
+ @project = project
+ @sha = sha
+ @custom_content = custom_content
+ @pipeline_source = pipeline_source
+ @pipeline_source_bridge = pipeline_source_bridge
+ end
+
+ def exists?
+ strong_memoize(:exists) do
+ content.present?
+ end
+ end
+
+ def content
+ raise NotImplementedError
+ end
+
+ def source
+ raise NotImplementedError
+ end
+
+ private
+
+ attr_reader :project, :sha, :custom_content, :pipeline_source, :pipeline_source_bridge
+
+ def ci_config_path
+ @ci_config_path ||= project.ci_config_path_or_default
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/coverage_report_generator.rb b/lib/gitlab/ci/reports/coverage_report_generator.rb
index 6d57e05aa63..88b3b14d5c9 100644
--- a/lib/gitlab/ci/reports/coverage_report_generator.rb
+++ b/lib/gitlab/ci/reports/coverage_report_generator.rb
@@ -35,7 +35,7 @@ module Gitlab
private
def report_builds
- @pipeline.latest_report_builds_in_self_and_descendants(::Ci::JobArtifact.coverage_reports)
+ @pipeline.latest_report_builds_in_self_and_project_descendants(::Ci::JobArtifact.of_report_type(:coverage))
end
end
end
diff --git a/lib/gitlab/ci/reports/sbom/component.rb b/lib/gitlab/ci/reports/sbom/component.rb
index 86b9be274cc..198b34451b4 100644
--- a/lib/gitlab/ci/reports/sbom/component.rb
+++ b/lib/gitlab/ci/reports/sbom/component.rb
@@ -7,10 +7,10 @@ module Gitlab
class Component
attr_reader :component_type, :name, :version
- def initialize(component = {})
- @component_type = component['type']
- @name = component['name']
- @version = component['version']
+ def initialize(type:, name:, version:)
+ @component_type = type
+ @name = name
+ @version = version
end
end
end
diff --git a/lib/gitlab/ci/reports/sbom/report.rb b/lib/gitlab/ci/reports/sbom/report.rb
index dc6b3153e51..4f84d12f78c 100644
--- a/lib/gitlab/ci/reports/sbom/report.rb
+++ b/lib/gitlab/ci/reports/sbom/report.rb
@@ -17,11 +17,11 @@ module Gitlab
end
def set_source(source)
- self.source = Source.new(source)
+ self.source = source
end
def add_component(component)
- components << Component.new(component)
+ components << component
end
private
diff --git a/lib/gitlab/ci/reports/sbom/source.rb b/lib/gitlab/ci/reports/sbom/source.rb
index 60bf30b65a5..ea0fb8d4fbb 100644
--- a/lib/gitlab/ci/reports/sbom/source.rb
+++ b/lib/gitlab/ci/reports/sbom/source.rb
@@ -7,10 +7,10 @@ module Gitlab
class Source
attr_reader :source_type, :data, :fingerprint
- def initialize(source = {})
- @source_type = source['type']
- @data = source['data']
- @fingerprint = source['fingerprint']
+ def initialize(type:, data:, fingerprint:)
+ @source_type = type
+ @data = data
+ @fingerprint = fingerprint
end
end
end
diff --git a/lib/gitlab/ci/reports/security/scanner.rb b/lib/gitlab/ci/reports/security/scanner.rb
index 1ac66a0c671..918df163ede 100644
--- a/lib/gitlab/ci/reports/security/scanner.rb
+++ b/lib/gitlab/ci/reports/security/scanner.rb
@@ -7,13 +7,13 @@ module Gitlab
class Scanner
ANALYZER_ORDER = {
"bundler_audit" => 1,
- "retire.js" => 2,
+ "retire.js" => 2,
"gemnasium" => 3,
"gemnasium-maven" => 3,
"gemnasium-python" => 3,
"bandit" => 1,
"spotbugs" => 1,
- "semgrep" => 2
+ "semgrep" => 2
}.freeze
attr_accessor :external_id, :name, :vendor, :version
diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb
index 5d60aa8f540..a136044c124 100644
--- a/lib/gitlab/ci/status/build/failed.rb
+++ b/lib/gitlab/ci/status/build/failed.rb
@@ -31,6 +31,7 @@ module Gitlab
downstream_pipeline_creation_failed: 'downstream pipeline can not be created',
secrets_provider_not_found: 'secrets provider can not be found',
reached_max_descendant_pipelines_depth: 'reached maximum depth of child pipelines',
+ reached_max_pipeline_hierarchy_size: 'downstream pipeline tree is too large',
project_deleted: 'pipeline project was deleted',
user_blocked: 'pipeline user was blocked',
ci_quota_exceeded: 'no more CI minutes available',
@@ -39,7 +40,8 @@ module Gitlab
builds_disabled: 'project builds are disabled',
environment_creation_failure: 'environment creation failure',
deployment_rejected: 'deployment rejected',
- ip_restriction_failure: 'IP address restriction failure'
+ ip_restriction_failure: 'IP address restriction failure',
+ failed_outdated_deployment_job: 'failed outdated deployment job'
}.freeze
private_constant :REASONS
diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
index f0ddc4b4916..539e1a6385d 100644
--- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.33.0'
+ DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.37.0'
.dast-auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..70f85382967
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml
@@ -0,0 +1,244 @@
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
+
+# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/
+#
+# Configure dependency scanning with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/index.html).
+# List of available variables: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html#available-variables
+
+variables:
+ # Setting this variable will affect all Security templates
+ # (SAST, Dependency Scanning, ...)
+ SECURE_ANALYZERS_PREFIX: "$CI_TEMPLATE_REGISTRY_HOST/security-products"
+ DS_EXCLUDED_ANALYZERS: ""
+ DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
+ DS_MAJOR_VERSION: 3
+
+dependency_scanning:
+ stage: test
+ script:
+ - echo "$CI_JOB_NAME is used for configuration only, and its script should not be executed"
+ - exit 1
+ artifacts:
+ reports:
+ dependency_scanning: gl-dependency-scanning-report.json
+ dependencies: []
+ rules:
+ - when: never
+
+.ds-analyzer:
+ extends: dependency_scanning
+ allow_failure: true
+ variables:
+ # DS_ANALYZER_IMAGE is an undocumented variable used internally to allow QA to
+ # override the analyzer image with a custom value. This may be subject to change or
+ # breakage across GitLab releases.
+ DS_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/$DS_ANALYZER_NAME:$DS_MAJOR_VERSION"
+ # DS_ANALYZER_NAME is an undocumented variable used in job definitions
+ # to inject the analyzer name in the image name.
+ DS_ANALYZER_NAME: ""
+ image:
+ name: "$DS_ANALYZER_IMAGE$DS_IMAGE_SUFFIX"
+ # `rules` must be overridden explicitly by each child job
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/218444
+ script:
+ - /analyzer run
+
+.cyclonedx-reports:
+ artifacts:
+ paths:
+ - "**/gl-sbom-*.cdx.json"
+
+.gemnasium-shared-rule:
+ exists:
+ - '{Gemfile.lock,*/Gemfile.lock,*/*/Gemfile.lock}'
+ - '{composer.lock,*/composer.lock,*/*/composer.lock}'
+ - '{gems.locked,*/gems.locked,*/*/gems.locked}'
+ - '{go.sum,*/go.sum,*/*/go.sum}'
+ - '{npm-shrinkwrap.json,*/npm-shrinkwrap.json,*/*/npm-shrinkwrap.json}'
+ - '{package-lock.json,*/package-lock.json,*/*/package-lock.json}'
+ - '{yarn.lock,*/yarn.lock,*/*/yarn.lock}'
+ - '{packages.lock.json,*/packages.lock.json,*/*/packages.lock.json}'
+ - '{conan.lock,*/conan.lock,*/*/conan.lock}'
+
+gemnasium-dependency_scanning:
+ extends:
+ - .ds-analyzer
+ - .cyclonedx-reports
+ variables:
+ DS_ANALYZER_NAME: "gemnasium"
+ GEMNASIUM_LIBRARY_SCAN_ENABLED: "true"
+ rules:
+ - if: $DEPENDENCY_SCANNING_DISABLED
+ when: never
+ - if: $DS_EXCLUDED_ANALYZERS =~ /gemnasium([^-]|$)/
+ when: never
+
+ # Add the job to merge request pipelines if there's an open merge request.
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ DS_REMEDIATE: "false"
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-shared-rule, exists]
+
+ # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
+ - if: $CI_OPEN_MERGE_REQUESTS
+ when: never
+
+ # Add the job to branch pipelines.
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ DS_REMEDIATE: "false"
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-shared-rule, exists]
+
+.gemnasium-maven-shared-rule:
+ exists:
+ - '{build.gradle,*/build.gradle,*/*/build.gradle}'
+ - '{build.gradle.kts,*/build.gradle.kts,*/*/build.gradle.kts}'
+ - '{build.sbt,*/build.sbt,*/*/build.sbt}'
+ - '{pom.xml,*/pom.xml,*/*/pom.xml}'
+
+gemnasium-maven-dependency_scanning:
+ extends:
+ - .ds-analyzer
+ - .cyclonedx-reports
+ variables:
+ DS_ANALYZER_NAME: "gemnasium-maven"
+ rules:
+ - if: $DEPENDENCY_SCANNING_DISABLED
+ when: never
+ - if: $DS_EXCLUDED_ANALYZERS =~ /gemnasium-maven/
+ when: never
+
+ # Add the job to merge request pipelines if there's an open merge request.
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-maven-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ DS_REMEDIATE: "false"
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-maven-shared-rule, exists]
+
+ # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
+ - if: $CI_OPEN_MERGE_REQUESTS
+ when: never
+
+ # Add the job to branch pipelines.
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-maven-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-maven-shared-rule, exists]
+
+.gemnasium-python-shared-rule:
+ exists:
+ - '{requirements.txt,*/requirements.txt,*/*/requirements.txt}'
+ - '{requirements.pip,*/requirements.pip,*/*/requirements.pip}'
+ - '{Pipfile,*/Pipfile,*/*/Pipfile}'
+ - '{requires.txt,*/requires.txt,*/*/requires.txt}'
+ - '{setup.py,*/setup.py,*/*/setup.py}'
+ - '{poetry.lock,*/poetry.lock,*/*/poetry.lock}'
+
+gemnasium-python-dependency_scanning:
+ extends:
+ - .ds-analyzer
+ - .cyclonedx-reports
+ variables:
+ DS_ANALYZER_NAME: "gemnasium-python"
+ rules:
+ - if: $DEPENDENCY_SCANNING_DISABLED
+ when: never
+ - if: $DS_EXCLUDED_ANALYZERS =~ /gemnasium-python/
+ when: never
+
+ # Add the job to merge request pipelines if there's an open merge request.
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-python-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-python-shared-rule, exists]
+ # Support passing of $PIP_REQUIREMENTS_FILE
+ # See https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#configuring-specific-analyzers-used-by-dependency-scanning
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $PIP_REQUIREMENTS_FILE &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $PIP_REQUIREMENTS_FILE
+
+ # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
+ - if: $CI_OPEN_MERGE_REQUESTS
+ when: never
+
+ # Add the job to branch pipelines.
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ exists: !reference [.gemnasium-python-shared-rule, exists]
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/
+ exists: !reference [.gemnasium-python-shared-rule, exists]
+ # Support passing of $PIP_REQUIREMENTS_FILE
+ # See https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#configuring-specific-analyzers-used-by-dependency-scanning
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $PIP_REQUIREMENTS_FILE &&
+ $CI_GITLAB_FIPS_MODE == "true"
+ variables:
+ DS_IMAGE_SUFFIX: "-fips"
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
+ $PIP_REQUIREMENTS_FILE
+
+bundler-audit-dependency_scanning:
+ extends: .ds-analyzer
+ variables:
+ DS_ANALYZER_NAME: "bundler-audit"
+ DS_MAJOR_VERSION: 2
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/347491"
+ - exit 1
+ rules:
+ - when: never
+
+retire-js-dependency_scanning:
+ extends: .ds-analyzer
+ variables:
+ DS_ANALYZER_NAME: "retire.js"
+ DS_MAJOR_VERSION: 2
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/289830"
+ - exit 1
+ rules:
+ - when: never
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 1a2a8b4edb4..78fe108e8b9 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.33.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.37.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
index cb8818357a2..bc2e1fed0d4 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.33.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.37.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/License-Scanning.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/License-Scanning.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..e47f669c2e2
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/License-Scanning.latest.gitlab-ci.yml
@@ -0,0 +1,48 @@
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml
+
+# Read more about this feature here: https://docs.gitlab.com/ee/user/compliance/license_compliance/index.html
+#
+# Configure license scanning with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/index.html).
+# List of available variables: https://docs.gitlab.com/ee/user/compliance/license_compliance/#available-variables
+
+variables:
+ # Setting this variable will affect all Security templates
+ # (SAST, Dependency Scanning, ...)
+ SECURE_ANALYZERS_PREFIX: "$CI_TEMPLATE_REGISTRY_HOST/security-products"
+
+ LICENSE_MANAGEMENT_SETUP_CMD: '' # If needed, specify a command to setup your environment with a custom package manager.
+ LICENSE_MANAGEMENT_VERSION: 4
+
+license_scanning:
+ stage: test
+ image:
+ name: "$SECURE_ANALYZERS_PREFIX/license-finder:$LICENSE_MANAGEMENT_VERSION"
+ entrypoint: [""]
+ variables:
+ LM_REPORT_VERSION: '2.1'
+ SETUP_CMD: $LICENSE_MANAGEMENT_SETUP_CMD
+ allow_failure: true
+ script:
+ - /run.sh analyze .
+ artifacts:
+ reports:
+ license_scanning: gl-license-scanning-report.json
+ dependencies: []
+ rules:
+ - if: $LICENSE_MANAGEMENT_DISABLED
+ when: never
+
+ # Add the job to merge request pipelines if there's an open merge request.
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $GITLAB_FEATURES =~ /\blicense_scanning\b/
+
+ # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
+ - if: $CI_OPEN_MERGE_REQUESTS
+ when: never
+
+ # Add the job to branch pipelines.
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\blicense_scanning\b/
diff --git a/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
index dd164c00724..a6d47e31de2 100644
--- a/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
@@ -36,19 +36,12 @@ sast:
bandit-sast:
extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 2
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.4"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /bandit/
- when: never
- - if: $CI_COMMIT_BRANCH
- exists:
- - '**/*.py'
+ - when: never
brakeman-sast:
extends: .sast-analyzer
@@ -69,23 +62,12 @@ brakeman-sast:
eslint-sast:
extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 2
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.4"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /eslint/
- when: never
- - if: $CI_COMMIT_BRANCH
- exists:
- - '**/*.html'
- - '**/*.js'
- - '**/*.jsx'
- - '**/*.ts'
- - '**/*.tsx'
+ - when: never
flawfinder-sast:
extends: .sast-analyzer
@@ -125,19 +107,12 @@ kubesec-sast:
gosec-sast:
extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 3
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.4"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /gosec/
- when: never
- - if: $CI_COMMIT_BRANCH
- exists:
- - '**/*.go'
+ - when: never
.mobsf-sast:
extends: .sast-analyzer
@@ -261,6 +236,8 @@ semgrep-sast:
- '**/*.c'
- '**/*.go'
- '**/*.java'
+ - '**/*.cs'
+ - '**/*.html'
sobelow-sast:
extends: .sast-analyzer
@@ -297,6 +274,5 @@ spotbugs-sast:
- if: $CI_COMMIT_BRANCH
exists:
- '**/*.groovy'
- - '**/*.java'
- '**/*.scala'
- '**/*.kt'
diff --git a/lib/gitlab/ci/templates/Jobs/SAST.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/SAST.latest.gitlab-ci.yml
index c6938920ea4..c0ca821ebff 100644
--- a/lib/gitlab/ci/templates/Jobs/SAST.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/SAST.latest.gitlab-ci.yml
@@ -36,24 +36,12 @@ sast:
bandit-sast:
extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 2
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.3"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /bandit/
- when: never
- - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Add the job to merge request pipelines if there's an open merge request.
- exists:
- - '**/*.py'
- - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
- when: never
- - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
- exists:
- - '**/*.py'
+ - when: never
brakeman-sast:
extends: .sast-analyzer
@@ -80,32 +68,12 @@ brakeman-sast:
eslint-sast:
extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 2
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
+ script:
+ - echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.3"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /eslint/
- when: never
- - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Add the job to merge request pipelines if there's an open merge request.
- exists:
- - '**/*.html'
- - '**/*.js'
- - '**/*.jsx'
- - '**/*.ts'
- - '**/*.tsx'
- - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
- when: never
- - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
- exists:
- - '**/*.html'
- - '**/*.js'
- - '**/*.jsx'
- - '**/*.ts'
- - '**/*.tsx'
+ - when: never
flawfinder-sast:
extends: .sast-analyzer
@@ -138,6 +106,15 @@ flawfinder-sast:
- '**/*.cp'
- '**/*.cxx'
+gosec-sast:
+ extends: .sast-analyzer
+ script:
+ - echo "This job was deprecated in GitLab 15.0 and removed in GitLab 15.2"
+ - echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/352554"
+ - exit 1
+ rules:
+ - when: never
+
kubesec-sast:
extends: .sast-analyzer
image:
@@ -159,27 +136,6 @@ kubesec-sast:
- if: $CI_COMMIT_BRANCH &&
$SCAN_KUBERNETES_MANIFESTS == 'true'
-gosec-sast:
- extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE"
- variables:
- SAST_ANALYZER_IMAGE_TAG: 3
- SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
- rules:
- - if: $SAST_DISABLED
- when: never
- - if: $SAST_EXCLUDED_ANALYZERS =~ /gosec/
- when: never
- - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Add the job to merge request pipelines if there's an open merge request.
- exists:
- - '**/*.go'
- - if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
- when: never
- - if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
- exists:
- - '**/*.go'
-
.mobsf-sast:
extends: .sast-analyzer
image:
@@ -323,7 +279,7 @@ semgrep-sast:
image:
name: "$SAST_ANALYZER_IMAGE"
variables:
- SERACH_MAX_DEPTH: 20
+ SEARCH_MAX_DEPTH: 20
SAST_ANALYZER_IMAGE_TAG: 3
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/semgrep:$SAST_ANALYZER_IMAGE_TAG$SAST_IMAGE_SUFFIX"
rules:
@@ -341,6 +297,8 @@ semgrep-sast:
- '**/*.c'
- '**/*.go'
- '**/*.java'
+ - '**/*.html'
+ - '**/*.cs'
- if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
when: never
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
@@ -353,6 +311,8 @@ semgrep-sast:
- '**/*.c'
- '**/*.go'
- '**/*.java'
+ - '**/*.html'
+ - '**/*.cs'
sobelow-sast:
extends: .sast-analyzer
@@ -394,7 +354,6 @@ spotbugs-sast:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # Add the job to merge request pipelines if there's an open merge request.
exists:
- '**/*.groovy'
- - '**/*.java'
- '**/*.scala'
- '**/*.kt'
- if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
@@ -402,6 +361,5 @@ spotbugs-sast:
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
exists:
- '**/*.groovy'
- - '**/*.java'
- '**/*.scala'
- '**/*.kt'
diff --git a/lib/gitlab/ci/templates/Katalon.gitlab-ci.yml b/lib/gitlab/ci/templates/Katalon.gitlab-ci.yml
new file mode 100644
index 00000000000..c8939c8f5a2
--- /dev/null
+++ b/lib/gitlab/ci/templates/Katalon.gitlab-ci.yml
@@ -0,0 +1,65 @@
+# This template is provided and maintained by Katalon, an official Technology Partner with GitLab.
+#
+# Use this template to run a Katalon Studio test from this repository.
+# You can:
+# - Copy and paste this template into a new `.gitlab-ci.yml` file.
+# - Add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# In either case, you must also select which job you want to run, `.katalon_tests`
+# or `.katalon_tests_with_artifacts` (see configuration below), and add that configuration
+# to a new job with `extends:`. For example:
+#
+# Katalon-tests:
+# extends:
+# - .katalon_tests_with_artifacts
+#
+# Requirements:
+# - A Katalon Studio project with the content saved in the root GitLab repository folder.
+# - An active KRE license.
+# - A valid Katalon API key.
+#
+# CI/CD variables, set in the project CI/CD settings:
+# - KATALON_TEST_SUITE_PATH: The default path is `Test Suites/<Your Test Suite Name>`.
+# Defines which test suite to run.
+# - KATALON_API_KEY: The Katalon API key.
+# - KATALON_PROJECT_DIR: Optional. Add if the project is in another location.
+# - KATALON_ORG_ID: Optional. Add if you are part of multiple Katalon orgs.
+# Set to the Org ID that has KRE licenses assigned. For more info on the Org ID,
+# see https://support.katalon.com/hc/en-us/articles/4724459179545-How-to-get-Organization-ID-
+
+.katalon_tests:
+ # Use the latest version of the Katalon Runtime Engine. You can also use other versions of the
+ # Katalon Runtime Engine by specifying another tag, for example `katalonstudio/katalon:8.1.2`
+ # or `katalonstudio/katalon:8.3.0`.
+ image: 'katalonstudio/katalon'
+ services:
+ - docker:dind
+ variables:
+ # Specify the Katalon Studio project directory. By default, it is stored under the root project folder.
+ KATALON_PROJECT_DIR: $CI_PROJECT_DIR
+
+ # The following bash script has two different versions, one if you set the KATALON_ORG_ID
+ # CI/CD variable, and the other if you did not set it. If you have more than one org in
+ # admin.katalon.com you must set the KATALON_ORG_ID variable with an ORG ID or
+ # the Katalon Test Suite fails to run.
+ #
+ # You can update or add additional `katalonc` commands below. To see all of the arguments
+ # `katalonc` supports, go to https://docs.katalon.com/katalon-studio/docs/console-mode-execution.html
+ script:
+ - |-
+ if [[ $KATALON_ORG_ID == "" ]]; then
+ katalonc.sh -projectPath=$KATALON_PROJECT_DIR -apiKey=$KATALON_API_KEY -browserType="Chrome" -retry=0 -statusDelay=20 -testSuitePath="$KATALON_TEST_SUITE_PATH" -reportFolder=Reports/
+ else
+ katalonc.sh -projectPath=$KATALON_PROJECT_DIR -apiKey=$KATALON_API_KEY -browserType="Chrome" -retry=0 -statusDelay=20 -orgID=$KATALON_ORG_ID -testSuitePath="$KATALON_TEST_SUITE_PATH" -reportFolder=Reports/
+ fi
+
+# Upload the artifacts and make the junit report accessible under the Pipeline Tests
+.katalon_tests_with_artifacts:
+ extends: .katalon_tests
+ artifacts:
+ when: always
+ paths:
+ - Reports/
+ reports:
+ junit:
+ Reports/*/*/*/*.xml
diff --git a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
index 3d7883fb87a..79a08c33fdf 100644
--- a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
@@ -11,12 +11,12 @@
#
# Requirements:
# - A `test` stage to be present in the pipeline.
-# - You must define the image to be scanned in the DOCKER_IMAGE variable. If DOCKER_IMAGE is the
+# - You must define the image to be scanned in the CS_IMAGE variable. If CS_IMAGE is the
# same as $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG, you can skip this.
-# - Container registry credentials defined by `DOCKER_USER` and `DOCKER_PASSWORD` variables if the
+# - Container registry credentials defined by `CS_REGISTRY_USER` and `CS_REGISTRY_PASSWORD` variables if the
# image to be scanned is in a private registry.
# - For auto-remediation, a readable Dockerfile in the root of the project or as defined by the
-# DOCKERFILE_PATH variable.
+# CS_DOCKERFILE_PATH variable.
#
# Configure container scanning with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/index.html).
# List of available variables: https://docs.gitlab.com/ee/user/application_security/container_scanning/#available-variables
diff --git a/lib/gitlab/ci/templates/Security/Container-Scanning.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Container-Scanning.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..f7b1d12b3b3
--- /dev/null
+++ b/lib/gitlab/ci/templates/Security/Container-Scanning.latest.gitlab-ci.yml
@@ -0,0 +1,68 @@
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
+
+# Use this template to enable container scanning in your project.
+# You should add this template to an existing `.gitlab-ci.yml` file by using the `include:`
+# keyword.
+# The template should work without modifications but you can customize the template settings if
+# needed: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
+#
+# Requirements:
+# - A `test` stage to be present in the pipeline.
+# - You must define the image to be scanned in the CS_IMAGE variable. If CS_IMAGE is the
+# same as $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG, you can skip this.
+# - Container registry credentials defined by `CS_REGISTRY_USER` and `CS_REGISTRY_PASSWORD` variables if the
+# image to be scanned is in a private registry.
+# - For auto-remediation, a readable Dockerfile in the root of the project or as defined by the
+# CS_DOCKERFILE_PATH variable.
+#
+# Configure container scanning with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/index.html).
+# List of available variables: https://docs.gitlab.com/ee/user/application_security/container_scanning/#available-variables
+
+variables:
+ CS_ANALYZER_IMAGE: "$CI_TEMPLATE_REGISTRY_HOST/security-products/container-scanning:5"
+
+container_scanning:
+ image: "$CS_ANALYZER_IMAGE$CS_IMAGE_SUFFIX"
+ stage: test
+ variables:
+ # To provide a `vulnerability-allowlist.yml` file, override the GIT_STRATEGY variable in your
+ # `.gitlab-ci.yml` file and set it to `fetch`.
+ # For details, see the following links:
+ # https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html#overriding-the-container-scanning-template
+ # https://docs.gitlab.com/ee/user/application_security/container_scanning/#vulnerability-allowlisting
+ GIT_STRATEGY: none
+ allow_failure: true
+ artifacts:
+ reports:
+ container_scanning: gl-container-scanning-report.json
+ dependency_scanning: gl-dependency-scanning-report.json
+ paths: [gl-container-scanning-report.json, gl-dependency-scanning-report.json]
+ dependencies: []
+ script:
+ - gtcs scan
+ rules:
+ - if: $CONTAINER_SCANNING_DISABLED
+ when: never
+
+ # Add the job to merge request pipelines if there's an open merge request.
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" &&
+ $CI_GITLAB_FIPS_MODE == "true" &&
+ $CS_ANALYZER_IMAGE !~ /-(fips|ubi)\z/
+ variables:
+ CS_IMAGE_SUFFIX: -fips
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+
+ # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
+ - if: $CI_OPEN_MERGE_REQUESTS
+ when: never
+
+ # Add the job to branch pipelines.
+ - if: $CI_COMMIT_BRANCH &&
+ $CI_GITLAB_FIPS_MODE == "true" &&
+ $CS_ANALYZER_IMAGE !~ /-(fips|ubi)\z/
+ variables:
+ CS_IMAGE_SUFFIX: -fips
+ - if: $CI_COMMIT_BRANCH
diff --git a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
index 3a956ebfc49..9a40a23b276 100644
--- a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
@@ -9,7 +9,7 @@
# There is a more opinionated template which we suggest the users to abide,
# which is the lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
image:
- name: "$CI_TEMPLATE_REGISTRY_HOST/gitlab-org/terraform-images/releases/terraform:1.1.9"
+ name: "$CI_TEMPLATE_REGISTRY_HOST/gitlab-org/terraform-images/releases/1.1:v0.43.0"
variables:
TF_ROOT: ${CI_PROJECT_DIR} # The relative path to the root directory of the Terraform project
diff --git a/lib/gitlab/ci/templates/npm.gitlab-ci.yml b/lib/gitlab/ci/templates/npm.gitlab-ci.yml
index 64c784f43cb..fb0d300338b 100644
--- a/lib/gitlab/ci/templates/npm.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/npm.gitlab-ci.yml
@@ -38,7 +38,7 @@ publish:
# Compare the version in package.json to all published versions.
# If the package.json version has not yet been published, run `npm publish`.
- |
- if [[ $(npm view "${NPM_PACKAGE_NAME}" versions) != *"'${NPM_PACKAGE_VERSION}'"* ]]; then
+ if [[ "$(npm view ${NPM_PACKAGE_NAME} versions)" != *"'${NPM_PACKAGE_VERSION}'"* ]]; then
npm publish
echo "Successfully published version ${NPM_PACKAGE_VERSION} of ${NPM_PACKAGE_NAME} to GitLab's NPM registry: ${CI_PROJECT_URL}/-/packages"
else
diff --git a/lib/gitlab/ci/trace.rb b/lib/gitlab/ci/trace.rb
index 95a60b852b8..c5664ef1cfb 100644
--- a/lib/gitlab/ci/trace.rb
+++ b/lib/gitlab/ci/trace.rb
@@ -23,7 +23,6 @@ module Gitlab
attr_reader :job
- delegate :old_trace, to: :job
delegate :can_attempt_archival_now?, :increment_archival_attempts!,
:archival_attempts_message, :archival_attempts_available?, to: :trace_metadata
@@ -82,7 +81,7 @@ module Gitlab
end
def live?
- job.trace_chunks.any? || current_path.present? || old_trace.present?
+ job.trace_chunks.any? || current_path.present?
end
def read(&block)
@@ -111,7 +110,6 @@ module Gitlab
# Erase the live trace
erase_trace_chunks!
FileUtils.rm_f(current_path) if current_path # Remove a trace file of a live trace
- job.erase_old_trace! if job.has_old_trace? # Remove a trace in database of a live trace
ensure
@current_path = nil
end
@@ -162,8 +160,6 @@ module Gitlab
Gitlab::Ci::Trace::ChunkedIO.new(job)
elsif current_path
File.open(current_path, "rb")
- elsif old_trace
- StringIO.new(old_trace)
end
end
@@ -210,11 +206,6 @@ module Gitlab
archive_stream!(stream)
FileUtils.rm(current_path)
end
- elsif old_trace
- StringIO.new(old_trace, 'rb').tap do |stream|
- archive_stream!(stream)
- job.erase_old_trace!
- end
end
end
diff --git a/lib/gitlab/ci/variables/builder.rb b/lib/gitlab/ci/variables/builder.rb
index 95dff83506d..528d72c9bcc 100644
--- a/lib/gitlab/ci/variables/builder.rb
+++ b/lib/gitlab/ci/variables/builder.rb
@@ -118,7 +118,7 @@ module Gitlab
def predefined_variables(job)
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'CI_JOB_NAME', value: job.name)
- variables.append(key: 'CI_JOB_STAGE', value: job.stage)
+ variables.append(key: 'CI_JOB_STAGE', value: job.stage_name)
variables.append(key: 'CI_JOB_MANUAL', value: 'true') if job.action?
variables.append(key: 'CI_PIPELINE_TRIGGERED', value: 'true') if job.trigger_request
@@ -127,7 +127,7 @@ module Gitlab
# legacy variables
variables.append(key: 'CI_BUILD_NAME', value: job.name)
- variables.append(key: 'CI_BUILD_STAGE', value: job.stage)
+ variables.append(key: 'CI_BUILD_STAGE', value: job.stage_name)
variables.append(key: 'CI_BUILD_TRIGGERED', value: 'true') if job.trigger_request
variables.append(key: 'CI_BUILD_MANUAL', value: 'true') if job.action?
end
diff --git a/lib/gitlab/ci/variables/helpers.rb b/lib/gitlab/ci/variables/helpers.rb
index 7cc727bb3ea..16e3afd8620 100644
--- a/lib/gitlab/ci/variables/helpers.rb
+++ b/lib/gitlab/ci/variables/helpers.rb
@@ -6,24 +6,24 @@ module Gitlab
module Helpers
class << self
def merge_variables(current_vars, new_vars)
- current_vars = transform_from_yaml_variables(current_vars)
- new_vars = transform_from_yaml_variables(new_vars)
+ return current_vars if new_vars.blank?
- transform_to_yaml_variables(
- current_vars.merge(new_vars)
- )
- end
+ current_vars = transform_to_array(current_vars) if current_vars.is_a?(Hash)
+ new_vars = transform_to_array(new_vars) if new_vars.is_a?(Hash)
- def transform_to_yaml_variables(vars)
- vars.to_h.map do |key, value|
- { key: key.to_s, value: value, public: true }
- end
+ (new_vars + current_vars).uniq { |var| var[:key] }
end
- def transform_from_yaml_variables(vars)
- return vars.stringify_keys.transform_values(&:to_s) if vars.is_a?(Hash)
+ def transform_to_array(vars)
+ return [] if vars.blank?
- vars.to_a.to_h { |var| [var[:key].to_s, var[:value]] }
+ vars.map do |key, data|
+ if data.is_a?(Hash)
+ { key: key.to_s, **data.except(:key) }
+ else
+ { key: key.to_s, value: data }
+ end
+ end
end
def inherit_yaml_variables(from:, to:, inheritance:)
@@ -35,7 +35,7 @@ module Gitlab
def apply_inheritance(variables, inheritance)
case inheritance
when true then variables
- when false then {}
+ when false then []
when Array then variables.select { |var| inheritance.include?(var[:key]) }
end
end
diff --git a/lib/gitlab/ci/yaml_processor/feature_flags.rb b/lib/gitlab/ci/yaml_processor/feature_flags.rb
index f03db9d0e6b..50d37f6e4a0 100644
--- a/lib/gitlab/ci/yaml_processor/feature_flags.rb
+++ b/lib/gitlab/ci/yaml_processor/feature_flags.rb
@@ -5,10 +5,10 @@ module Gitlab
class YamlProcessor
module FeatureFlags
ACTOR_KEY = 'ci_yaml_processor_feature_flag_actor'
+ CORRECT_USAGE_KEY = 'ci_yaml_processor_feature_flag_correct_usage'
NO_ACTOR_VALUE = :no_actor
-
- NoActorError = Class.new(StandardError)
NO_ACTOR_MESSAGE = "Actor not set. Ensure to call `enabled?` inside `with_actor` block"
+ NoActorError = Class.new(StandardError)
class << self
# Cache a feature flag actor as thread local variable so
@@ -31,6 +31,15 @@ module Gitlab
::Feature.enabled?(feature_flag, current_actor)
end
+ def ensure_correct_usage
+ previous = Thread.current[CORRECT_USAGE_KEY]
+ Thread.current[CORRECT_USAGE_KEY] = true
+
+ yield
+ ensure
+ Thread.current[CORRECT_USAGE_KEY] = previous
+ end
+
private
def current_actor
@@ -39,10 +48,22 @@ module Gitlab
value
rescue NoActorError => e
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
+ handle_missing_actor(e)
nil
end
+
+ def handle_missing_actor(exception)
+ if ensure_correct_usage?
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(exception)
+ else
+ Gitlab::ErrorTracking.track_exception(exception)
+ end
+ end
+
+ def ensure_correct_usage?
+ Thread.current[CORRECT_USAGE_KEY] == true
+ end
end
end
end
diff --git a/lib/gitlab/ci/yaml_processor/result.rb b/lib/gitlab/ci/yaml_processor/result.rb
index 4bd1ac3b67f..f203f88442d 100644
--- a/lib/gitlab/ci/yaml_processor/result.rb
+++ b/lib/gitlab/ci/yaml_processor/result.rb
@@ -43,7 +43,7 @@ module Gitlab
end
def root_variables
- @root_variables ||= transform_to_yaml_variables(variables)
+ @root_variables ||= transform_to_array(variables)
end
def jobs
@@ -70,7 +70,7 @@ module Gitlab
environment: job[:environment_name],
coverage_regex: job[:coverage],
# yaml_variables is calculated with using job_variables in Seed::Build
- job_variables: transform_to_yaml_variables(job[:job_variables]),
+ job_variables: transform_to_array(job[:job_variables]),
root_variables_inheritance: job[:root_variables_inheritance],
needs_attributes: job.dig(:needs, :job),
interruptible: job[:interruptible],
@@ -114,7 +114,7 @@ module Gitlab
Gitlab::Ci::Variables::Helpers.inherit_yaml_variables(
from: root_variables,
- to: transform_to_yaml_variables(job[:job_variables]),
+ to: job[:job_variables],
inheritance: job.fetch(:root_variables_inheritance, true)
)
end
@@ -137,8 +137,8 @@ module Gitlab
job[:release]
end
- def transform_to_yaml_variables(variables)
- ::Gitlab::Ci::Variables::Helpers.transform_to_yaml_variables(variables)
+ def transform_to_array(variables)
+ ::Gitlab::Ci::Variables::Helpers.transform_to_array(variables)
end
end
end