phacility/phabricator · error · Exception
Invalid path URI.
Error message
Invalid path URI.
What it means
When DiffusionRequest parses a request URI, it splits the extracted path on '/' and rejects any segment equal to '..' with 'Invalid path URI.'. The guard exists because the path is later passed to VCS commands and filesystem operations, so '..' segments would allow escaping the repository root (directory traversal).
Source
Thrown at src/applications/diffusion/request/DiffusionRequest.php:527
$result['commit'] = $matches[1];
$blob = substr($blob, 0, -(strlen($matches[1]) + 1));
}
// We've consumed the commit if it exists, so unescape ";" in the rest
// of the string.
$blob = str_replace(';;', ';', $blob);
if (strlen($blob)) {
$result['path'] = $blob;
}
if ($result['path'] !== null) {
$parts = explode('/', $result['path']);
foreach ($parts as $part) {
// Prevent any hyjinx since we're ultimately shipping this to the
// filesystem under a lot of workflows.
if ($part == '..') {
throw new Exception(pht('Invalid path URI.'));
}
}
}
return $result;
}
/**
* Check that the working copy of the repository is present and readable.
*
* @param string Path to the working copy.
*/
protected function validateWorkingCopy($path) {
if (!is_readable(dirname($path))) {
$this->raisePermissionException();
}
if (!Filesystem::pathExists($path)) {View on GitHub (pinned to 5720a38cfe)
Solutions
- Normalize the path client-side (resolve and drop '..' segments) before issuing the request
- Generate Diffusion links with the framework URI helpers instead of string concatenation
- Treat occurrences in access logs as probing rather than a bug — the guard is doing its job
Example fix
// before
$uri = '/diffusion/X/browse/'.$path_from_user; // may contain ..
// after
$parts = explode('/', $path_from_user);
$parts = array_values(array_filter($parts, function ($p) { return $p !== '..'; }));
$uri = '/diffusion/X/browse/'.implode('/', $parts); Defensive patterns
Strategy: validation
Validate before calling
// Reject traversal segments before constructing the request
$parts = explode('/', $path);
foreach ($parts as $part) {
if ($part === '..') {
return new Aphront400Response(); // or reject in the client
}
} Type guard
function isValidDiffusionPath($path) {
foreach (explode('/', $path) as $part) {
if ($part === '..') {
return false;
}
}
return true;
} Try / catch
try {
$request = DiffusionRequest::newFromAphrontRequest($request);
} catch (Exception $ex) {
if ($ex->getMessage() === pht('Invalid path URI.')) {
return new Aphront400Response();
}
throw $ex;
} Prevention
- Always normalize ('collapse') dot segments in user-supplied paths before requesting
- Build Diffusion URLs with framework helpers, never by concatenation
- Treat this exception in logs as attack traffic, not an application bug
When it happens
Trigger: Any Diffusion request whose decoded path contains a '..' segment, e.g. /diffusion/X/browse/trunk/..%2F..%2Fsecret — usually from hand-built links, crawlers, security scanners, or clients that fail to normalize paths.
Common situations: Automated vulnerability scanners probing the install; copy-pasted URLs with manual path edits; double-encoded %252E%252E payloads.
Related errors
- String "%s" is invalid in path specification "%s".
- When creating a new Almanac service via the Conduit API, you
- Provide a public key, not a private key!
- Invalid response token for this challenge: token digest does
- Request includes restricted parameter "%s", but this control
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/dbca918472a68911.
Report an issue: GitHub.