Class WorkspaceGuard
Why link resolution, not just string checks
Rejecting .. and absolute paths stops the naive attack. It does nothing about a
workspace that contains a link pointing somewhere else — a symlink on Linux, a directory
junction on Windows. Both let a lexically innocent relative path such as
config/web.config resolve to a file outside the workspace entirely.
So confinement is decided on the real path, after the operating system has resolved
every component. Gate 3 measured why this matters on Windows: Files.isSymbolicLink returns
false for a directory junction, so an implementation that screened for symlinks alone would let
junctions through. Path.toRealPath(java.nio.file.LinkOption...) resolves both.
This class deliberately uses only java.nio. The Jenkins step layer additionally calls
FilePath.isDescendant as defence in depth, but the rule enforced here must hold without a
Jenkins runtime so it can be tested exhaustively and cheaply.
-
Method Summary
Modifier and TypeMethodDescriptionstatic PathrequireConfinedRegularFile(Path workspaceRoot, String relativePath) Resolves a workspace-relative path and proves it is a regular file inside the workspace.
-
Method Details
-
requireConfinedRegularFile
public static Path requireConfinedRegularFile(Path workspaceRoot, String relativePath) throws SpliceException Resolves a workspace-relative path and proves it is a regular file inside the workspace.- Parameters:
workspaceRoot- the build workspace; must existrelativePath- a workspace-relative path as produced by glob expansion- Returns:
- the resolved real path, safe to read and replace
- Throws:
SpliceException-ErrorCode.WORKSPACE_ESCAPEif the path is absolute, traverses out of the workspace, or resolves outside it through a link;ErrorCode.FILE_NOT_FOUNDif nothing is there
-