theonedev/onedev · warning · ExplicitException

Invalid request path

Error message

Invalid request path

What it means

BuildReportPage takes the report name directly from the URL. To prevent path traversal against the report storage directory, the constructor rejects any report name containing '..' and throws ExplicitException('Invalid request path'). This is a deliberate security check, not a data error.

Source

Thrown at server-core/src/main/java/io/onedev/server/web/page/project/builds/detail/report/BuildReportPage.java:20

import io.onedev.commons.utils.ExplicitException;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import io.onedev.server.model.Build;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.web.page.project.builds.detail.BuildDetailPage;

public abstract class BuildReportPage extends BuildDetailPage {

	private static final String PARAM_REPORT = "report";

	private final String reportName;
	
	public BuildReportPage(PageParameters params) {
		super(params);
		reportName = params.get(PARAM_REPORT).toString();
		if (reportName.contains(".."))
			throw new ExplicitException("Invalid request path");
	}
	
	@Override
	protected boolean isPermitted() {
		return SecurityUtils.canAccessReport(getBuild(), reportName);
	}
	
	public String getReportName() {
		return reportName;
	}

	public static PageParameters paramsOf(Build build, String reportName) {
		PageParameters params = paramsOf(build);
		params.add(PARAM_REPORT, reportName);
		return params;
	}
	
}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Remove '..' from the report name in the URL; use the exact report name as shown on the build page.
  2. URL-encode or validate report names in any integration that generates report links.
  3. If this appears unexpectedly, treat it as a potential probing attempt and check access logs.

Example fix

// before
String url = "/~builds/5/reports/" + userInput; // userInput="../x"
// after
String url = "/~builds/5/reports/" + URLEncoder.encode(sanitizeReportName(userInput), StandardCharsets.UTF_8);
Defensive patterns

Strategy: validation

Validate before calling

if (reportName == null || reportName.contains("..") || reportName.isBlank()) {
    throw new IllegalArgumentException("Invalid report name");
}

Type guard

static boolean isSafeSegment(String s) { return s != null && !s.contains("..") && !s.isBlank(); }

Try / catch

try {
    // open report page
} catch (ExplicitException e) {
    // surface e.getMessage() to the user, do not retry
}

Prevention

When it happens

Trigger: Requesting a build report page where the PARAM_REPORT path segment contains '..' (e.g. /~builds/5/reports/../../secrets), typically crafted URLs or links generated with unescaped report names.

Common situations: Security scanning / pen-testing OneDev; a custom integration that interpolates raw report names into URLs; clicking a tampered link.

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/0502749399cd450f. Report an issue: GitHub.