{"record":{"id":"bc757e8b0ad1d95f","repo":"alibaba/nacos","slug":"absolute-path-not-allowed-path","errorCode":null,"errorMessage":"Absolute path not allowed: {path}","messagePattern":"Absolute path not allowed: (.+?)","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"critical","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/model/skills/SkillUtils.java","lineNumber":176,"sourceCode":"        validatePathSafety(entryPath);\n        return entryPath;\n    }\n    \n    /**\n     * Validate that a path does not contain path traversal sequences or absolute path indicators.\n     *\n     * @param path the path to validate\n     * @throws SecurityException if path contains unsafe sequences\n     */\n    public static void validatePathSafety(String path) {\n        if (path == null) {\n            return;\n        }\n        if (path.contains(PATH_TRAVERSAL_SEQUENCE)) {\n            throw new SecurityException(\"Path traversal detected: \" + path);\n        }\n        if (path.startsWith(\"/\") || path.startsWith(\"\\\\\")) {\n            throw new SecurityException(\"Absolute path not allowed: \" + path);\n        }\n    }\n    \n    /**\n     * Validate that a resolved path stays within the expected base directory.\n     *\n     * @param baseDir the base directory that must contain the target\n     * @param target  the resolved target path\n     * @throws SecurityException if target escapes baseDir\n     */\n    public static void validatePathContainment(Path baseDir, Path target) {\n        if (!target.normalize().startsWith(baseDir.normalize())) {\n            throw new SecurityException(\n                \"Path escapes target directory: \" + target + \" is outside \" + baseDir);\n        }\n    }\n    \n    /**","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/model/skills/SkillUtils.java#L158-L194","documentation":"Thrown by SkillUtils.validatePathSafety as a SecurityException when the supplied path starts with '/' or '\\\\'. The method is a hard security gate used to validate ZIP entry names and skill resource paths before they are written to disk, blocking absolute paths that could write outside the intended skill directory.","triggerScenarios":"Calling SkillUtils.validatePathSafety(path) where path begins with a forward slash or backslash, or feeding validateZipEntryPaths a ZIP whose entry name is absolute (e.g. \"/etc/passwd\" or \"\\\\windows\\\\system32\").","commonSituations":"A skill bundle downloaded from the server contains a malicious or malformed entry with an absolute name; a client constructs a SkillResource whose path field was accidentally prefixed with '/'; a ZIP built by a third-party tool stored entries with leading slashes.","solutions":["Strip leading '/' or '\\\\' from the path/entry name before calling validatePathSafety or before creating the ZIP.","If you control the ZIP producer, use relative entry names only (e.g. 'skillName/SKILL.md', never '/skillName/SKILL.md').","Reject the offending skill bundle at the source and re-export it with relative paths."],"exampleFix":"// before\nString entryPath = \"/skillName/SKILL.md\";\nSkillUtils.validatePathSafety(entryPath); // throws\n\n// after\nString entryPath = \"skillName/SKILL.md\";\nSkillUtils.validatePathSafety(entryPath); // ok","handlingStrategy":"validation","validationCode":"// Sanitize before calling validatePathSafety\nstatic String safeRelative(String path) {\n    if (path == null) return null;\n    String p = path;\n    while (p.startsWith(\"/\") || p.startsWith(\"\\\\\")) p = p.substring(1);\n    if (p.contains(\"..\")) throw new IllegalArgumentException(\"Refusing unsafe path: \" + path);\n    return p;\n}\nString clean = safeRelative(entryPath);\nSkillUtils.validatePathSafety(clean);","typeGuard":"static boolean isSafeRelativePath(String p) {\n    return p != null && !p.startsWith(\"/\") && !p.startsWith(\"\\\\\") && !p.contains(\"..\");\n}","tryCatchPattern":"try {\n    SkillUtils.validatePathSafety(entryPath);\n} catch (SecurityException e) {\n    log.warn(\"Rejecting unsafe entry path: {}\", entryPath);\n    throw e;\n}","preventionTips":["Never build ZIP entries with leading slashes; always use relative 'dir/name' forms.","Run validateZipEntryPaths on any ZIP received from external sources before extraction.","Treat SecurityException from SkillUtils as a hard reject — never catch-and-continue silently."],"tags":["java","nacos","ai","skills","security","path-traversal","zip"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}