From 08d0e69149794af1e3c6e6b14724ff46e2d154c4 Mon Sep 17 00:00:00 2001
From: Philip Cunningham <pcunningham@gitlab.com>
Date: Mon, 29 Mar 2021 07:39:19 +0000
Subject: [PATCH] Inject additional site profile config into CI yaml

- Extend services
- Update specs
---
 .../ci/dast_scan_ci_configuration_service.rb  |  7 +-
 .../params_create_service.rb                  | 23 +++++-
 ...dast_scan_ci_configuration_service_spec.rb | 12 ++-
 .../services/ci/run_dast_scan_service_spec.rb | 80 ++++++++++++++-----
 .../create_service_spec.rb                    |  6 +-
 .../params_create_service_spec.rb             | 16 +++-
 ...can_pipeline_configuration_service_spec.rb | 18 +++--
 7 files changed, 127 insertions(+), 35 deletions(-)

diff --git a/ee/app/services/ci/dast_scan_ci_configuration_service.rb b/ee/app/services/ci/dast_scan_ci_configuration_service.rb
index 58948536f8373..47157507f12b5 100644
--- a/ee/app/services/ci/dast_scan_ci_configuration_service.rb
+++ b/ee/app/services/ci/dast_scan_ci_configuration_service.rb
@@ -8,7 +8,12 @@ module DastScanCiConfigurationService
       target_url: 'DAST_WEBSITE',
       use_ajax_spider: 'DAST_USE_AJAX_SPIDER',
       show_debug_messages: 'DAST_DEBUG',
-      full_scan_enabled: 'DAST_FULL_SCAN_ENABLED'
+      full_scan_enabled: 'DAST_FULL_SCAN_ENABLED',
+      excluded_urls: 'DAST_EXCLUDE_URLS',
+      auth_url: 'DAST_AUTH_URL',
+      auth_username_field: 'DAST_USERNAME_FIELD',
+      auth_password_field: 'DAST_PASSWORD_FIELD',
+      auth_username: 'DAST_USERNAME'
     }.freeze
 
     def self.execute(args)
diff --git a/ee/app/services/dast_on_demand_scans/params_create_service.rb b/ee/app/services/dast_on_demand_scans/params_create_service.rb
index 3b59aa1187e29..c014d38055937 100644
--- a/ee/app/services/dast_on_demand_scans/params_create_service.rb
+++ b/ee/app/services/dast_on_demand_scans/params_create_service.rb
@@ -5,11 +5,11 @@ class ParamsCreateService < BaseContainerService
     include Gitlab::Utils::StrongMemoize
 
     def execute
-      return ServiceResponse.error(message: 'Site Profile was not provided') unless dast_site.present?
+      return ServiceResponse.error(message: 'Dast site profile was not provided') unless dast_site_profile.present?
       return ServiceResponse.error(message: 'Cannot run active scan against unvalidated target') unless active_scan_allowed?
 
       ServiceResponse.success(
-        payload: default_config.merge(scanner_profile_config)
+        payload: default_config.merge(site_profile_config, scanner_profile_config)
       )
     end
 
@@ -33,7 +33,13 @@ def branch
 
     def dast_site
       strong_memoize(:dast_site) do
-        params[:dast_site_profile]&.dast_site
+        dast_site_profile&.dast_site
+      end
+    end
+
+    def dast_site_profile
+      strong_memoize(:dast_site_profile) do
+        params[:dast_site_profile]
       end
     end
 
@@ -56,6 +62,17 @@ def default_config
       }
     end
 
+    def site_profile_config
+      return {} unless dast_site_profile
+
+      {
+        excluded_urls: dast_site_profile.excluded_urls.join(','),
+        auth_username_field: dast_site_profile.auth_username_field,
+        auth_password_field: dast_site_profile.auth_password_field,
+        auth_username: dast_site_profile.auth_username
+      }
+    end
+
     def scanner_profile_config
       return {} unless dast_scanner_profile
 
diff --git a/ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb b/ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb
index b92b36a8fdc78..873cdf80458e1 100644
--- a/ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb
+++ b/ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb
@@ -14,7 +14,12 @@
           target_url: 'https://gitlab.local',
           use_ajax_spider: true,
           show_debug_messages: true,
-          full_scan_enabled: true
+          full_scan_enabled: true,
+          excluded_urls: 'https://gitlab.local/hello,https://gitlab.local/world',
+          auth_url: 'https://gitlab.local/login',
+          auth_username_field: 'session[username]',
+          auth_password_field: 'session[password]',
+          auth_username: 'tanuki'
         }
       end
 
@@ -32,6 +37,11 @@
           DAST_USE_AJAX_SPIDER: 'true'
           DAST_DEBUG: 'true'
           DAST_FULL_SCAN_ENABLED: 'true'
+          DAST_EXCLUDE_URLS: https://gitlab.local/hello,https://gitlab.local/world
+          DAST_AUTH_URL: https://gitlab.local/login
+          DAST_USERNAME_FIELD: session[username]
+          DAST_PASSWORD_FIELD: session[password]
+          DAST_USERNAME: tanuki
         YAML
       end
 
diff --git a/ee/spec/services/ci/run_dast_scan_service_spec.rb b/ee/spec/services/ci/run_dast_scan_service_spec.rb
index 3510b093d5ac6..bff3a480623ab 100644
--- a/ee/spec/services/ci/run_dast_scan_service_spec.rb
+++ b/ee/spec/services/ci/run_dast_scan_service_spec.rb
@@ -6,17 +6,36 @@
   let(:user) { create(:user) }
   let(:project) { create(:project, :repository, creator: user) }
   let(:branch) { project.default_branch }
+  let(:spider_timeout) { 42 }
+  let(:target_timeout) { 21 }
   let(:target_url) { generate(:url) }
   let(:use_ajax_spider) { true }
   let(:show_debug_messages) { false }
   let(:full_scan_enabled) { true }
+  let(:excluded_urls) { "#{target_url}/hello,#{target_url}/world" }
+  let(:auth_url) { "#{target_url}/login" }
 
   before do
     stub_licensed_features(security_on_demand_scans: true)
   end
 
   describe '#execute' do
-    subject { described_class.new(project, user).execute(branch: branch, target_url: target_url, spider_timeout: 42, target_timeout: 21, use_ajax_spider: use_ajax_spider, show_debug_messages: show_debug_messages, full_scan_enabled: full_scan_enabled) }
+    subject do
+      described_class.new(project, user).execute(
+        branch: branch,
+        target_url: target_url,
+        spider_timeout: spider_timeout,
+        target_timeout: target_timeout,
+        use_ajax_spider: use_ajax_spider,
+        show_debug_messages: show_debug_messages,
+        full_scan_enabled: full_scan_enabled,
+        excluded_urls: excluded_urls,
+        auth_url: auth_url,
+        auth_username_field: 'session[username]',
+        auth_password_field: 'session[password]',
+        auth_username: 'tanuki'
+      )
+    end
 
     let(:status) { subject.status }
     let(:pipeline) { subject.payload }
@@ -90,46 +109,67 @@
 
       it 'creates a build with appropriate variables' do
         build = pipeline.builds.first
+
         expected_variables = [
           {
-            'key' => 'DAST_VERSION',
-            'value' => '1',
+            'key' => 'DAST_AUTH_URL',
+            'value' => auth_url,
             'public' => true
           }, {
-            'key' => 'SECURE_ANALYZERS_PREFIX',
-            'value' => 'registry.gitlab.com/gitlab-org/security-products/analyzers',
+            'key' => 'DAST_DEBUG',
+            'value' => 'false',
             'public' => true
           }, {
-            'key' => 'DAST_WEBSITE',
-            'value' => target_url,
+            'key' => 'DAST_EXCLUDE_URLS',
+            'value' => excluded_urls,
             'public' => true
-          },
-          {
+          }, {
+            'key' => 'DAST_FULL_SCAN_ENABLED',
+            'value' => 'true',
+            'public' => true
+          }, {
+            'key' => 'DAST_PASSWORD_FIELD',
+            'value' => 'session[password]',
+            'public' => true
+          }, {
             'key' => 'DAST_SPIDER_MINS',
-            'value' => '42',
+            'value' => spider_timeout.to_s,
             'public' => true
           }, {
             'key' => 'DAST_TARGET_AVAILABILITY_TIMEOUT',
-            'value' => '21',
+            'value' => target_timeout.to_s,
             'public' => true
           }, {
-            'key' => "DAST_USE_AJAX_SPIDER",
-            'public' => true,
-            'value' => 'true'
+            'key' => 'DAST_USERNAME',
+            'value' => 'tanuki',
+            'public' => true
           }, {
-            'key' => "DAST_DEBUG",
-            'public' => true,
-            'value' => 'false'
+            'key' => 'DAST_USERNAME_FIELD',
+            'value' => 'session[username]',
+            'public' => true
+          }, {
+            'key' => 'DAST_USE_AJAX_SPIDER',
+            'value' => 'true',
+            'public' => true
           }, {
-            'key' => "DAST_FULL_SCAN_ENABLED",
-            'public' => true,
-            'value' => 'true'
+            'key' => 'DAST_VERSION',
+            'value' => '1',
+            'public' => true
+          }, {
+            'key' => 'DAST_WEBSITE',
+            'value' => target_url,
+            'public' => true
           }, {
             'key' => 'GIT_STRATEGY',
             'value' => 'none',
             'public' => true
+          }, {
+            'key' => 'SECURE_ANALYZERS_PREFIX',
+            'value' => 'registry.gitlab.com/gitlab-org/security-products/analyzers',
+            'public' => true
           }
         ]
+
         expect(build.yaml_variables).to contain_exactly(*expected_variables)
       end
 
diff --git a/ee/spec/services/dast_on_demand_scans/create_service_spec.rb b/ee/spec/services/dast_on_demand_scans/create_service_spec.rb
index 4d539ca326010..969bcf622df64 100644
--- a/ee/spec/services/dast_on_demand_scans/create_service_spec.rb
+++ b/ee/spec/services/dast_on_demand_scans/create_service_spec.rb
@@ -51,7 +51,11 @@
 
         it 'delegates pipeline creation to Ci::RunDastScanService', :aggregate_failures do
           expected_params = {
-            branch: 'master',
+            auth_password_field: dast_site_profile.auth_password_field,
+            auth_username: dast_site_profile.auth_username,
+            auth_username_field: dast_site_profile.auth_username_field,
+            branch: project.default_branch_or_master,
+            excluded_urls: dast_site_profile.excluded_urls.join(','),
             full_scan_enabled: false,
             show_debug_messages: false,
             spider_timeout: nil,
diff --git a/ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb b/ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb
index 86ccdf41174a5..353378a7a76d3 100644
--- a/ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb
+++ b/ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb
@@ -17,7 +17,7 @@
 
       it 'responds with error message', :aggregate_failures do
         expect(subject).not_to be_success
-        expect(subject.message).to eq('Site Profile was not provided')
+        expect(subject.message).to eq('Dast site profile was not provided')
       end
     end
 
@@ -39,8 +39,12 @@
 
         it 'returns prepared scanner params in the payload' do
           expect(subject.payload).to eq(
-            branch: 'master',
-            target_url: dast_site_profile.dast_site.url
+            branch: project.default_branch,
+            target_url: dast_site_profile.dast_site.url,
+            excluded_urls: dast_site_profile.excluded_urls.join(','),
+            auth_username_field: dast_site_profile.auth_username_field,
+            auth_password_field: dast_site_profile.auth_password_field,
+            auth_username: dast_site_profile.auth_username
           )
         end
       end
@@ -51,11 +55,15 @@
         it 'returns prepared scanner params in the payload' do
           expect(subject.payload).to eq(
             branch: project.default_branch,
+            target_url: dast_site_profile.dast_site.url,
+            excluded_urls: dast_site_profile.excluded_urls.join(','),
+            auth_username_field: dast_site_profile.auth_username_field,
+            auth_password_field: dast_site_profile.auth_password_field,
+            auth_username: dast_site_profile.auth_username,
             full_scan_enabled: false,
             show_debug_messages: false,
             spider_timeout: nil,
             target_timeout: nil,
-            target_url: dast_site_profile.dast_site.url,
             use_ajax_spider: false
           )
         end
diff --git a/ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb b/ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
index dbd50aee137c3..9f2ecf6752806 100644
--- a/ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
+++ b/ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
@@ -50,7 +50,11 @@
 
     it 'delegates variables preparation to ::Ci::DastScanCiConfigurationService' do
       expected_params = {
+        auth_password_field: site_profile.auth_password_field,
+        auth_username: site_profile.auth_username,
+        auth_username_field: site_profile.auth_username_field,
         branch: project.default_branch_or_master,
+        excluded_urls: site_profile.excluded_urls.join(','),
         full_scan_enabled: false,
         show_debug_messages: false,
         spider_timeout: nil,
@@ -76,19 +80,23 @@
           stage: 'test',
           image: { name: '$SECURE_ANALYZERS_PREFIX/dast:$DAST_VERSION' },
           variables: {
-            DAST_VERSION: 1,
-            SECURE_ANALYZERS_PREFIX: 'registry.gitlab.com/gitlab-org/security-products/analyzers',
-            DAST_WEBSITE: site_profile.dast_site.url,
+            DAST_DEBUG: 'false',
+            DAST_EXCLUDE_URLS: site_profile.excluded_urls.join(','),
             DAST_FULL_SCAN_ENABLED: 'false',
+            DAST_PASSWORD_FIELD: site_profile.auth_password_field,
+            DAST_USERNAME: site_profile.auth_username,
+            DAST_USERNAME_FIELD: site_profile.auth_username_field,
             DAST_USE_AJAX_SPIDER: 'false',
-            DAST_DEBUG: 'false'
+            DAST_VERSION: 1,
+            DAST_WEBSITE: site_profile.dast_site.url,
+            SECURE_ANALYZERS_PREFIX: 'registry.gitlab.com/gitlab-org/security-products/analyzers'
           },
           allow_failure: true,
           script: ['/analyze'],
           artifacts: { reports: { dast: 'gl-dast-report.json' } }
         },
         'dast-on-demand-1': {
-          script: 'echo "Error during On-Demand Scan execution: Site Profile was not provided" && false',
+          script: 'echo "Error during On-Demand Scan execution: Dast site profile was not provided" && false',
           allow_failure: true
         }
       }
-- 
GitLab