diff --git a/config/config-template-generic-scan.yaml b/config/config-template-generic-scan.yaml index 8bdb4513..c2ba201f 100644 --- a/config/config-template-generic-scan.yaml +++ b/config/config-template-generic-scan.yaml @@ -23,7 +23,8 @@ general: # podman: RapiDAST runs each scanner using podman # flatpak: RapiDAST runs each scanner using flatpak # none: RapiDAST runs each scanner in the same host or container (where RapiDAST itself is running in a container) - type: "podman" + # When undefined, relies on rapidast-defaults.yaml, or `podman` if nothing is set + #type: "podman" # `scanners' is a section that configures scanning options scanners: @@ -42,15 +43,15 @@ scanners: image: "" # Optional: command to run. By default, the image's ENTRYPOINT will be run - # command: "" + #command: "" # Optional: inject into an existing Pod - # podName: "mypod" + #podName: "mypod" # Optional: list of expected return codes, anything else will be considered as an error. by default: [0] - # validReturns: [ 0, 1 ] + #validReturns: [ 0, 1 ] # Optional: list of volume to mount, e.g.: to retrieve results on the host - # volumes: + #volumes: # - "::Z" # for Linux # - ":" # for Mac diff --git a/config/config-template-multi-scan.yaml b/config/config-template-multi-scan.yaml index 04addc8f..4a27c9df 100644 --- a/config/config-template-multi-scan.yaml +++ b/config/config-template-multi-scan.yaml @@ -33,7 +33,8 @@ general: # podman: RapiDAST runs each scanner using podman # flatpak: RapiDAST runs each scanner using flatpak # none: RapiDAST runs each scanner in the same host or container (where RapiDAST itself is running in a container) - type: "podman" + # When undefined, relies on rapidast-defaults.yaml, or `podman` if nothing is set + #type: "podman" # `scanners' is a section that configures scanning options # See the config-template-long.yaml for more options @@ -49,11 +50,10 @@ scanners: disabledRules: "2,10015,10027,10096,10024" # Enable activeScan by uncommenting, once scans with the passiveScan only has run successfully - # # If no policy is chosen, a default ("API-scan-minimal") will be selected - # # The list of policies can be found in scanners/zap/policies/ + # If no policy is chosen, a default ("API-scan-minimal") will be selected + # The list of policies can be found in scanners/zap/policies/ #activeScan: # policy: "API-scan-minimal" - # generic_1: # This is a generic scanner configuration, defined by the user diff --git a/config/config-template-zap-long.yaml b/config/config-template-zap-long.yaml index 427d0d0c..e03cb384 100644 --- a/config/config-template-zap-long.yaml +++ b/config/config-template-zap-long.yaml @@ -72,7 +72,8 @@ general: # flatpak: RapiDAST runs each scanner using flatpak # none: RapiDAST runs each scanner in the same host or container (where RapiDAST itself is running in a container) # container. - type: "podman" + # When undefined, relies on rapidast-defaults.yaml, or `podman` if nothing is set + #type: "podman" # `scanners' is a section that configures scanning options @@ -111,7 +112,7 @@ scanners: browserId: firefox-headless passiveScan: - # optional comma-separated list of passive rules to disable + # Optional comma-separated list of passive rules to disable # Use https://www.zaproxy.org/docs/alerts/ to match rule with its ID disabledRules: "2,10015,10027,10096,10024" @@ -126,12 +127,12 @@ scanners: #podName: "mypod" # optional: inject ZAP in an existing Pod executable: "zap.sh" # for Linux - # executable: "/Applications/OWASP ZAP.app/Contents/Java/zap.sh" # for MacOS, when general.container.type is 'none' only + #executable: "/Applications/OWASP ZAP.app/Contents/Java/zap.sh" # for MacOS, when general.container.type is 'none' only report: format: ["json"] - # format: ["json","html","sarif","xml"] # default: "json" only + #format: ["json","html","sarif","xml"] # default: "json" only urls: # Optional, `includes` and `excludes` take a list of regexps. @@ -146,14 +147,14 @@ scanners: # - "^https?://example.com:3000/do-not-descend-here/.*$" miscOptions: - # enableUI (default: false), requires a compatible runtime (e.g.: flatpak or no containment) + # EnableUI (default: false), requires a compatible runtime (e.g.: flatpak or no containment) enableUI: False # Defaults to True, set False to prevent auto update of ZAP plugins updateAddons: True # If set to True and authentication is oauth2_rtoken: manually download schemas (e.g.: openAPI, GraphQL) oauth2ManualDownload: False - # overwrite the default port in case it is required. The default port was selected to avoid any collision with other services + # Overwrite the default port in case it is required. The default port was selected to avoid any collision with other services zapPort: 8080 # Maximum heap size of the JVM. Default: ΒΌ of the RAM. acceptable values: [0-9]+[kKmMgG]? diff --git a/config/config-template-zap-mac.yaml b/config/config-template-zap-mac.yaml index 2ddee681..b4c35861 100644 --- a/config/config-template-zap-mac.yaml +++ b/config/config-template-zap-mac.yaml @@ -32,11 +32,12 @@ general: # podman: RapiDAST runs each scanner using podman # flatpak: RapiDAST runs each scanner using flatpak # none: RapiDAST runs each scanner in the same host or container (where RapiDAST itself is running in a container) + # When undefined, relies on rapidast-defaults.yaml, or `podman` if nothing is set type: "none" scanners: zap: - # define a scan through the ZAP scanner + # Define a scan through the ZAP scanner apiScan: apis: apiFile: "path/to/local/openapi-schema" diff --git a/config/config-template-zap-simple.yaml b/config/config-template-zap-simple.yaml index 76433416..a475741b 100644 --- a/config/config-template-zap-simple.yaml +++ b/config/config-template-zap-simple.yaml @@ -33,7 +33,8 @@ general: # podman: RapiDAST runs each scanner using podman # flatpak: RapiDAST runs each scanner using flatpak # none: RapiDAST runs each scanner in the same host or container (where RapiDAST itself is running in a container) - type: "podman" + # When undefined, relies on rapidast-defaults.yaml, or `podman` if nothing is set + #type: "podman" # `scanners' is a section that configures scanning options # See the config-template-long.yaml for more options @@ -49,7 +50,7 @@ scanners: disabledRules: "2,10015,10027,10096,10024" # Enable activeScan by uncommenting, once scans with the passiveScan only has run successfully - # # If no policy is chosen, a default ("API-scan-minimal") will be selected - # # The list of policies can be found in scanners/zap/policies/ + # If no policy is chosen, a default ("API-scan-minimal") will be selected + # The list of policies can be found in scanners/zap/policies/ #activeScan: # policy: "API-scan-minimal" diff --git a/configmodel/__init__.py b/configmodel/__init__.py index c15ff8fe..96355c28 100644 --- a/configmodel/__init__.py +++ b/configmodel/__init__.py @@ -191,6 +191,8 @@ def path_to_list(path): - path_to_list(('a','b','c')) => ['a','b','c'] """ + if not path: + return [] if isinstance(path, str): path = path.split(".") return list(path) diff --git a/containerize/Containerfile b/containerize/Containerfile index 26997950..d8abc934 100644 --- a/containerize/Containerfile +++ b/containerize/Containerfile @@ -39,6 +39,9 @@ COPY ./utils/ /opt/rapidast/utils/ COPY ./config/ /opt/rapidast/config/ COPY ./requirements.txt /opt/rapidast/ +### Overload default config (set 'none' as default container type) +COPY ./containerize/container_default_config.yaml /opt/rapidast/rapidast-defaults.yaml + ### Add /opt/{zap,rapidast}/ to the PATH (for any user and future user) COPY ./containerize/path_rapidast.sh /etc/profile.d/rapidast.sh diff --git a/containerize/container_default_config.yaml b/containerize/container_default_config.yaml new file mode 100644 index 00000000..ea31cc17 --- /dev/null +++ b/containerize/container_default_config.yaml @@ -0,0 +1,3 @@ +general: + container: + type: "none" diff --git a/rapidast.py b/rapidast.py index 18db11e7..0c4726ce 100755 --- a/rapidast.py +++ b/rapidast.py @@ -158,15 +158,27 @@ def run(): f"log level set to debug. Config file: '{parser.parse_args().config_file}'" ) + # Load config file try: config = configmodel.RapidastConfigModel( yaml.safe_load(load_config_file(parser.parse_args().config_file)) ) except yaml.YAMLError as exc: raise RuntimeError( - f"Something went wrong while parsing one of the config '{parser.parse_args().config_file}':\n {str(exc)}" + f"YAML error in config {parser.parse_args().config_file}':\n {str(exc)}" ) from exc + # Optionally adds default if file exists (will not overwrite existing entries) + default_conf = os.path.join(os.path.dirname(__file__), "rapidast-defaults.yaml") + if os.path.exists(default_conf): + logging.info(f"Loading defaults from: {default_conf}") + try: + config.merge(yaml.safe_load(load_config_file(default_conf)), preserve=True) + except yaml.YAMLError as exc: + raise RuntimeError( + f"YAML error in config {default_conf}':\n {str(exc)}" + ) from exc + # Update to latest config schema if need be config = configmodel.converter.update_to_latest_config(config)