diff options
Diffstat (limited to 'spec/lib/gitlab/ci/parsers/security')
-rw-r--r-- | spec/lib/gitlab/ci/parsers/security/common_spec.rb | 29 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb | 278 |
2 files changed, 204 insertions, 103 deletions
diff --git a/spec/lib/gitlab/ci/parsers/security/common_spec.rb b/spec/lib/gitlab/ci/parsers/security/common_spec.rb index dfc5dec1481..6495d1f654b 100644 --- a/spec/lib/gitlab/ci/parsers/security/common_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/common_spec.rb @@ -292,7 +292,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do expect(scans.map(&:status).all?('success')).to be(true) expect(scans.map(&:start_time).all?('placeholder-value')).to be(true) expect(scans.map(&:end_time).all?('placeholder-value')).to be(true) - expect(scans.size).to eq(3) + expect(scans.size).to eq(7) expect(scans.first).to be_a(::Gitlab::Ci::Reports::Security::Scan) end @@ -348,22 +348,29 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do it 'returns links object for each finding', :aggregate_failures do links = report.findings.flat_map(&:links) - expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030']) - expect(links.map(&:name)).to match_array([nil, 'CVE-1030']) - expect(links.size).to eq(2) + expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030', + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2137", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2138", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2139", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2140"]) + expect(links.map(&:name)).to match_array([nil, nil, nil, nil, nil, 'CVE-1030']) + expect(links.size).to eq(6) expect(links.first).to be_a(::Gitlab::Ci::Reports::Security::Link) end end describe 'parsing evidence' do - it 'returns evidence object for each finding', :aggregate_failures do - evidences = report.findings.map(&:evidence) + RSpec::Matchers.define_negated_matcher :have_values, :be_empty - expect(evidences.first.data).not_to be_empty - expect(evidences.first.data["summary"]).to match(/The Origin header was changed/) - expect(evidences.size).to eq(3) - expect(evidences.compact.size).to eq(2) - expect(evidences.first).to be_a(::Gitlab::Ci::Reports::Security::Evidence) + it 'returns evidence object for each finding', :aggregate_failures do + all_evidences = report.findings.map(&:evidence) + evidences = all_evidences.compact + data = evidences.map(&:data) + summaries = evidences.map { |e| e.data["summary"] } + + expect(all_evidences.size).to eq(7) + expect(evidences.size).to eq(2) + expect(evidences).to all( be_a(::Gitlab::Ci::Reports::Security::Evidence) ) + expect(data).to all( have_values ) + expect(summaries).to all( match(/The Origin header was changed/) ) end end diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb index f6409c8b01f..d06077d69b6 100644 --- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb @@ -5,6 +5,8 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let_it_be(:project) { create(:project) } + let(:supported_dast_versions) { described_class::SUPPORTED_VERSIONS[:dast].join(', ') } + let(:scanner) do { 'id' => 'gemnasium', @@ -22,7 +24,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do expect(described_class::SUPPORTED_VERSIONS.keys).to eq(described_class::DEPRECATED_VERSIONS.keys) end - context 'files under schema path are explicitly listed' do + context 'when a schema JSON file exists for a particular report type version' do # We only care about the part that comes before report-format.json # https://rubular.com/r/N8Juz7r8hYDYgD filename_regex = /(?<report_type>[-\w]*)\-report-format.json/ @@ -36,14 +38,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do matches = filename_regex.match(file) report_type = matches[:report_type].tr("-", "_").to_sym - it "#{report_type} #{version}" do + it "#{report_type} #{version} is in the constant" do expect(described_class::SUPPORTED_VERSIONS[report_type]).to include(version) end end end end - context 'every SUPPORTED_VERSION has a corresponding JSON file' do + context 'when every SUPPORTED_VERSION has a corresponding JSON file' do described_class::SUPPORTED_VERSIONS.each_key do |report_type| # api_fuzzing is covered by DAST schema next if report_type == :api_fuzzing @@ -66,7 +68,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -77,7 +79,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to be_truthy } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version @@ -104,9 +106,19 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do context 'when given a deprecated schema version' do let(:report_type) { :dast } + let(:deprecations_hash) do + { + dast: %w[10.0.0] + } + end + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } - context 'and the report passes schema validation' do + before do + stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) + end + + context 'when the report passes schema validation' do let(:report_data) do { 'version' => '10.0.0', @@ -131,8 +143,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end - context 'and the report does not pass schema validation' do - context 'and enforce_security_report_validation is enabled' do + context 'when the report does not pass schema validation' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end @@ -146,7 +158,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to be_falsey } end - context 'and enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end @@ -166,12 +178,12 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { "12.37.0" } - context 'if enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -196,14 +208,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - context 'and scanner information is empty' do + context 'when scanner information is empty' do let(:scanner) { {} } it 'logs related information' do @@ -235,12 +247,12 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end - context 'if enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -251,7 +263,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to be_truthy } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version @@ -262,6 +274,30 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end end + + context 'when not given a schema version' do + let(:report_type) { :dast } + let(:report_version) { nil } + let(:report_data) do + { + 'vulnerabilities' => [] + } + end + + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + it { is_expected.to be_falsey } + + context 'when enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + it { is_expected.to be_truthy } + end + end end describe '#errors' do @@ -271,7 +307,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -279,19 +315,17 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_errors) { [] } - - it { is_expected.to match_array(expected_errors) } + it { is_expected.to be_empty } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - context 'if enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: project) end @@ -305,23 +339,31 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to match_array(expected_errors) } end - context 'if enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end - let(:expected_errors) { [] } - - it { is_expected.to match_array(expected_errors) } + it { is_expected.to be_empty } end end end context 'when given a deprecated schema version' do let(:report_type) { :dast } + let(:deprecations_hash) do + { + dast: %w[10.0.0] + } + end + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } - context 'and the report passes schema validation' do + before do + stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) + end + + context 'when the report passes schema validation' do let(:report_data) do { 'version' => '10.0.0', @@ -329,13 +371,11 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_errors) { [] } - - it { is_expected.to match_array(expected_errors) } + it { is_expected.to be_empty } end - context 'and the report does not pass schema validation' do - context 'and enforce_security_report_validation is enabled' do + context 'when the report does not pass schema validation' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end @@ -356,7 +396,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to match_array(expected_errors) } end - context 'and enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end @@ -367,9 +407,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_errors) { [] } - - it { is_expected.to match_array(expected_errors) } + it { is_expected.to be_empty } end end end @@ -378,12 +416,12 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { "12.37.0" } - context 'if enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -393,14 +431,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:expected_errors) do [ - "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 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" + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}" ] end it { is_expected.to match_array(expected_errors) } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version @@ -409,7 +447,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:expected_errors) do [ - "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 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", + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}", "root is missing required keys: vulnerabilities" ] end @@ -418,12 +456,12 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end - context 'if enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -431,22 +469,45 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_errors) { [] } - - it { is_expected.to match_array(expected_errors) } + it { is_expected.to be_empty } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - let(:expected_errors) { [] } + it { is_expected.to be_empty } + end + end + end - it { is_expected.to match_array(expected_errors) } + context 'when not given a schema version' do + let(:report_type) { :dast } + let(:report_version) { nil } + let(:report_data) do + { + 'vulnerabilities' => [] + } + end + + let(:expected_errors) do + [ + "root is missing required keys: version", + "Report version not provided, dast report type supports versions: #{supported_dast_versions}" + ] + end + + it { is_expected.to match_array(expected_errors) } + + context 'when enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) end + + it { is_expected.to be_empty } end end end @@ -458,9 +519,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } - let(:expected_deprecation_warnings) { [] } - - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -468,30 +527,40 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - it { is_expected.to match_array(expected_deprecation_warnings) } + it { is_expected.to be_empty } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - it { is_expected.to match_array(expected_deprecation_warnings) } + it { is_expected.to be_empty } end end context 'when given a deprecated schema version' do let(:report_type) { :dast } + let(:deprecations_hash) do + { + dast: %w[V2.7.0] + } + end + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } let(:expected_deprecation_warnings) do [ - "Version V2.7.0 for report type dast has been deprecated, supported versions for this report type are: 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" + "Version V2.7.0 for report type dast has been deprecated, supported versions for this report type are: #{supported_dast_versions}" ] end - context 'and the report passes schema validation' do + before do + stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) + end + + context 'when the report passes schema validation' do let(:report_data) do { 'version' => report_version, @@ -502,7 +571,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do it { is_expected.to match_array(expected_deprecation_warnings) } end - context 'and the report does not pass schema validation' do + context 'when the report does not pass schema validation' do let(:report_data) do { 'version' => 'V2.7.0' @@ -535,7 +604,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -543,29 +612,25 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - context 'if enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: project) end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end - context 'if enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end @@ -583,38 +648,44 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do context 'when given a deprecated schema version' do let(:report_type) { :dast } + let(:deprecations_hash) do + { + dast: %w[V2.7.0] + } + end + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } - context 'and the report passes schema validation' do + before do + stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) + end + + context 'when the report passes schema validation' do let(:report_data) do { 'vulnerabilities' => [] } end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end - context 'and the report does not pass schema validation' do + context 'when the report does not pass schema validation' do let(:report_data) do { 'version' => 'V2.7.0' } end - context 'and enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end - context 'and enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end @@ -635,12 +706,12 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:report_type) { :dast } let(:report_version) { "12.37.0" } - context 'if enforce_security_report_validation is enabled' do + context 'when enforce_security_report_validation is enabled' do before do stub_feature_flags(enforce_security_report_validation: true) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -648,30 +719,26 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version } end - let(:expected_warnings) { [] } - - it { is_expected.to match_array(expected_warnings) } + it { is_expected.to be_empty } end end - context 'if enforce_security_report_validation is disabled' do + context 'when enforce_security_report_validation is disabled' do before do stub_feature_flags(enforce_security_report_validation: false) end - context 'and the report is valid' do + context 'when the report is valid' do let(:report_data) do { 'version' => report_version, @@ -681,14 +748,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:expected_warnings) do [ - "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 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" + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}" ] end it { is_expected.to match_array(expected_warnings) } end - context 'and the report is invalid' do + context 'when the report is invalid' do let(:report_data) do { 'version' => report_version @@ -697,7 +764,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:expected_warnings) do [ - "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 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", + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}", "root is missing required keys: vulnerabilities" ] end @@ -706,5 +773,32 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end end + + context 'when not given a schema version' do + let(:report_type) { :dast } + let(:report_version) { nil } + let(:report_data) do + { + 'vulnerabilities' => [] + } + end + + it { is_expected.to be_empty } + + context 'when enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:expected_warnings) do + [ + "root is missing required keys: version", + "Report version not provided, dast report type supports versions: #{supported_dast_versions}" + ] + end + + it { is_expected.to match_array(expected_warnings) } + end + end end end |