Skip to content
Prev Previous commit
Next Next commit
Refactor config file handling
Signed-off-by: Jannik Hollenbach <jannik.hollenbach@iteratec.com>
  • Loading branch information
J12934 committed Jul 30, 2021
commit 652578c5ae7a7673a69e1ad95239ce9acc1d16bc
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ def test_bodgeit_scan_without_config(get_bodgeit_url, get_zap_instance: ZAPv2):

logging.warning("get_bodgeit_url: %s", get_bodgeit_url)

zap_automation = ZapAutomation(zap=zap, config_dir="")
zap_automation = ZapAutomation(zap=zap, config_dir="",>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 5

Expand All @@ -135,12 +135,12 @@ def test_bodgeit_scan_with_config(get_bodgeit_url, get_zap_instance: ZAPv2):

logging.warning("get_bodgeit_url: %s", get_bodgeit_url)

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 5

Expand All @@ -150,12 +150,12 @@ def test_juiceshop_scan_without_config(get_juiceshop_url, get_zap_instance: ZAPv
zap = get_zap_instance
test_target = "http://juiceshop:3000/"

zap_automation = ZapAutomation(zap=zap, config_dir="")
zap_automation = ZapAutomation(zap=zap, config_dir="",>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 2

Expand All @@ -166,12 +166,12 @@ def test_juiceshop_scan_with_config(get_juiceshop_url, get_zap_instance: ZAPv2):
test_config_yaml = "./tests/mocks/scan-full-juiceshop-docker/"
test_target = "http://juiceshop:3000/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 2

Expand All @@ -182,11 +182,11 @@ def test_petstore_scan_with_config(get_petstore_url, get_zap_instance: ZAPv2):
test_config_yaml = "./tests/mocks/scan-full-petstore-docker/"
test_target = "http://petstore:8080/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 1
19 changes: 9 additions & 10 deletions scanners/zap-advanced/scanner/tests/test_integration_zap_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ def test_global_config(get_zap_instance: ZAPv2):
test_target = "http://www.secureCodeBox.io/"
test_config_yaml = "./tests/mocks/global/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])

logging.info('Found ZAP Alerts: %s', str(len(alerts)))
logging.info('Found ZAP Alerts: %d', len(alerts))

assert int(len(alerts)) >= 1

Expand All @@ -132,7 +132,7 @@ def test_petstore_scan_with_config(get_petstore_url, get_zap_instance: ZAPv2):
test_config_yaml = "./tests/mocks/scan-full-petstore-local/"
test_target = "http://localhost:8000/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])
Expand All @@ -146,9 +146,8 @@ def test_scan_target_without_config(get_zap_instance: ZAPv2):

zap = get_zap_instance
test_target = "http://www.secureCodeBox.io/"


zap_automation = ZapAutomation(zap=zap, config_dir="")

zap_automation = ZapAutomation(zap=zap, config_dir="",>
zap_automation.scan_target(target=test_target)

@pytest.mark.integrationtest
Expand All @@ -157,7 +156,7 @@ def test_bodgeit_scan_without_config(get_bodgeit_url, get_zap_instance: ZAPv2):
zap = get_zap_instance
test_target = "http://localhost:8080/bodgeit/"

zap_automation = ZapAutomation(zap=zap, config_dir="")
zap_automation = ZapAutomation(zap=zap, config_dir="",>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])
Expand All @@ -173,7 +172,7 @@ def test_bodgeit_scan_with_config(get_bodgeit_url, get_zap_instance: ZAPv2):
test_config_yaml = "./tests/mocks/scan-full-bodgeit-local/"
test_target = "http://localhost:8080/bodgeit/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])
Expand All @@ -189,7 +188,7 @@ def test_juiceshop_scan_without_config(get_juiceshop_url, get_zap_instance: ZAPv
test_config_yaml = "./tests/mocks/scan-full-juiceshop-local/"
test_target = "http://localhost:3000/"

zap_automation = ZapAutomation(zap=zap, config_dir="")
zap_automation = ZapAutomation(zap=zap, config_dir="",>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])
Expand All @@ -205,7 +204,7 @@ def test_juiceshop_scan_with_config(get_juiceshop_url, get_zap_instance: ZAPv2):
test_config_yaml = "./tests/mocks/scan-full-juiceshop-local/"
test_target = "http://localhost:3000/"

zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml)
zap_automation = ZapAutomation(zap=zap, config_dir=test_config_yaml,>)
zap_automation.scan_target(target=test_target)

alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], [])
Expand Down
65 changes: 34 additions & 31 deletions scanners/zap-advanced/scanner/tests/test_zap_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,62 @@ def test_always_passes(self):

@pytest.mark.unit
def test_empty_config_path(self):
config = ZapConfiguration("")
self.assertFalse(config.get_contexts.has_configurations)
config = ZapConfiguration("", "https://example.com")
self.assertIsNone(config.get_active_context_config)

@pytest.mark.unit
def test_corrupt_config_path(self):
config = ZapConfiguration("not/existing/path")
self.assertFalse(config.get_contexts.has_configurations)
config = ZapConfiguration("not/existing/path", "https://example.com")
self.assertIsNone(config.get_active_context_config)

@pytest.mark.unit
def test_existing_config_path(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertTrue(config.get_contexts.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNotNone(config.get_active_context_config)

@pytest.mark.unit
def test_empty_config_folder(self):
config = ZapConfiguration("./tests/mocks/empty/")
self.assertFalse(config.get_contexts.has_configurations)
config = ZapConfiguration("./tests/mocks/empty/", "https://www.secureCodeBox.io/")
self.assertIsNone(config.get_active_context_config)

@pytest.mark.unit
def test_empty_config_file(self):
config = ZapConfiguration("./tests/mocks/empty-files/")
self.assertFalse(config.get_contexts.has_configurations)
config = ZapConfiguration("./tests/mocks/empty-files/", "https://www.secureCodeBox.io/")
self.assertIsNone(config.get_active_context_config)

@pytest.mark.unit
def test_config_context_without_overlay(self):
config = ZapConfiguration("./tests/mocks/context-without-overlay/")
self.assertTrue(config.get_contexts.has_configurations)
config = ZapConfiguration("./tests/mocks/context-without-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNotNone(config.get_active_context_config)

@pytest.mark.unit
def test_config_context_with_overlay(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertTrue(config.get_contexts.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNotNone(config.get_active_context_config)

@pytest.mark.unit
def test_returns_the_current_context_correctly(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
context = config.get_active_context_config
self.assertIsNotNone(context)
self.assertEqual(context["name"], "secureCodeBoxScanType-NoAuth")

@pytest.mark.unit
def test_has_spider_configurations(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertTrue(config.get_contexts.has_configurations)
self.assertFalse(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNotNone(config.get_active_context_config)
self.assertIsNone(config.get_active_spider_config)

config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/")
self.assertTrue(config.get_contexts.has_configurations)
self.assertTrue(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/bodgeit/")
self.assertIsNotNone(config.get_active_context_config)
self.assertIsNotNone(config.get_active_spider_config)

@pytest.mark.unit
def test_has_scan_configurations(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertTrue(config.get_contexts.has_configurations)
self.assertFalse(config.get_scanners.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNotNone(config.get_active_context_config)
self.assertIsNone(config.get_active_spider_config)

config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/")
self.assertTrue(config.get_contexts.has_configurations)
self.assertTrue(config.get_scanners.has_configurations)




config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/bodgeit/")
self.assertIsNotNone(config.get_active_context_config)
self.assertIsNotNone(config.get_active_spider_config)
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class ZapConfigurationTests(TestCase):

@pytest.mark.unit
def test_has_scan_configurations(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertFalse(config.get_scanners.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNone(config.get_active_scanner_config)

config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/")
self.assertTrue(config.get_scanners.has_configurations)
config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/")
self.assertIsNotNone(config.get_active_scanner_config)
8 changes: 4 additions & 4 deletions scanners/zap-advanced/scanner/tests/test_zap_spider_ajax.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class ZapSpiderAjaxTests(TestCase):

@pytest.mark.unit
def test_has_spider_configurations(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertFalse(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNone(config.get_active_spider_config)

config = ZapConfiguration("./tests/mocks/scan-full-juiceshop-docker/")
self.assertTrue(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/scan-full-juiceshop-docker/", "http://juiceshop:3000/")
self.assertIsNotNone(config.get_active_spider_config)
8 changes: 4 additions & 4 deletions scanners/zap-advanced/scanner/tests/test_zap_spider_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class ZapSpiderHttpTests(TestCase):

@pytest.mark.unit
def test_has_spider_configurations(self):
config = ZapConfiguration("./tests/mocks/context-with-overlay/")
self.assertFalse(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/")
self.assertIsNone(config.get_active_spider_config)

config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/")
self.assertTrue(config.get_spiders.has_configurations)
config = ZapConfiguration("./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/")
self.assertIsNotNone(config.get_active_spider_config)
2 changes: 1 addition & 1 deletion scanners/zap-advanced/scanner/zapclient/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def process(args):
zap = ZAPv2(proxies=zap_proxy, apikey=api_key)

logging.info(':: Starting SCB ZAP Automation Framework with config %s', args.config_folder)
zap_automation = ZapAutomation(zap=zap, config_dir=args.config_folder)
zap_automation = ZapAutomation(zap=zap, config_dir=args.config_folder,>)

try:
logging.info(':: Starting SCB ZAP Scan with target %s', args.target)
Expand Down
34 changes: 14 additions & 20 deletions scanners/zap-advanced/scanner/zapclient/api/zap_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

logging = logging.getLogger('ZapConfigureApi')


class ZapConfigureApi(ZapClient):
"""This class configures a Api scan in a running ZAP instance, based on a ZAP Configuration.

Expand All @@ -48,8 +49,11 @@ def __init__(self, zap: ZAPv2, config: ZapConfiguration):
self.__api_config = None

# if at least one ZAP Context is defined start to configure the running ZAP instance (`zap`) accordingly
if self.get_config.has_configurations and self.get_config.get_apis.has_configurations:
logging.debug('Configure #%s APIs(s) with: %s', len(self.get_config.get_apis.get_configurations), self.get_config.get_apis.get_configurations)
if self.get_config.has_configurations and self.get_config.get_active_api_config is not None:
logging.debug(
'Configure API Import with: %s',
self.get_config.get_active_api_config
)
else:
logging.warning("No valid ZAP configuration object found: %s! It seems there is something important missing.", config)

Expand All @@ -58,40 +62,30 @@ def get_api_config(self) -> collections.OrderedDict:
""" Returns the spider config of the currently running ZAP instance. """
return self.__api_config

def start_api_by_url(self, url: str):
def start_api_import(self, url: str, context: collections.OrderedDict, api_config: collections.OrderedDict):
""" Starts a ZAP Api scan for the given target, based on the given configuration and ZAP instance.

Parameters
----------
url: str
The target to Api.
context:
The active context for the current scan / api import
api_config:
Active api_config that should be used for the api import
"""

if self.get_config.get_apis.has_configurations:
# Search for the corresponding context object related to the given url
api_context=self.get_config.get_contexts.get_configuration_by_url(url)
# Search for a API configuration referencing the context identified by url
if self._is_not_empty_string("name", api_context):
self.__api_config = self.get_config.get_apis.get_configuration_by_context_name(str(api_context["name"]))

logging.info("Trying to start API Import with target url: '%s'", url)
self.__load_api(url=url, api_config=self.__api_config)
else:
logging.warning("No context configuration found for target: %s!", url)
else:
logging.error("There is no API configuration section defined in your configuration YAML.")
logging.info("Trying to start API Import with target url: '%s'", url)

def __load_api(self, url: str, api_config: collections.OrderedDict):

if (api_config is not None) and "format" in api_config and api_config["format"] == 'openapi' and "url" in api_config:
logging.debug('Import Api URL ' + api_config["url"])
result = self.get_zap.openapi.import_url(api_config["url"], api_config["hostOverride"])
urls = self.get_zap.core.urls()

logging.info('Number of Imported URLs: ' + str(len(urls)))
logging.debug('Import warnings: ' + str(result))
else:
logging.info("No complete API definition configured (format: openapi, url: xxx): %s!", api_config)

logging.debug('Trying to configure the API Scan')
self.configure_scripts(config=api_config)
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@
A Python package containing secureCodeBox specific ZAPv2 Client configuration parsing based on a YAML format.
"""

__all__ = ['zap_configuration', 'zap_configuration_context', 'zap_configuration_api', 'zap_configuration_context', 'zap_configuration_context_users', 'zap_configuration_spider', 'zap_configuration_scanner']
__all__ = ['zap_configuration']

from .zap_configuration import ZapConfiguration
from .zap_configuration_context import ZapConfigurationContext
from .zap_configuration_api import ZapConfigurationApi
from .zap_configuration_context import ZapConfigurationContext
from .zap_configuration_context_users import ZapConfigurationContextUsers
from .zap_configuration_spider import ZapConfigurationSpider
from .zap_configuration_scanner import ZapConfigurationScanner
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2021 iteratec GmbH
#
# SPDX-License-Identifier: Apache-2.0

__all__ = ['zap_configuration_context_users']

from .zap_configuration_context_users import ZapConfigurationContextUsers
Loading