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

  1. Normalize the path client-side (resolve and drop '..' segments) before issuing the request
  2. Generate Diffusion links with the framework URI helpers instead of string concatenation
  3. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/dbca918472a68911. Report an issue: GitHub.