Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
dbb914db
Commit
dbb914db
authored
Jun 03, 2021
by
Philip Cunningham
Committed by
Heinrich Lee Yu
Jun 03, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor DAST on-demand CI config generation
parent
2651ee6a
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
284 additions
and
560 deletions
+284
-560
ee/app/graphql/mutations/pipelines/run_dast_scan.rb
ee/app/graphql/mutations/pipelines/run_dast_scan.rb
+9
-3
ee/app/services/app_sec/dast/scan_configs/build_service.rb
ee/app/services/app_sec/dast/scan_configs/build_service.rb
+84
-0
ee/app/services/ci/dast_scan_ci_configuration_service.rb
ee/app/services/ci/dast_scan_ci_configuration_service.rb
+0
-43
ee/app/services/ci/run_dast_scan_service.rb
ee/app/services/ci/run_dast_scan_service.rb
+2
-6
ee/app/services/dast_on_demand_scans/create_service.rb
ee/app/services/dast_on_demand_scans/create_service.rb
+3
-3
ee/app/services/dast_on_demand_scans/params_create_service.rb
...pp/services/dast_on_demand_scans/params_create_service.rb
+0
-105
ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb
...policies/on_demand_scan_pipeline_configuration_service.rb
+4
-4
ee/spec/graphql/mutations/dast_on_demand_scans/create_spec.rb
...pec/graphql/mutations/dast_on_demand_scans/create_spec.rb
+5
-5
ee/spec/services/app_sec/dast/scan_configs/build_service_spec.rb
.../services/app_sec/dast/scan_configs/build_service_spec.rb
+145
-0
ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb
...ec/services/ci/dast_scan_ci_configuration_service_spec.rb
+0
-131
ee/spec/services/ci/run_dast_scan_service_spec.rb
ee/spec/services/ci/run_dast_scan_service_spec.rb
+26
-55
ee/spec/services/dast_on_demand_scans/create_service_spec.rb
ee/spec/services/dast_on_demand_scans/create_service_spec.rb
+4
-14
ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb
...rvices/dast_on_demand_scans/params_create_service_spec.rb
+0
-166
ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
...ies/on_demand_scan_pipeline_configuration_service_spec.rb
+2
-25
No files found.
ee/app/graphql/mutations/pipelines/run_dast_scan.rb
View file @
dbb914db
...
...
@@ -32,11 +32,17 @@ module Mutations
def
resolve
(
project_path
:,
target_url
:,
branch
:,
scan_type
:)
project
=
authorized_find!
(
project_path
)
service
=
::
Ci
::
RunDastScanService
.
new
(
project
,
current_user
)
result
=
service
.
execute
(
branch:
branch
,
target_url:
target_url
)
result
=
::
DastOnDemandScans
::
CreateService
.
new
(
container:
project
,
current_user:
current_user
,
params:
{
branch:
branch
,
dast_site_profile:
DastSiteProfile
.
new
(
dast_site:
DastSite
.
new
(
url:
target_url
))
}
).
execute
if
result
.
success?
success_response
(
project:
project
,
pipeline:
result
.
payload
)
success_response
(
project:
project
,
pipeline:
result
.
payload
[
:pipeline
]
)
else
error_response
(
result
.
message
)
end
...
...
ee/app/services/app_sec/dast/scan_configs/build_service.rb
0 → 100644
View file @
dbb914db
# frozen_string_literal: true
module
AppSec
module
Dast
module
ScanConfigs
class
BuildService
<
BaseContainerService
include
Gitlab
::
Utils
::
StrongMemoize
def
execute
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:
{
dast_profile:
dast_profile
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch:
branch
,
ci_configuration:
ci_configuration
}
)
end
private
def
active_scan_allowed?
return
true
unless
dast_scanner_profile
&
.
full_scan_enabled?
url_base
=
DastSiteValidation
.
get_normalized_url_base
(
dast_site
&
.
url
)
DastSiteValidationsFinder
.
new
(
project_id:
container
.
id
,
state: :passed
,
url_base:
url_base
).
execute
.
present?
end
def
branch
strong_memoize
(
:branch
)
do
dast_profile
&
.
branch_name
||
params
[
:branch
]
||
container
.
default_branch
end
end
def
ci_configuration
{
'stages'
=>
[
'dast'
],
'include'
=>
[{
'template'
=>
'DAST-On-Demand-Scan.gitlab-ci.yml'
}],
'variables'
=>
ci_variables
.
to_hash
.
to_hash
# Collection#to_hash returns HashWithIndifferentAccess which does not serialise correctly
}.
to_yaml
end
def
ci_variables
dast_site_profile
.
ci_variables
.
tap
do
|
collection
|
collection
.
concat
(
dast_scanner_profile
.
ci_variables
)
if
dast_scanner_profile
end
end
def
dast_profile
strong_memoize
(
:dast_profile
)
do
params
[
:dast_profile
]
end
end
def
dast_site_profile
strong_memoize
(
:dast_site_profile
)
do
dast_profile
&
.
dast_site_profile
||
params
[
:dast_site_profile
]
end
end
def
dast_scanner_profile
strong_memoize
(
:dast_scanner_profile
)
do
dast_profile
&
.
dast_scanner_profile
||
params
[
:dast_scanner_profile
]
end
end
def
dast_site
strong_memoize
(
:dast_site
)
do
dast_site_profile
.
dast_site
end
end
end
end
end
end
ee/app/services/ci/dast_scan_ci_configuration_service.rb
deleted
100644 → 0
View file @
2651ee6a
# frozen_string_literal: true
module
Ci
module
DastScanCiConfigurationService
ENV_MAPPING
=
{
spider_timeout:
'DAST_SPIDER_MINS'
,
target_timeout:
'DAST_TARGET_AVAILABILITY_TIMEOUT'
,
target_url:
'DAST_WEBSITE'
,
api_specification_url:
'DAST_API_SPECIFICATION'
,
api_host_override:
'DAST_API_HOST_OVERRIDE'
,
use_ajax_spider:
'DAST_USE_AJAX_SPIDER'
,
show_debug_messages:
'DAST_DEBUG'
,
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
)
variables
=
args
.
slice
(
*
ENV_MAPPING
.
keys
).
compact
.
to_h
do
|
key
,
val
|
[
ENV_MAPPING
[
key
],
to_env_value
(
val
)]
end
{
'stages'
=>
[
'dast'
],
'include'
=>
[{
'template'
=>
'DAST-On-Demand-Scan.gitlab-ci.yml'
}],
'variables'
=>
variables
}.
to_yaml
end
def
self
.
bool?
(
value
)
!!
value
==
value
end
private_class_method
:bool?
def
self
.
to_env_value
(
value
)
bool?
(
value
)
?
value
.
to_s
:
value
end
private_class_method
:to_env_value
end
end
ee/app/services/ci/run_dast_scan_service.rb
View file @
dbb914db
...
...
@@ -2,12 +2,12 @@
module
Ci
class
RunDastScanService
<
BaseService
def
execute
(
branch
:,
dast_profile:
nil
,
dast_site_profile:
nil
,
**
args
)
def
execute
(
branch
:,
ci_configuration
:,
dast_profile:
nil
,
dast_site_profile:
nil
,
dast_scanner_profile:
nil
)
return
ServiceResponse
.
error
(
message:
'Insufficient permissions'
)
unless
allowed?
service
=
Ci
::
CreatePipelineService
.
new
(
project
,
current_user
,
ref:
branch
)
pipeline
=
service
.
execute
(
:ondemand_dast_scan
,
content:
ci_
yaml
(
args
)
)
do
|
pipeline
|
pipeline
=
service
.
execute
(
:ondemand_dast_scan
,
content:
ci_
configuration
)
do
|
pipeline
|
if
dast_profile
pipeline
.
dast_profile
=
dast_profile
else
...
...
@@ -28,9 +28,5 @@ module Ci
def
allowed?
Ability
.
allowed?
(
current_user
,
:create_on_demand_dast_scan
,
project
)
end
def
ci_yaml
(
args
)
Ci
::
DastScanCiConfigurationService
.
execute
(
args
)
end
end
end
ee/app/services/dast_on_demand_scans/create_service.rb
View file @
dbb914db
...
...
@@ -31,11 +31,11 @@ module DastOnDemandScans
end
def
create_pipeline
params_result
=
DastOnDemandScans
::
ParamsCreate
Service
.
new
(
container:
container
,
current_user:
current_user
,
params:
params
).
execute
config_result
=
AppSec
::
Dast
::
ScanConfigs
::
Build
Service
.
new
(
container:
container
,
current_user:
current_user
,
params:
params
).
execute
return
params_result
unless
params
_result
.
success?
return
config_result
unless
config
_result
.
success?
result
=
::
Ci
::
RunDastScanService
.
new
(
container
,
current_user
).
execute
(
**
params
_result
.
payload
)
result
=
::
Ci
::
RunDastScanService
.
new
(
container
,
current_user
).
execute
(
**
config
_result
.
payload
)
return
success_response
(
result
.
payload
)
if
result
.
success?
...
...
ee/app/services/dast_on_demand_scans/params_create_service.rb
deleted
100644 → 0
View file @
2651ee6a
# frozen_string_literal: true
module
DastOnDemandScans
class
ParamsCreateService
<
BaseContainerService
include
Gitlab
::
Utils
::
StrongMemoize
def
execute
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
(
target_config
,
site_profile_config
,
scanner_profile_config
)
)
end
private
def
active_scan_allowed?
return
true
unless
dast_scanner_profile
&
.
full_scan_enabled?
DastSiteValidationsFinder
.
new
(
project_id:
container
.
id
,
state: :passed
,
url_base:
url_base
).
execute
.
present?
end
def
dast_profile
strong_memoize
(
:dast_profile
)
do
params
[
:dast_profile
]
end
end
def
dast_site_profile
strong_memoize
(
:dast_site_profile
)
do
dast_profile
&
.
dast_site_profile
||
params
[
:dast_site_profile
]
end
end
def
dast_scanner_profile
strong_memoize
(
:dast_scanner_profile
)
do
dast_profile
&
.
dast_scanner_profile
||
params
[
:dast_scanner_profile
]
end
end
def
dast_site
strong_memoize
(
:dast_site
)
do
dast_site_profile
.
dast_site
end
end
def
branch
strong_memoize
(
:branch
)
do
dast_profile
&
.
branch_name
||
params
[
:branch
]
||
container
.
default_branch
end
end
def
url_base
strong_memoize
(
:url_base
)
do
DastSiteValidation
.
get_normalized_url_base
(
dast_site
&
.
url
)
end
end
def
default_config
{
dast_profile:
dast_profile
,
dast_site_profile:
dast_site_profile
,
branch:
branch
}
end
def
target_config
url
=
dast_site
.
url
if
dast_site_profile
.
target_type
==
'website'
{
target_url:
url
}
else
{
api_specification_url:
url
,
api_host_override:
URI
(
url
).
host
}
end
end
def
site_profile_config
return
{}
unless
dast_site_profile
excluded_urls
=
dast_site_profile
.
excluded_urls
.
presence
&
.
join
(
','
)
return
{
excluded_urls:
excluded_urls
}
unless
dast_site_profile
.
auth_enabled
{
excluded_urls:
excluded_urls
,
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
,
auth_url:
dast_site_profile
.
auth_url
}
end
def
scanner_profile_config
return
{}
unless
dast_scanner_profile
{
spider_timeout:
dast_scanner_profile
.
spider_timeout
,
target_timeout:
dast_scanner_profile
.
target_timeout
,
full_scan_enabled:
dast_scanner_profile
.
full_scan_enabled?
,
use_ajax_spider:
dast_scanner_profile
.
use_ajax_spider
,
show_debug_messages:
dast_scanner_profile
.
show_debug_messages
}
end
end
end
ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb
View file @
dbb914db
...
...
@@ -28,10 +28,10 @@ module Security
end
def
prepare_on_demand_scan_configuration
(
action
)
result
=
prepare_
on_demand_scan_params
(
action
[
:site_profile
],
action
[
:scanner_profile
])
result
=
prepare_
base_configuration
(
action
[
:site_profile
],
action
[
:scanner_profile
])
return
error_script
(
result
.
message
)
unless
result
.
success?
ci_configuration
=
YAML
.
safe_load
(
::
Ci
::
DastScanCiConfigurationService
.
execute
(
result
.
payload
)
)
ci_configuration
=
YAML
.
safe_load
(
result
.
payload
[
:ci_configuration
]
)
dast_on_demand_template
[
:dast
].
deep_merge
(
'variables'
=>
dast_on_demand_template
[
:variables
].
deep_merge
(
ci_configuration
[
'variables'
]),
...
...
@@ -39,11 +39,11 @@ module Security
)
end
def
prepare_
on_demand_scan_params
(
site_profile_name
,
scanner_profile_name
)
def
prepare_
base_configuration
(
site_profile_name
,
scanner_profile_name
)
site_profile
=
DastSiteProfilesFinder
.
new
(
project_id:
project
.
id
,
name:
site_profile_name
).
execute
.
first
scanner_profile
=
DastScannerProfilesFinder
.
new
(
project_ids:
[
project
.
id
],
name:
scanner_profile_name
).
execute
.
first
if
scanner_profile_name
.
present?
DastOnDemandScans
::
ParamsCreate
Service
AppSec
::
Dast
::
ScanConfigs
::
Build
Service
.
new
(
container:
project
,
params:
{
dast_site_profile:
site_profile
,
dast_scanner_profile:
scanner_profile
})
.
execute
end
...
...
ee/spec/graphql/mutations/dast_on_demand_scans/create_spec.rb
View file @
dbb914db
...
...
@@ -78,11 +78,11 @@ RSpec.describe Mutations::DastOnDemandScans::Create do
it
'passes additional arguments to the underlying service object'
do
args
=
hash_including
(
spider_timeout:
dast_scanner_profile
.
spider_timeout
,
target_timeout:
dast_scanner_profile
.
target_timeout
,
use_ajax_spider:
dast_scanner_profile
.
use_ajax_spider
,
show_debug_messages:
dast_scanner_profile
.
show_debug_messages
,
full_scan_enabled:
dast_scanner_profile
.
full_scan_enabled?
branch:
project
.
default_branch
,
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
ci_configuration:
kind_of
(
String
)
)
expect_any_instance_of
(
::
Ci
::
RunDastScanService
).
to
receive
(
:execute
).
with
(
args
).
and_call_original
...
...
ee/spec/services/app_sec/dast/scan_configs/build_service_spec.rb
0 → 100644
View file @
dbb914db
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
AppSec
::
Dast
::
ScanConfigs
::
BuildService
do
let_it_be
(
:project
)
{
create
(
:project
,
:repository
)
}
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
)
}
let_it_be
(
:dast_scanner_profile
)
{
create
(
:dast_scanner_profile
,
project:
project
,
spider_timeout:
5
,
target_timeout:
20
)
}
let_it_be
(
:dast_profile
)
{
create
(
:dast_profile
,
project:
project
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch_name:
'master'
)
}
let
(
:dast_website
)
{
dast_site_profile
.
dast_site
.
url
}
let
(
:dast_exclude_urls
)
{
dast_site_profile
.
excluded_urls
.
join
(
','
)
}
let
(
:dast_auth_url
)
{
dast_site_profile
.
auth_url
}
let
(
:dast_username
)
{
dast_site_profile
.
auth_username
}
let
(
:dast_username_field
)
{
dast_site_profile
.
auth_username_field
}
let
(
:dast_password_field
)
{
dast_site_profile
.
auth_password_field
}
let
(
:dast_spider_mins
)
{
dast_scanner_profile
.
spider_timeout
}
let
(
:dast_target_availability_timeout
)
{
dast_scanner_profile
.
target_timeout
}
let
(
:dast_full_scan_enabled
)
{
dast_scanner_profile
.
full_scan_enabled?
}
let
(
:dast_use_ajax_spider
)
{
dast_scanner_profile
.
use_ajax_spider?
}
let
(
:dast_debug
)
{
dast_scanner_profile
.
show_debug_messages?
}
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
}
}
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables:
DAST_WEBSITE:
#{
dast_website
}
DAST_EXCLUDE_URLS:
#{
dast_exclude_urls
}
DAST_AUTH_URL:
#{
dast_auth_url
}
DAST_USERNAME:
#{
dast_username
}
DAST_USERNAME_FIELD:
#{
dast_username_field
}
DAST_PASSWORD_FIELD:
#{
dast_password_field
}
DAST_SPIDER_MINS: '
#{
dast_spider_mins
}
'
DAST_TARGET_AVAILABILITY_TIMEOUT: '
#{
dast_target_availability_timeout
}
'
DAST_FULL_SCAN_ENABLED: '
#{
dast_full_scan_enabled
}
'
DAST_USE_AJAX_SPIDER: '
#{
dast_use_ajax_spider
}
'
DAST_DEBUG: '
#{
dast_debug
}
'
YAML
end
subject
{
described_class
.
new
(
container:
project
,
params:
params
).
execute
}
describe
'execute'
do
context
'when a dast_profile is provided'
do
let
(
:params
)
{
{
dast_profile:
dast_profile
}
}
it
'returns a dast_profile, dast_site_profile, dast_scanner_profile, branch and YAML configuration'
do
expected_payload
=
{
dast_profile:
dast_profile
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch:
dast_profile
.
branch_name
,
ci_configuration:
expected_yaml_configuration
}
expect
(
subject
.
payload
).
to
eq
(
expected_payload
)
end
end
context
'when a dast_site_profile is provided'
do
context
'when a dast_scanner_profile is provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
}
}
it
'returns a dast_site_profile, dast_scanner_profile, branch and YAML configuration'
do
expected_payload
=
{
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch:
project
.
default_branch
,
ci_configuration:
expected_yaml_configuration
}
expect
(
subject
.
payload
).
to
eq
(
expected_payload
)
end
context
'when the target is not validated and an active scan is requested'
do
let_it_be
(
:active_dast_scanner_profile
)
{
create
(
:dast_scanner_profile
,
project:
project
,
scan_type:
'active'
)
}
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
active_dast_scanner_profile
}
}
it
'responds with an error message'
,
:aggregate_failures
do
expect
(
subject
).
not_to
be_success
expect
(
subject
.
message
).
to
eq
(
'Cannot run active scan against unvalidated target'
)
end
end
end
context
'when a dast_scanner_profile is not provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
}
}
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables:
DAST_WEBSITE:
#{
dast_website
}
DAST_EXCLUDE_URLS:
#{
dast_exclude_urls
}
DAST_AUTH_URL:
#{
dast_auth_url
}
DAST_USERNAME:
#{
dast_username
}
DAST_USERNAME_FIELD:
#{
dast_username_field
}
DAST_PASSWORD_FIELD:
#{
dast_password_field
}
YAML
end
it
'returns a dast_site_profile, branch and YAML configuration'
do
expected_payload
=
{
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
nil
,
branch:
project
.
default_branch
,
ci_configuration:
expected_yaml_configuration
}
expect
(
subject
.
payload
).
to
eq
(
expected_payload
)
end
end
end
context
'when a dast_site_profile is not provided'
do
let
(
:params
)
{
{
dast_site_profile:
nil
,
dast_scanner_profile:
dast_scanner_profile
}
}
it
'responds with an error message'
,
:aggregate_failures
do
expect
(
subject
).
not_to
be_success
expect
(
subject
.
message
).
to
eq
(
'Dast site profile was not provided'
)
end
end
context
'when a branch is provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch:
'hello-world'
}
}
it
'returns the branch in the payload'
do
expect
(
subject
.
payload
[
:branch
]).
to
match
(
'hello-world'
)
end
end
end
end
ee/spec/services/ci/dast_scan_ci_configuration_service_spec.rb
deleted
100644 → 0
View file @
2651ee6a
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Ci
::
DastScanCiConfigurationService
do
describe
'.execute'
do
subject
(
:yaml_configuration
)
{
described_class
.
execute
(
params
)
}
context
'when all variables are provided'
do
let
(
:params
)
do
{
spider_timeout:
1000
,
target_timeout:
100
,
target_url:
'https://gitlab.local'
,
api_specification_url:
'https://gitlab.local/api.json'
,
api_host_override:
'gitlab.local'
,
use_ajax_spider:
true
,
show_debug_messages:
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
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables:
DAST_SPIDER_MINS: 1000
DAST_TARGET_AVAILABILITY_TIMEOUT: 100
DAST_WEBSITE: https://gitlab.local
DAST_API_SPECIFICATION: https://gitlab.local/api.json
DAST_API_HOST_OVERRIDE: gitlab.local
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
it
'returns the YAML configuration of the On-Demand DAST scan'
do
expect
(
yaml_configuration
).
to
eq
(
expected_yaml_configuration
)
end
end
context
'when unknown variables are provided'
do
let
(
:params
)
do
{
target_url:
'https://gitlab.local'
,
use_ajax_spider:
false
,
show_debug_messages:
nil
,
full_scan_enabled:
nil
,
additional_argument:
true
,
additional_list:
[
'item a'
]
}
end
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables:
DAST_WEBSITE: https://gitlab.local
DAST_USE_AJAX_SPIDER: 'false'
YAML
end
it
'returns the YAML configuration of the On-Demand DAST scan'
do
expect
(
yaml_configuration
).
to
eq
(
expected_yaml_configuration
)
end
end
context
'when a variable is set to nil'
do
let
(
:params
)
do
{
target_url:
'https://gitlab.local'
,
api_specification_url:
nil
}
end
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables:
DAST_WEBSITE: https://gitlab.local
YAML
end
it
'returns the YAML configuration of the On-Demand DAST scan'
do
expect
(
yaml_configuration
).
to
eq
(
expected_yaml_configuration
)
end
end
context
'when no variables are provided'
do
let
(
:params
)
{
{}
}
let
(
:expected_yaml_configuration
)
do
<<~
YAML
---
stages:
- dast
include:
- template: DAST-On-Demand-Scan.gitlab-ci.yml
variables: {}
YAML
end
it
'returns the YAML configuration of the On-Demand DAST scan'
do
expect
(
yaml_configuration
).
to
eq
(
expected_yaml_configuration
)
end
end
end
end
ee/spec/services/ci/run_dast_scan_service_spec.rb
View file @
dbb914db
...
...
@@ -5,17 +5,9 @@ require 'spec_helper'
RSpec
.
describe
Ci
::
RunDastScanService
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
,
:repository
,
creator:
user
)
}
let_it_be
(
:dast_profile
)
{
create
(
:dast_profile
)
}
let_it_be
(
:dast_site_profile
)
{
dast_profile
.
dast_site_profile
}
let_it_be
(
:branch
)
{
project
.
default_branch
}
let_it_be
(
:spider_timeout
)
{
42
}
let_it_be
(
:target_timeout
)
{
21
}
let_it_be
(
:target_url
)
{
generate
(
:url
)
}
let_it_be
(
:use_ajax_spider
)
{
true
}
let_it_be
(
:show_debug_messages
)
{
false
}
let_it_be
(
:full_scan_enabled
)
{
true
}
let_it_be
(
:excluded_urls
)
{
"
#{
target_url
}
/hello,
#{
target_url
}
/world"
}
let_it_be
(
:auth_url
)
{
"
#{
target_url
}
/login"
}
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
)
}
let_it_be
(
:dast_scanner_profile
)
{
create
(
:dast_scanner_profile
,
project:
project
,
spider_timeout:
42
,
target_timeout:
21
)
}
let_it_be
(
:dast_profile
)
{
create
(
:dast_profile
,
project:
project
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
)
}
before
do
stub_licensed_features
(
security_on_demand_scans:
true
)
...
...
@@ -23,22 +15,17 @@ RSpec.describe Ci::RunDastScanService do
describe
'#execute'
do
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'
,
dast_profile:
dast_profile
,
dast_site_profile:
dast_site_profile
)
config_result
=
AppSec
::
Dast
::
ScanConfigs
::
BuildService
.
new
(
container:
project
,
current_user:
user
,
params:
{
branch:
project
.
default_branch
,
dast_profile:
dast_profile
,
dast_site_profile:
dast_site_profile
}
).
execute
described_class
.
new
(
project
,
user
).
execute
(
**
config_result
.
payload
)
end
let
(
:status
)
{
subject
.
status
}
...
...
@@ -73,7 +60,7 @@ RSpec.describe Ci::RunDastScanService do
end
it
'sets the pipeline ref to the branch'
do
expect
(
pipeline
.
ref
).
to
eq
(
branch
)
expect
(
pipeline
.
ref
).
to
eq
(
project
.
default_
branch
)
end
it
'sets the source to indicate an ondemand scan'
do
...
...
@@ -117,43 +104,43 @@ RSpec.describe Ci::RunDastScanService do
expected_variables
=
[
{
'key'
=>
'DAST_AUTH_URL'
,
'value'
=>
auth_url
,
'value'
=>
dast_site_profile
.
auth_url
,
'public'
=>
true
},
{
'key'
=>
'DAST_DEBUG'
,
'value'
=>
'false'
,
'value'
=>
String
(
dast_scanner_profile
.
show_debug_messages?
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_EXCLUDE_URLS'
,
'value'
=>
excluded_urls
,
'value'
=>
dast_site_profile
.
excluded_urls
.
join
(
','
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_FULL_SCAN_ENABLED'
,
'value'
=>
'true'
,
'value'
=>
String
(
dast_scanner_profile
.
full_scan_enabled?
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_PASSWORD_FIELD'
,
'value'
=>
'session[password]'
,
'value'
=>
dast_site_profile
.
auth_password_field
,
'public'
=>
true
},
{
'key'
=>
'DAST_SPIDER_MINS'
,
'value'
=>
spider_timeout
.
to_s
,
'value'
=>
String
(
dast_scanner_profile
.
spider_timeout
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_TARGET_AVAILABILITY_TIMEOUT'
,
'value'
=>
target_timeout
.
to_s
,
'value'
=>
String
(
dast_scanner_profile
.
target_timeout
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_USERNAME'
,
'value'
=>
'tanuki'
,
'value'
=>
dast_site_profile
.
auth_username
,
'public'
=>
true
},
{
'key'
=>
'DAST_USERNAME_FIELD'
,
'value'
=>
'session[username]'
,
'value'
=>
dast_site_profile
.
auth_username_field
,
'public'
=>
true
},
{
'key'
=>
'DAST_USE_AJAX_SPIDER'
,
'value'
=>
'true'
,
'value'
=>
String
(
dast_scanner_profile
.
use_ajax_spider?
)
,
'public'
=>
true
},
{
'key'
=>
'DAST_VERSION'
,
...
...
@@ -161,7 +148,7 @@ RSpec.describe Ci::RunDastScanService do
'public'
=>
true
},
{
'key'
=>
'DAST_WEBSITE'
,
'value'
=>
target_
url
,
'value'
=>
dast_site_profile
.
dast_site
.
url
,
'public'
=>
true
},
{
'key'
=>
'GIT_STRATEGY'
,
...
...
@@ -177,14 +164,6 @@ RSpec.describe Ci::RunDastScanService do
expect
(
build
.
yaml_variables
).
to
contain_exactly
(
*
expected_variables
)
end
shared_examples
'transactional creation'
do
let_it_be
(
:type_mismatch
)
{
build
(
:dast_scanner_profile
)
}
it
'does not create a Ci::Pipeline'
do
expect
{
subject
}.
to
raise_error
(
ActiveRecord
::
AssociationTypeMismatch
).
and
change
{
Ci
::
Pipeline
.
count
}.
by
(
0
)
end
end
context
'when the dast_profile and dast_site_profile are provided'
do
it
'associates the dast_profile with the pipeline'
do
expect
(
pipeline
.
dast_profile
).
to
eq
(
dast_profile
)
...
...
@@ -193,10 +172,6 @@ RSpec.describe Ci::RunDastScanService do
it
'does associate the dast_site_profile with the pipeline'
do
expect
(
pipeline
.
dast_site_profile
).
to
be_nil
end
it_behaves_like
'transactional creation'
do
let_it_be
(
:dast_profile
)
{
type_mismatch
}
end
end
context
'when the dast_site_profile is provided'
do
...
...
@@ -205,10 +180,6 @@ RSpec.describe Ci::RunDastScanService do
it
'associates the dast_site_profile with the pipeline'
do
expect
(
pipeline
.
dast_site_profile
).
to
eq
(
dast_site_profile
)
end
it_behaves_like
'transactional creation'
do
let_it_be
(
:dast_site_profile
)
{
type_mismatch
}
end
end
context
'when the pipeline fails to save'
do
...
...
ee/spec/services/dast_on_demand_scans/create_service_spec.rb
View file @
dbb914db
...
...
@@ -63,22 +63,12 @@ RSpec.describe DastOnDemandScans::CreateService do
it_behaves_like
'a service that calls Ci::RunDastScanService'
do
let
(
:expected_params
)
do
{
auth_password_field:
dast_site_profile
.
auth_password_field
,
auth_url:
dast_site_profile
.
auth_url
,
auth_username:
dast_site_profile
.
auth_username
,
auth_username_field:
dast_site_profile
.
auth_username_field
,
hash_including
(
branch:
project
.
default_branch
,
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
excluded_urls:
dast_site_profile
.
excluded_urls
.
join
(
','
),
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
}
dast_scanner_profile:
dast_scanner_profile
,
ci_configuration:
kind_of
(
String
)
)
end
end
...
...
ee/spec/services/dast_on_demand_scans/params_create_service_spec.rb
deleted
100644 → 0
View file @
2651ee6a
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
DastOnDemandScans
::
ParamsCreateService
do
let_it_be
(
:project
)
{
create
(
:project
,
:repository
)
}
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
)
}
let_it_be
(
:dast_scanner_profile
)
{
create
(
:dast_scanner_profile
,
project:
project
)
}
let
(
:excluded_urls
)
{
dast_site_profile
.
excluded_urls
.
join
(
','
)
}
let
(
:target_url
)
{
dast_site_profile
.
dast_site
.
url
}
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
}
}
subject
{
described_class
.
new
(
container:
project
,
params:
params
).
execute
}
describe
'execute'
do
context
'when the dast_site_profile is not provided'
do
let
(
:params
)
{
{
dast_site_profile:
nil
,
dast_scanner_profile:
dast_scanner_profile
}
}
it
'responds with error message'
,
:aggregate_failures
do
expect
(
subject
).
not_to
be_success
expect
(
subject
.
message
).
to
eq
(
'Dast site profile was not provided'
)
end
end
context
'when the dast_site_profile is provided'
do
context
'when the branch is provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
branch:
'other-branch'
}
}
context
'when the branch exists'
do
it
'includes the branch in the prepared params'
do
project
.
repository
.
create_branch
(
params
[
:branch
])
expect
(
subject
.
payload
[
:branch
]).
to
eq
(
params
[
:branch
])
end
end
end
context
'when the dast_scanner_profile is not provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
nil
}
}
it
'returns prepared scanner params in the payload'
do
expect
(
subject
.
payload
).
to
eq
(
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
,
auth_url:
dast_site_profile
.
auth_url
,
branch:
project
.
default_branch
,
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
excluded_urls:
excluded_urls
,
target_url:
target_url
)
end
end
context
'when the dast_scanner_profile is provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
}
}
it
'returns prepared scanner params in the payload'
do
expect
(
subject
.
payload
).
to
eq
(
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
,
auth_url:
dast_site_profile
.
auth_url
,
branch:
project
.
default_branch
,
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
excluded_urls:
excluded_urls
,
full_scan_enabled:
false
,
show_debug_messages:
false
,
spider_timeout:
nil
,
target_timeout:
nil
,
target_url:
target_url
,
use_ajax_spider:
false
)
end
context
'when dast_site_profile.excluded_urls is empty'
do
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
,
excluded_urls:
[])
}
it
'returns nil'
do
expect
(
subject
.
payload
[
:excluded_urls
]).
to
be_nil
end
end
context
'when the target is not validated and an active scan is requested'
do
let_it_be
(
:active_dast_scanner_profile
)
{
create
(
:dast_scanner_profile
,
project:
project
,
scan_type:
'active'
)
}
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
active_dast_scanner_profile
}
}
it
'responds with error message'
,
:aggregate_failures
do
expect
(
subject
).
not_to
be_success
expect
(
subject
.
message
).
to
eq
(
'Cannot run active scan against unvalidated target'
)
end
end
end
context
'when authentication is not enabled'
do
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
,
auth_enabled:
false
)
}
it
'returns prepared scanner params excluding auth params in the payload'
do
expect
(
subject
.
payload
).
to
eq
(
branch:
project
.
default_branch
,
dast_profile:
nil
,
dast_site_profile:
dast_site_profile
,
excluded_urls:
excluded_urls
,
full_scan_enabled:
false
,
show_debug_messages:
false
,
spider_timeout:
nil
,
target_timeout:
nil
,
target_url:
target_url
,
use_ajax_spider:
false
)
end
end
context
'when target_type=api'
do
let_it_be
(
:dast_site_profile
)
{
create
(
:dast_site_profile
,
project:
project
,
target_type: :api
)
}
it
'returns params including the api_specification_url and omitting the target_url'
do
expected_payload
=
hash_including
(
api_specification_url:
target_url
,
api_host_override:
URI
(
target_url
).
host
)
expect
(
subject
.
payload
).
to
match
(
expected_payload
).
and
exclude
(
:target_url
)
end
end
context
'when the dast_profile is provided'
do
let_it_be
(
:dast_profile
)
{
create
(
:dast_profile
,
project:
project
,
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch_name:
project
.
default_branch
)
}
let
(
:params
)
{
{
dast_profile:
dast_profile
}
}
it
'returns prepared scanner params in the payload'
do
expect
(
subject
.
payload
).
to
eq
(
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:
dast_profile
.
branch_name
,
auth_url:
dast_site_profile
.
auth_url
,
dast_profile:
dast_profile
,
dast_site_profile:
dast_profile
.
dast_site_profile
,
excluded_urls:
excluded_urls
,
full_scan_enabled:
false
,
show_debug_messages:
false
,
spider_timeout:
nil
,
target_timeout:
nil
,
target_url:
target_url
,
use_ajax_spider:
false
)
end
end
end
context
'when the branch is provided'
do
let
(
:params
)
{
{
dast_site_profile:
dast_site_profile
,
dast_scanner_profile:
dast_scanner_profile
,
branch:
'hello-world'
}
}
it
'returns the branch in the payload'
do
expect
(
subject
.
payload
[
:branch
]).
to
match
(
'hello-world'
)
end
end
end
end
ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
View file @
dbb914db
...
...
@@ -42,31 +42,8 @@ RSpec.describe Security::SecurityOrchestrationPolicies::OnDemandScanPipelineConf
end
it
'delegates params creation to DastOnDemandScans::ParamsCreateService'
do
expect
(
DastOnDemandScans
::
ParamsCreateService
).
to
receive
(
:new
).
with
(
container:
project
,
params:
{
dast_site_profile:
site_profile
,
dast_scanner_profile:
scanner_profile
}).
and_call_original
expect
(
DastOnDemandScans
::
ParamsCreateService
).
to
receive
(
:new
).
with
(
container:
project
,
params:
{
dast_site_profile:
nil
,
dast_scanner_profile:
nil
}).
and_call_original
pipeline_configuration
end
it
'delegates variables preparation to ::Ci::DastScanCiConfigurationService'
do
expected_params
=
{
auth_password_field:
site_profile
.
auth_password_field
,
auth_url:
site_profile
.
auth_url
,
auth_username:
site_profile
.
auth_username
,
auth_username_field:
site_profile
.
auth_username_field
,
dast_profile:
nil
,
dast_site_profile:
site_profile
,
branch:
project
.
default_branch
,
excluded_urls:
site_profile
.
excluded_urls
.
join
(
','
),
full_scan_enabled:
false
,
show_debug_messages:
false
,
spider_timeout:
nil
,
target_timeout:
nil
,
target_url:
site_profile
.
dast_site
.
url
,
use_ajax_spider:
false
}
expect
(
::
Ci
::
DastScanCiConfigurationService
).
to
receive
(
:execute
).
with
(
expected_params
).
and_call_original
expect
(
AppSec
::
Dast
::
ScanConfigs
::
BuildService
).
to
receive
(
:new
).
with
(
container:
project
,
params:
{
dast_site_profile:
site_profile
,
dast_scanner_profile:
scanner_profile
}).
and_call_original
expect
(
AppSec
::
Dast
::
ScanConfigs
::
BuildService
).
to
receive
(
:new
).
with
(
container:
project
,
params:
{
dast_site_profile:
nil
,
dast_scanner_profile:
nil
}).
and_call_original
pipeline_configuration
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment