Skip to content
Prev Previous commit
Next Next commit
Add support for specifing the path to the OpenAPI spec via a path
This allows to keep all absolute urls out of the config.
This can be used to define a single config for a set of simmilarly build services and only cahnge the url via the config args.

Signed-off-by: Jannik Hollenbach <jannik.hollenbach@iteratec.com>
  • Loading branch information
J12934 committed Jul 30, 2021
commit dc8abb31ba8dd26e4ee766d7c27f7fec5a5bf91a
4 changes: 4 additions & 0 deletions scanners/zap-advanced/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,10 @@ zapConfiguration:
format: openapi
# -- Url to start importing the API from, default: first context URL
url: http://localhost:8000/v2/swagger.json
# -- Optional: path to the OpenAPI spec. Mutually exclusive to apis[].url, only one can be used.
# Path is relative to the targets **hosts**, paths in the targets url will be ignored
# See example: demo-petstoreapi-scan-authenticated-no-hardcoded-urls
path: /v2/swagger.json
# -- Optional: Override host setting in the API (e.g. swagger.json) if your API is using some kind of internal routing.
hostOverride: http://localhost:8000
# -- Optional: Assumes that the API Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# SPDX-FileCopyrightText: 2021 iteratec GmbH
#
# SPDX-License-Identifier: Apache-2.0

---
apiVersion: v1
kind: ConfigMap
metadata:
name: zap-advanced-scan-config
data:
2-zap-advanced-scan.yaml: |-

# ZAP Contexts Configuration
contexts:
# Name to be used to refer to this context in other jobs, mandatory
- name: scb-petstore-context
# An optional list of regexes to include
includePaths:
- "https?://.*\\..*.svc:.*"
- "https?://.*\\..*.svc/.*"
- "https?://.*\\..*.svc.cluster.local/.*"
- "https?://.*\\..*.svc.cluster.local:.*"
# An optional list of regexes to exclude
excludePaths:
- ".*\\.css"
- ".*\\.png"
- ".*\\.jpeg"

apis:
- name: scb-petstore-api
# -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available.
context: scb-petstore-context
# -- format of the API ('openapi', 'grapql', 'soap')
format: openapi
# -- path to the OpenAPI spec. Always relative to the targets **hosts**, paths in the targets url will be ignored
path: /v2/swagger.json

# ZAP ActiveScans Configuration
scanners:
- name: scb-petstore-scan
# String: Name of the context to attack, default: first context
context: scb-petstore-context
# Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited
maxRuleDurationInMins: 1
# Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited
maxScanDurationInMins: 5
# Int: The max number of threads per host, default: 2
threadPerHost: 5


---
apiVersion: "execution.securecodebox.io/v1"
kind: Scan
metadata:
name: "zap-advanced-api-scan-petstore"
labels:
organization: "OWASP"
spec:
scanType: "zap-advanced-scan"
parameters:
# target URL including the protocol
- "--target"
- "http://swagger-petstore.default.svc/"
- "--context"
- "scb-petstore-context"
volumeMounts:
- name: zap-advanced-scan-config
mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml
subPath: 2-zap-advanced-scan.yaml
readOnly: true
volumes:
- name: zap-advanced-scan-config
configMap:
name: zap-advanced-scan-config
40 changes: 31 additions & 9 deletions scanners/zap-advanced/scanner/zapclient/api/zap_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# -*- coding: utf-8 -*-

import json
import urllib

import requests
import collections
import logging
Expand Down Expand Up @@ -75,17 +77,37 @@ def start_api_import(self, url: str, context: collections.OrderedDict, api_confi
Active api_config that should be used for the api import
"""

logging.debug('Trying to configure the API Scan')
self.configure_scripts(config=api_config)

logging.info("Trying to start API Import with target url: '%s'", url)

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()
if (api_config is None) or "format" not in api_config or api_config["format"] != 'openapi':
logging.info("No complete API definition configured (format: openapi): %s!", api_config)
return

if "url" not in api_config and "path" not in api_config:
logging.warning(
"API Config section '%s' has neither a 'url' or a 'path' configured. It will be skipped",
api_config["name"]
)
return

api_spec_url = None

if "url" in api_config:
api_spec_url = api_config["url"]
elif "path" in api_config:
logging.info('Building OpenAPI Spec from path (%s) and the target url (%s)', api_config["path"], url)
api_spec_url = urllib.parse.urlparse(url)._replace(path=api_config["path"]).geturl()

logging.info('Number of Imported URLs: ' + str(len(urls)))
logging.debug('Import warnings: ' + str(result))
logging.info('Import OpenAPI Spec from (%s)', api_spec_url)
if "hostOverride" in api_config:
result = self.get_zap.openapi.import_url(api_spec_url, api_config["hostOverride"])
else:
logging.info("No complete API definition configured (format: openapi, url: xxx): %s!", api_config)
logging.warning("No 'hostOverride' configured for target %s. Defaulting for target as override.", url)
result = self.get_zap.openapi.import_url(api_spec_url, url)

logging.debug('Trying to configure the API Scan')
self.configure_scripts(config=api_config)
urls = self.get_zap.core.urls()
logging.info('Number of Imported URLs: %d', len(urls))
logging.debug('Import warnings: %d', result)