theonedev/onedev · error · ExplicitException
Invalid artifact path
Error message
Invalid artifact path
What it means
normalizeArtifactPath throws this ExplicitException when the supplied artifact path contains '..', which could allow directory traversal outside the build's artifact directory. It is a deliberate safety check rejecting any path that escapes the artifact root.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/ArtifactResource.java:54
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Singleton
public class ArtifactResource {
private final BuildService buildService;
@Inject
public ArtifactResource(BuildService buildService) {
this.buildService = buildService;
}
@Nullable
private String normalizeArtifactPath(@Nullable String artifactPath) {
if (StringUtils.isNotBlank(artifactPath)) {
artifactPath = StringUtils.stripStart(artifactPath, "/");
if (StringUtils.isNotBlank(artifactPath)) {
if (artifactPath.contains(".."))
throw new ExplicitException("Invalid artifact path");
return artifactPath;
}
}
return null;
}
@Api(order=100, description = "Get artifact info of specified path")
@Path("/{buildId}/infos{artifactPath:(/.*)?}")
@GET
public ArtifactInfo getArtifactInfo(@PathParam("buildId") Long buildId,
@PathParam("artifactPath") @Api(example = "/path/to/directoryOrFile") String artifactPath) {
Build build = buildService.load(buildId);
if (!SecurityUtils.canAccessProject(build.getProject()))
throw new UnauthorizedException();
return buildService.getArtifactInfo(build, normalizeArtifactPath(artifactPath));
}
@Api(order=200, description = "Download artifact of specified path")View on GitHub (pinned to d44925c47c)
Solutions
- Remove '..' from the artifact path and address artifacts by their path under the build root
- Validate/canonicalize the path in the calling script before calling the API
- Reference the artifact via its exact published path shown in the build's artifacts tab
Example fix
// before path="../../secrets/key.jar" // after path="target/app.jar"
Defensive patterns
Strategy: validation
Validate before calling
if (artifactPath && artifactPath.includes('..')) throw new Error('artifactPath must not contain ..'); Type guard
const isSafeArtifactPath = (p) => typeof p === 'string' && !p.includes('..'); Try / catch
try { upload(path) } catch (e) { if (/Invalid artifact path/.test(e.message)) { console.error('Path rejected: remove any ".." segments'); } else { throw e } } Prevention
- Always normalize and canonicalize paths before sending
- Reject '..' segments in user-supplied artifact paths at the script level
- Reference artifacts by paths as shown in the build artifacts listing
When it happens
Trigger: Passing a path containing '..' (e.g. '../../etc/passwd', 'a/../../b') as artifactPath to getArtifactInfo, downloadArtifact, uploadArtifact, or deleteArtifact.
Common situations: Concatenating user-supplied file paths into artifact URLs; misconfigured CI variables that resolve to relative paths with '..'; path templates built with build-number placeholders inserted incorrectly.
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
- Count should not be greater than ${RestConstants.MAX_PAGE_SI
- Count should not be greater than
- Invalid report name
- Invalid report name
- Invalid request path
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/3d446c60e511fe3d.
Report an issue: GitHub.