ZAP Automation includePaths

34 views
Skip to first unread message

Lloyd

unread,
Oct 28, 2025, 3:10:25 AM (9 days ago) Oct 28
to ZAP User Group
Hi, I'm currently configuring automatic scanning using ZAP and I encountered a problem with includePaths.

I have a stage environment with multiple version deployed that's separated using path. So example.com/v1.0.0/index.php,  example.com/v2.0.0/index.ph, etc. I want to scan only the v1.0.0 of this website (best case) or at least only show v1.0.0 in the report, but I can't seem to find the proper configuration.

This is my current automation configuration
{
  "bucket_name": "devops-tools-artifacts",
  "bucket_prefix": "zap-reports",
  "config.yaml": {
    "env": {
      "contexts": [
        {
          "name": "example.com",
          "urls": [
            "https://example.com",
            "https://sso-example.com"
          ],
          "includePaths": [
            "^https://example.com/v1.0.0.*",
            "^https://sso-example.com.*"
          ],
          "authentication": {
            "method": "browser",
            "parameters": {
              "loginPageUrl": "https://sso-example.com/en/login",
              "loginPageWait": 30,
              "steps": [
                {
                  "description": "auto",
                  "type": "AUTO_STEPS",
                  "timeout": 5000
                },
                {
                  "description": "fillusername",
                  "type": "USERNAME",
                  "xpath": "//input[@name='account']",
                  "timeout": 5000
                },
                {
                  "description": "fillpassword",
                  "type": "PASSWORD",
                  "xpath": "//input[@name='pwd']",
                  "timeout": 5000
                },
                {
                  "description": "filltotp",
                  "type": "TOTP_FIELD",
                  "xpath": "//input[@name='mfaCode']",
                  "timeout": 5000
                },
                {
                  "description": "clickenter",
                  "type": "RETURN",
                  "xpath": "//input[@name='mfaCode']",
                  "timeout": 5000
                },
                {
                  "description": "clickcmpimage",
                  "type": "CLICK",
                  "xpath": "//a[.//img[@alt='application']]",
                  "timeout": 5000
                }
              ]
            },
            "verification": {
              "method": "poll",
              "loggedInRegex": "\\Q200OK\\E",
              "loggedOutRegex": "\\Q401Unauthorized\\E",
              "pollFrequency": 5,
              "pollUnits": "seconds",
              "pollUrl": "https://sso-example.com/api/portal/user",
              "pollPostData": ""
            }
          },
          "sessionManagement": {
            "method": "cookie"
          },
          "technology": {},
          "structure": {},
          "users": [
            {
              "name": "us...@example.com",
              "credentials": {
                "totp": {
                  "secret": "SECRETKEY",
                  "period": 30,
                  "digits": 6,
                  "algorithm": "SHA1"
                },
                "password": "password",
                "username": "us...@example.com"
              }
            }
          ]
        }
      ],
      "parameters": {}
    },
    "jobs": [
      {
        "type": "passiveScan-config",
        "parameters": {}
      },
      {
        "type": "spider",
        "parameters": {
          "context": "example.com",
          "user": "us...@example.com"
        },
        "tests": [
          {
            "name": "Atleast75URLsfound",
            "type": "stats",
            "onFail": "INFO",
            "statistic": "automation.spider.urls.added",
            "operator": ">=",
            "value": 75
          }
        ]
      },
      {
        "type": "spiderAjax",
        "parameters": {
          "context": "example.com",
          "user": "us...@example.com"
        },
        "tests": [
          {
            "name": "Atleast100URLsfound",
            "type": "stats",
            "onFail": "INFO",
            "statistic": "spiderAjax.urls.added",
            "operator": ">=",
            "value": 100
          }
        ]
      },
      {
        "type": "passiveScan-wait",
        "parameters": {}
      },
      {
        "type": "report",
        "parameters": {
          "reportTitle": "ZAPbyCheckmarxScanningReport",
          "template": "traditional-pdf"
        },
        "sites": [
          "v1.0.0"
        ]
      },
      {
        "type": "exitStatus",
        "parameters": {}
      }
    ]
  }
}

As you can see, I've tried adding the v1.0.0 path in the "includePaths": "^https://example.com/v1.0.0.*" and also filter the report to only include v1.0.0 by using "sites": ["v1.0.0"]

However, after all this, I can still see v2.0.0 URL in the report. Is there anything that I do wrong?

If you click example.com, you will be shown many links to different versions. I suspect this is what's causing the spider to click the link and scan it, but it shouldn't be included in the report since I'm filtering the result.

I'm running ZAP inside Kubernetes with this image zaproxy/zap-stable:2.16.1 and using this command "zap.sh -cmd -autorun /zap/wrk/config.yaml"

Thank you

Simon Bennetts

unread,
Nov 3, 2025, 6:05:00 AM (3 days ago) Nov 3
to ZAP User Group
Hiya,

As per https://www.zaproxy.org/docs/desktop/addons/automation-framework/environment/ the "urls" section is: A mandatory list of top level urls, everything under each url will be included
So you are already including all of the URLs under "https://example.com" and "https://sso-example.com", you dont need to include them again.

You have 2 options:
  1. Specify "https://example.com/v1.0.0/" as your first url
  2. Keep the urls as now but add an excludePaths section with "https://example.com/v2.0.0/.*"
Note that for the report / sites section you should use strings like "https://example.com/v1.0.0/" - the code actually does a "start with" match.

Cheers,

Simon
Reply all
Reply to author
Forward
0 new messages