diff --git a/README.md b/README.md index 27a2fa8..2da10fb 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,6 @@ config: context: file: '' # Optional user: '' # Optional - fullScan: - minutes: '' apiScan: format: 'openapi' ``` @@ -107,7 +105,7 @@ config: ### Baseline -It runs the [ZAP](https://www.zaproxy.org/) spider against the specified target for (by default) 1 minute and then waits for the passive scanning to complete before reporting the results. +It runs the [ZAP](https://www.zaproxy.org/docs/docker/about/) spider against the specified target for (by default) 1 minute and then waits for the passive scanning to complete before reporting the results. This means that the script doesn't perform any actual ‘attacks’ and will run for a relatively short period of time (a few minutes at most). @@ -117,7 +115,7 @@ This mode is intended to be ideal to run in a `CI/CD` environment, even against ### Full Scan -It runs the [ZAP](https://www.zaproxy.org/) spider against the specified target (by default with no time limit) followed by an optional ajax spider scan and then a full `Active Scan` before reporting the results. +It runs the [ZAP](https://www.zaproxy.org/docs/docker/about/) spider against the specified target (by default with no time limit) followed by an optional ajax spider scan and then a full `Active Scan` before reporting the results. This means that the script does perform actual ‘attacks’ and can potentially run for a long period of time. You should NOT use it on web applications that you do not own. `Active Scan` can only find certain types of vulnerabilities. Logical vulnerabilities, such as broken access control, will not be found by any active or automated vulnerability scanning. Manual penetration testing should always be performed in addition to active scanning to find all types of vulnerabilities. @@ -127,6 +125,19 @@ By default, it reports all alerts as WARNings but you can specify a config file It is tuned for performing scans against APIs defined by `openapi`, `soap`, or `graphql` via either a local file or a URL. +To point to a local file, use the following syntax: +``` +docker run -v :/zap/wrk/:rw -it --rm soosio/dast --clientId=--apiKey= --projectName= --scanMode=apiscan --apiScanFormat=openapi swagger.yaml +``` + +Be sure the local file still points to the live endpoint of your API. E.g. for `openapi` YAML, you would set the `servers` section: +``` +servers: + - url: https://myapi.example.com +``` + +NOTE: The DNS name of the API being scanned must be resolved by the Docker container. Use an IP address if this is not possible. + It imports the definition that you specify and then runs an `Active Scan` against the URLs found. The `Active Scan` is tuned to APIs, so it doesn't bother looking for things like `XSSs`. It also includes 2 scripts that: diff --git a/VERSION.txt b/VERSION.txt index 3f11ef6..f8536a4 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.0.27 \ No newline at end of file +1.0.28 \ No newline at end of file diff --git a/config-example.yml b/config-example.yml index 0788fce..a538e37 100644 --- a/config-example.yml +++ b/config-example.yml @@ -11,7 +11,5 @@ config: apiURL: 'https://api.soos.io/api/' debug: false ajaxSpider: false - fullScan: - minutes: '' apiScan: format: 'openapi' diff --git a/helpers/constants.py b/helpers/constants.py index 76b6c87..43f1acb 100644 --- a/helpers/constants.py +++ b/helpers/constants.py @@ -35,8 +35,7 @@ FILE_WRITE_MODE = "x" UTF_8_ENCODING = "utf-8" - -# OWASP ZAP Constants +# OWASP ZAP Constants - for command line options, see https://www.zaproxy.org/docs/docker/full-scan/ REPORT_SCAN_RESULT_FILENAME = "report.json" REPORT_SCAN_RESULT_FILE = "/zap/wrk/" + REPORT_SCAN_RESULT_FILENAME PY_CMD = "python3" @@ -48,7 +47,7 @@ ZAP_MINIMUM_LEVEL_OPTION = "-l" ZAP_RULES_FILE_OPTION = "-c" ZAP_CONTEXT_FILE_OPTION = "-n" -ZAP_MINUTES_DELAY_OPTION = "-m" +ZAP_SPIDER_MINUTES_OPTION = "-m" ZAP_DEBUG_OPTION = "-d" ZAP_AJAX_SPIDER_OPTION = "-j" ZAP_FORMAT_OPTION = "-f" diff --git a/main.py b/main.py index bdb44e0..7d743ec 100644 --- a/main.py +++ b/main.py @@ -63,8 +63,7 @@ def __init__(self): self.debug_mode: bool = False self.app_version: Optional[str] = None self.ajax_spider_scan: bool = False - self.spider: bool = False - self.minutes_delay: Optional[str] = None + self.spider_minutes: Optional[int] = 120 self.report_request_headers: bool = False self.on_failure: Optional[str] = None self.update_addons: bool = False @@ -81,7 +80,6 @@ def __init__(self): self.request_cookies: Optional[str] = None self.request_header: Optional[str] = None - # Hardcoded values, used for analysis metadata self.dast_analysis_tool: str = Constants.DEFAULT_DAST_TOOL self.dast_analysis_tool_version: str = Constants.DEFAULT_DAST_TOOL_VERSION @@ -173,10 +171,8 @@ def parse_configuration(self, configuration: Dict, target_url: str): self.context_file = value elif key == "contextUser": self.user_context = value - elif key == "fullScan": - self.minutes_delay = value["minutes"] elif key == "fullScanMinutes": - self.minutes_delay = value + self.spider_minutes = value elif key == "apiScan": self.api_scan_format = value["format"] elif key == "apiScanFormat": @@ -295,10 +291,10 @@ def __add_ajax_spider_scan_option__(self, args: List[str]) -> None: if is_true(self.ajax_spider_scan): args.append(Constants.ZAP_AJAX_SPIDER_OPTION) - def __add_minutes_delay_option__(self, args: List[str]) -> None: - if has_value(self.minutes_delay): - args.append(Constants.ZAP_MINUTES_DELAY_OPTION) - args.append(self.minutes_delay) + def __add_spider_minutes_option__(self, args: List[str]) -> None: + if has_value(self.spider_minutes): + args.append(Constants.ZAP_SPIDER_MINUTES_OPTION) + args.append(self.spider_minutes) def __add_format_option__(self, args: List[str]) -> NoReturn: if has_value(self.api_scan_format): @@ -362,7 +358,7 @@ def __generate_command__(self, args: List[str]) -> str: self.__add_rules_file_option__(args) self.__add_context_file_option__(args) self.__add_ajax_spider_scan_option__(args) - self.__add_minutes_delay_option__(args) + self.__add_spider_minutes_option__(args) log("Add ZAP Options?") log(f"Auth Login: {str(self.auth_login_url)}") log(f"Zap Options: {str(self.zap_options)}")