{"record":{"id":"45818dc9dcf54b80","repo":"zaproxy/zaproxy","slug":"illegal-parameter-45818d","errorCode":"illegal_parameter","errorMessage":"illegal_parameter","messagePattern":"illegal_parameter","errorType":"error_code","errorClass":"ApiException","httpStatus":null,"severity":"error","filePath":"zap/src/main/java/org/zaproxy/zap/extension/api/CoreAPI.java","lineNumber":999,"sourceCode":"\n        throw new ApiException(Type.USER_NOT_FOUND, PARAM_USER_NAME);\n    }\n\n    /**\n     * Returns a Path for the child file underneath the specified parent directory. Detects and\n     * throws an exception if a path traversal attack is used.\n     *\n     * @param parent the parent directory\n     * @param child the child path, which can include sub directories\n     * @return a Path for the child file\n     * @throws ApiException is a path traversal attack is used\n     */\n    protected static Path getChildPath(String parent, String child) throws ApiException {\n        Path childPath = Paths.get(parent, child).normalize();\n        Path parentPath = Paths.get(parent).normalize();\n        if (!childPath.startsWith(parentPath)) {\n            LOGGER.error(\"Detected path traversal attack {}\", childPath);\n            throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_FILENAME);\n        }\n        return childPath;\n    }\n\n    private static Path getSessionPath(String path) throws ApiException {\n        try {\n            return SessionUtils.getSessionPath(path);\n        } catch (IllegalArgumentException e) {\n            throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_SESSION, e);\n        }\n    }\n\n    private static ApiImplementor getNetworkImplementor() throws ApiException {\n        return API.getInstance().getImplementors().get(\"network\");\n    }\n\n    private void setProxyChainExcludedDomainsEnabled(boolean enabled) {\n        List<DomainMatcher> domains = getProxyExcludedDomains();","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/zaproxy/zaproxy/blob/9d1970a436b1b189bfb588fc88864c80d9baf6a5/zap/src/main/java/org/zaproxy/zap/extension/api/CoreAPI.java#L981-L1017","documentation":"ApiException(ILLEGAL_PARAMETER, filename) is thrown by CoreAPI.getChildPath when the resolved child path, after normalize(), does not start with the normalized parent path — i.e. the request attempts a path traversal ('..') outside the allowed directory. This is a deliberate security guard; ZAP logs 'Detected path traversal attack' before throwing. It protects endpoints that write/read session or other files under a fixed parent.","triggerScenarios":"Calling file-related core API actions (e.g. saveSession with a path, snapshot session) whose filename contains '../' or absolute paths that escape the parent directory supplied by the handler; any child parameter normalizing outside parentPath.","commonSituations":"Scripts passing user-supplied or temp paths directly into saveSession/loadSession; Windows vs Unix path mixing causing startsWith to fail unexpectedly; relative paths containing .. that the caller assumed would be resolved; automated fuzzers hitting ZAP triggering the guard.","solutions":["Pass a plain filename without path separators or '..' so it resolves inside the intended parent.","Provide an absolute target path that is genuinely inside the parent directory the endpoint uses (e.g. ZAP session directory).","Resolve intended location first (e.g. File(parentDir, filename).getCanonicalPath()) and confirm it stays under the parent before calling.","Never interpolate untrusted input into the path parameter; validate/sanitize it client-side."],"exampleFix":"// before\nzap.core.save_session('../../tmp/evil.session', overwrite=True)  // illegal_parameter\n// after\nimport os\nname = os.path.basename(user_input)  # strips traversal\nzap.core.save_session(name, overwrite=True)","handlingStrategy":"validation","validationCode":"import os\ndef safe_child(parent, child):\n    base = os.path.realpath(parent)\n    target = os.path.realpath(os.path.join(base, child))\n    if not (target == base or target.startswith(base + os.sep)):\n        raise ValueError(f'path escapes parent: {child}')\n    return target","typeGuard":"def is_within(parent, child):\n    base = os.path.realpath(parent)\n    t = os.path.realpath(os.path.join(base, child))\n    return t.startswith(base + os.sep)","tryCatchPattern":"try:\n    zap.core.save_session(filename, True)\nexcept zapv2.exceptions.APIException as e:\n    if 'illegal_parameter' in str(e):\n        raise ValueError('path traversal rejected: use a bare filename inside the session dir') from e","preventionTips":["Never concatenate user input into the filename/path parameter; strip with os.path.basename","Check for '..' segments and absolute paths in client-side input validation","Keep generated session files inside ZAP's designated session directory","Audit fuzzer/test inputs for traversal payloads before pointing them at ZAP"],"tags":["api","zap","path-traversal","illegal-parameter","security"],"backgroundTag":"path-traversal-detected","analyzedSha":"9d1970a436b1b189bfb588fc88864c80d9baf6a5","analyzedAt":"2026-09-05T19:26:59.356Z","contentChangedAt":"2026-09-05T19:26:59.356Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}