{"record":{"id":"345280f24363f798","repo":"theonedev/onedev","slug":"invalid-request-path-345280","errorCode":null,"errorMessage":"Invalid request path","messagePattern":"Invalid request path","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"warning","filePath":"server-core/src/main/java/io/onedev/server/web/page/project/blob/ProjectBlobPage.java","lineNumber":219,"sourceCode":"\t\n\tprivate State state;\n\t\n\tprivate ObjectId resolvedRevision;\n\t\n\tprivate Component revisionIndexing;\n\t\n\tprivate WebMarkupContainer searchResult;\n\t\n\tprivate AbstractPostAjaxBehavior ajaxBehavior;\n\t\n\tpublic ProjectBlobPage(PageParameters params) {\n\t\tsuper(params);\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(getProject(), revisionAndPathSegments); \n\t\tstate = new State(blobIdent);\n\n\t\tString modeStr = params.get(PARAM_MODE).toString();\n\t\tif (modeStr != null)\n\t\t\tstate.mode = Mode.valueOf(modeStr.toUpperCase());\n\t\t\n\t\tString viewPlain = params.get(PARAM_VIEW_PLAIN).toString();\n\t\tstate.viewPlain = \"true\".equals(viewPlain);\n\t\t\n\t\tstate.urlBeforeEdit = params.get(PARAM_URL_BEFORE_EDIT).toString();\n\t\tstate.urlAfterEdit = params.get(PARAM_URL_AFTER_EDIT).toString();\n\n\t\tif (state.blobIdent.revision != null)","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/page/project/blob/ProjectBlobPage.java#L201-L237","documentation":"ProjectBlobPage builds the blob path from indexed URL parameters; any segment containing '..' is rejected with an ExplicitException to prevent path traversal in repository blob URLs. The message is a plain (unlocalized) ExplicitException.","triggerScenarios":"A blob URL where any indexed path segment includes '..' (e.g. /projects/x/blob/commit/dir/../file).","commonSituations":"Hand-edited or programmatically generated blob URLs collapsing directories, or security scanners probing for traversal vulnerabilities.","solutions":["Remove '..' segments from the URL and use the normalized repository path","Navigate via the repository file browser instead of hand-building blob URLs","URL-encode or resolve relative paths client-side before constructing the link"],"exampleFix":"// before\n/projects/demo/blob/main/docs/../src/App.java\n// after\n/projects/demo/blob/main/src/App.java","handlingStrategy":"validation","validationCode":"if (segments.stream().anyMatch(s -> s.contains(\"..\"))) throw new IllegalArgumentException(\"path must be normalized\");","typeGuard":"boolean isSafePathSegment(String s) { return s != null && !s.contains(\"..\"); }","tryCatchPattern":"try {\n    openBlobPage(params);\n} catch (ExplicitException e) {\n    renderInvalidPathNotice();\n}","preventionTips":["Normalize repository paths client-side before building blob URLs","Never construct blob URLs from untrusted user input containing '..'","Use the UI file browser to generate links"],"tags":["path-traversal","url-validation","security","blob"],"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"}