{"record":{"id":"f541b8a6093bd97b","repo":"theonedev/onedev","slug":"invalid-request-path-f541b8","errorCode":null,"errorMessage":"Invalid request path","messagePattern":"Invalid request path","errorType":"exception","errorClass":"ExplicitException","httpStatus":400,"severity":"warning","filePath":"server-core/src/main/java/io/onedev/server/web/resource/RawBlobResource.java","lineNumber":71,"sourceCode":"\t\n\tprivate static final String PARAM_DISPOSITION = \"disposition\";\n\t\n\tprivate static final Logger logger = LoggerFactory.getLogger(RawBlobResource.class);\n\n\t@Override\n\tprotected ResourceResponse newResourceResponse(Attributes attributes) {\n\t\tPageParameters params = attributes.getParameters();\n\n\t\tString projectPath = params.get(ProjectMapperUtils.PARAM_PROJECT).toString();\n\t\tProject project = getProjectService().findByPath(projectPath);\n\t\tif (project == null)\n\t\t\tthrow new EntityNotFoundException(\"Project not found: \" + projectPath);\n\t\t\n\t\tList<String> revisionAndPathSegments = new ArrayList<>();\n\t\tfor (int i = 0; i < params.getIndexedCount(); i++) {\n\t\t\tString segment = params.get(i).toString();\n\t\t\tif (segment.contains(\"..\"))\n\t\t\t\tthrow new ExplicitException(\"Invalid request path\");\n\t\t\tif (segment.length() != 0)\n\t\t\t\trevisionAndPathSegments.add(segment);\n\t\t}\n\n\t\tBlobIdent blobIdent = new BlobIdent(project, revisionAndPathSegments);\n\n\t\tString revision = blobIdent.revision;\n\t\tString path = blobIdent.path;\n\t\tif (StringUtils.isBlank(revision) || StringUtils.isBlank(path))\n\t\t\tthrow new NotAcceptableException(\"Revision and path should be specified\");\n\n\t\tif (!SecurityUtils.canReadCode(project))\n\t\t\tthrow new UnauthorizedException();\n\n\t\tfinal Blob blob = project.getBlob(new BlobIdent(revision, path, 0), true);\n\n\t\tResourceResponse response = new ResourceResponse();\n\t\tresponse.setAcceptRange(ContentRangeType.BYTES);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/resource/RawBlobResource.java#L53-L89","documentation":"RawBlobResource validates each indexed path segment of the raw blob URL; any segment containing '..' is rejected with ExplicitException to prevent path traversal out of the repository. This is a deliberate security guard, not a data problem.","triggerScenarios":"Requesting a raw blob URL where any path segment contains '..' (e.g. /~raw/proj/main/../../secret) — typically hand-crafted or malicious URLs.","commonSituations":"Path traversal probing/scanning; buggy URL builders that don't normalize '..' out of file paths; users pasting manipulated URLs.","solutions":["Remove '..' segments from the requested path in your URL builder or script.","Normalize the file path relative to the repo root before constructing the raw URL.","Ensure scanners/tools do not send traversal-style URLs to this endpoint."],"exampleFix":"// before\nString url = \"/~raw/proj/main/\" + \"docs/../../README.md\";\n// after\nString url = \"/~raw/proj/main/\" + Path.of(\"docs/../README.md\").normalize();","handlingStrategy":"validation","validationCode":"if (filePath.split(\"/\").anyMatch(seg -> seg.equals(\"..\"))) throw new IllegalArgumentException(\"Path must not contain '..'\");","typeGuard":"boolean isSafeSegment(String s) { return s != null && !s.contains(\"..\"); }","tryCatchPattern":null,"preventionTips":["Normalize repository paths before building URLs.","Never interpolate untrusted path input directly into raw URLs."],"tags":["security","path-traversal","http"],"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-14T05:17:10.506Z"}