theonedev/onedev · error · ExplicitException
Invalid report name
Error message
Invalid report name
What it means
ProblemReport.checkReportName rejects report names containing ".." to prevent path traversal when the name is resolved under the report directory. The check runs when reading code problem reports (readFrom, getCodeProblems) and throws ExplicitException "Invalid report name".
Source
Thrown at server-core/src/main/java/io/onedev/server/codequality/ProblemReport.java:102
public static List<CodeProblem> getCodeProblems(Build build, String blobPath,
@Nullable String reportName) {
if (reportName != null)
checkReportName(reportName);
Long projectId = build.getProject().getId();
Map<String, Collection<CodeProblem>> problemsMap = OneDev.getInstance(ProjectService.class)
.runOnActiveServer(projectId, new GetCodeProblems(projectId, build.getNumber(),
blobPath, reportName));
List<CodeProblem> problems = new ArrayList<>();
for (var entry: problemsMap.entrySet()) {
if (SecurityUtils.canAccessReport(build, entry.getKey()))
problems.addAll(entry.getValue());
}
return problems;
}
private static void checkReportName(String reportName) {
if (reportName.contains(".."))
throw new ExplicitException("Invalid report name");
}
public void writeTo(File reportDir) {
File dataFile = new File(reportDir, REPORT);
try (var os = new BufferedOutputStream(new FileOutputStream(dataFile), BUFFER_SIZE)) {
SerializationUtils.serialize(this, os);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getReportLockName(Build build) {
return getReportLockName(build.getProject().getId(), build.getNumber());
}
public static String getReportLockName(Long projectId, Long buildNumber) {
return ProblemReport.class.getName() + ":" + projectId + ":" + buildNumber;
}View on GitHub (pinned to d44925c47c)
Solutions
- Strip or reject ".." sequences in the report name before calling the API
- Pass a single-segment report name and keep directory nesting outside the name
- Validate externally supplied report names at the ingestion boundary
Example fix
// before
var problems = report.getCodeProblems("../workspace/problems");
// after
var problems = report.getCodeProblems("static-analysis"); Defensive patterns
Strategy: validation
Validate before calling
// validate before calling ProblemReport APIs
if (reportName == null || reportName.contains(".."))
throw new IllegalArgumentException("problem report name must not contain '..'"); Type guard
function isValidProblemReportName(name) { return typeof name === 'string' && name.length > 0 && !name.includes('..') && !/[/\\]/.test(name); } Try / catch
try {
problems = ProblemReport.getCodeProblems(reportName);
} catch (ExplicitException e) {
if ("Invalid report name".equals(e.getMessage())) {
problems = ProblemReport.getCodeProblems(sanitizeReportName(reportName));
} else throw e;
} Prevention
- Sanitize externally supplied problem report names before use
- Reject names containing '..' at the ingestion/plugin boundary
- Prefer enumerating available report names via the API instead of constructing them from user input
When it happens
Trigger: Calling ProblemReport.getCodeProblems(reportName) or readFrom(reportDir, reportName) with a reportName containing "..", such as "../../etc" or names built from unsanitized CI parameters.
Common situations: Problem/issue report names sourced from untrusted build configs or REST input; scripts passing relative paths instead of a bare report name.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/d703ab4ef7198924.
Report an issue: GitHub.