phacility/phabricator · error · Exception
You have an old version of Mercurial (%s) which has a severe
Error message
You have an old version of Mercurial (%s) which has a severe command injection security vulnerability. The remote URI for this repository (%s) is potentially unsafe. Upgrade Mercurial to at least 3.2.4 to clone it.
What it means
Thrown before cloning a Mercurial repository when PhutilBinaryAnalyzer reports the installed hg is a version with a known command-injection vulnerability (below 3.2.4) and the remote URI contains characters that csprintf with '%R' would escape, meaning a vulnerable shell invocation could interpret them. Phabricator refuses the clone rather than risk injection; the repository monogram (e.g. R123) is included so the admin can find it.
Source
Thrown at src/applications/repository/engine/PhabricatorRepositoryPullEngine.php:678
} else {
$remote = $repository->getRemoteURIEnvelope();
// NOTE: Mercurial prior to 3.2.4 has an severe command injection
// vulnerability. See: <http://bit.ly/19B58E9>
// On vulnerable versions of Mercurial, we refuse to clone remotes which
// contain characters which may be interpreted by the shell.
$hg_binary = PhutilBinaryAnalyzer::getForBinary('hg');
$is_vulnerable = $hg_binary->isMercurialVulnerableToInjection();
if ($is_vulnerable) {
$cleartext = $remote->openEnvelope();
// The use of "%R" here is an attempt to limit collateral damage
// for normal URIs because it isn't clear how long this vulnerability
// has been around for.
$escaped = csprintf('%R', $cleartext);
if ((string)$escaped !== (string)$cleartext) {
throw new Exception(
pht(
'You have an old version of Mercurial (%s) which has a severe '.
'command injection security vulnerability. The remote URI for '.
'this repository (%s) is potentially unsafe. Upgrade Mercurial '.
'to at least 3.2.4 to clone it.',
$hg_binary->getBinaryVersion(),
$repository->getMonogram()));
}
}
try {
$repository->execxRemoteCommand(
'clone --noupdate -- %P %s',
$remote,
$path);
} catch (Exception $ex) {
$message = $ex->getMessage();
$message = $this->censorMercurialErrorMessage($message);View on GitHub (pinned to 5720a38cfe)
Solutions
- Upgrade Mercurial to 3.2.4 or newer on the Phabricator host; confirm with 'hg version', which removes the check entirely
- If upgrading is impossible, change the repository remote URI to contain only characters that need no shell escaping
- Re-run the clone or pull task after the upgrade
Example fix
# before hg version # 2.6.2 (vulnerable) -> clone refused # after sudo apt-get install mercurial # or build from source hg version # 4.x -> clone proceeds
Defensive patterns
Strategy: validation
Validate before calling
// Before adding a Mercurial repository, verify the binary is patched:
$hg = PhutilBinaryAnalyzer::getForBinary('hg');
if ($hg->isMercurialVulnerableToInjection()) {
// refuse to configure the repository until hg >= 3.2.4
} Prevention
- Pin Mercurial 3.2.4 or newer in host provisioning from day one
- Keep repository remote URIs free of shell metacharacters where possible
- Periodically audit VCS binary versions on the Phabricator host
When it happens
Trigger: The hg binary on the Phabricator host is older than 3.2.4 AND the repository remote URI contains shell metacharacters such as spaces, quotes, ampersands, or semicolons; first clone or pull of such a Mercurial repository triggers the guard before execxRemoteCommand runs.
Common situations: Long-lived servers running stock distro Mercurial (e.g. CentOS 7 ships hg 2.x); Mercurial remotes with passwords or unusual characters embedded in the URI; minimal installs where the vendor hg package was never upgraded.
Related errors
- Mercurial command appears to contain unsafe injected "--conf
- 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
- Unknown Mercurial command "%s"!
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/0d06aafcd1328fc9.
Report an issue: GitHub.