{"record":{"id":"75062ad6633b7aa2","repo":"theonedev/onedev","slug":"invalid-request-path-75062a","errorCode":null,"errorMessage":"Invalid request path","messagePattern":"Invalid request path","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-plugin/server-plugin-report-html/src/main/java/io/onedev/server/plugin/report/html/HtmlReportDownloadResource.java","lineNumber":53,"sourceCode":"\t\n\t@Override\n\tprotected ResourceResponse newResourceResponse(Attributes attributes) {\n\t\tvar params = attributes.getParameters();\n\n\t\tvar projectId = params.get(PARAM_PROJECT).toLong();\n\t\tvar project = OneDev.getInstance(ProjectService.class).load(projectId);\n\t\t\n\t\tvar buildNumber = params.get(PARAM_BUILD).toLong();\n\t\tvar build = OneDev.getInstance(BuildService.class).find(project, buildNumber);\n\t\tif (build == null) {\n\t\t\tString message = String.format(\"Unable to find build (project: %s, build number: %d)\",\n\t\t\t\t\tproject.getPath(), buildNumber);\n\t\t\tthrow new EntityNotFoundException(message);\n\t\t}\n\t\t\n\t\tString reportName = params.get(PARAM_REPORT).toString();\n\t\tif (reportName.contains(\"..\"))\n\t\t\tthrow new ExplicitException(\"Invalid request path\");\n\n\t\tif (!SecurityUtils.canAccessReport(build, reportName))\n\t\t\tthrow new UnauthorizedException();\n\n\t\tList<String> pathSegments = new ArrayList<>();\n\n\t\tfor (int i = 0; i < params.getIndexedCount(); i++) {\n\t\t\tString pathSegment = params.get(i).toString();\n\t\t\tif (pathSegment.contains(\"..\"))\n\t\t\t\tthrow new ExplicitException(\"Invalid request path\");\n\t\t\tif (pathSegment.length() != 0)\n\t\t\t\tpathSegments.add(pathSegment);\n\t\t}\n\n\t\tif (pathSegments.isEmpty())\n\t\t\tthrow new ExplicitException(\"File path has to be specified\");\n\n\t\tvar filePath = Joiner.on(\"/\").join(pathSegments);","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-report-html/src/main/java/io/onedev/server/plugin/report/html/HtmlReportDownloadResource.java#L35-L71","documentation":"The HTML report download resource rejects a report name containing '..' with an ExplicitException 'Invalid request path'. This is a path-traversal guard: '..' in the report name could escape the report directory. It runs after build lookup and before the access check.","triggerScenarios":"Requesting the html report download resource with PARAM_REPORT containing '..' (e.g. '../secrets').","commonSituations":"Hand-crafted or templated URLs with path segments not URL-encoded properly; probing/fragile link generators concatenating paths; security scanners.","solutions":["Pass a plain report name without any '..' or path separators in the report parameter","URL-encode or sanitize the link generated for the report","If multiple path levels are needed, use indexed path segments, never '..'"],"exampleFix":"// before\nreport=../../etc\n// after\nreport=my-report","handlingStrategy":"validation","validationCode":"if (reportName.contains(\"..\")) throw new IllegalArgumentException(\"Report name must not contain '..'\");","typeGuard":"function isSafeSegment(s) { return typeof s === 'string' && !s.includes('..'); }","tryCatchPattern":"try { fetch(url); } catch (ExplicitException e) { // sanitize report name and rebuild URL }","preventionTips":["Sanitize/URL-encode all report-name values before building URLs","Never pass user-controlled paths into report resource URLs","Treat report names as identifiers, not paths"],"tags":["security","path-traversal","report","rest"],"backgroundTag":"path-traversal-blocked","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}