phacility/phabricator · critical · DiffusionMercurialFlagInjectionException
Mercurial command appears to contain unsafe injected "--conf
Error message
Mercurial command appears to contain unsafe injected "--config" or "--debugger": %s
What it means
Phabricator's Mercurial command engine rebuilds the final hg command line from its pattern plus argv (which embeds user-controlled values such as the repository remote URI), re-lexes that finished string with shell rules, and rejects the whole command if any single argument starts with --config or --debugger (case-insensitive). Those flags can make Mercurial execute attacker-controlled hooks or configuration (security task T13012), so the engine aborts by throwing DiffusionMercurialFlagInjectionException before hg ever runs.
Source
Thrown at src/applications/diffusion/protocol/DiffusionMercurialCommandEngine.php:27
}
protected function newFormattedCommand($pattern, array $argv) {
$args = array();
// Crudely blacklist commands which look like they may contain command
// injection via "--config" or "--debugger". See T13012. To do this, we
// print the whole command, parse it using shell rules, then examine each
// argument to see if it looks like "--config" or "--debugger".
$test_command = call_user_func_array(
'csprintf',
array_merge(array($pattern), $argv));
$test_args = id(new PhutilShellLexer())
->splitArguments($test_command);
foreach ($test_args as $test_arg) {
if (preg_match('/^--(config|debugger)/i', $test_arg)) {
throw new DiffusionMercurialFlagInjectionException(
pht(
'Mercurial command appears to contain unsafe injected "--config" '.
'or "--debugger": %s',
$test_command));
}
}
// NOTE: Here, and in Git and Subversion, we override the SSH command even
// if the repository does not use an SSH remote, since our SSH wrapper
// defuses an attack against older versions of Mercurial, Git and
// Subversion (see T12961) and it's possible to execute this attack
// in indirect ways, like by using an SSH subrepo inside an HTTP repo.
$pattern = "hg --config ui.ssh=%s {$pattern}";
$args[] = $this->getSSHWrapper();
return array($pattern, array_merge($args, $argv));
}View on GitHub (pinned to 5720a38cfe)
Solutions
- Open the repository in Diffusion, go to Manage, then URIs, and remove any '--config' or '--debugger' text from the remote URI, then retry the operation
- If you genuinely need custom hg configuration, place it in the server-side repository hgrc (or Phabricator environment config) instead of the URI
- If nobody intentionally added the offending flag, audit the URI edit history and treat this as an attempted command-injection attack
- Never bypass or patch out this check; upgrade Phabricator so real fixes apply
Example fix
// before (Remote URI saved in Diffusion): --config=hooks.prechangegroup=touch%%20/tmp/pwned // after: https://hg.example.com/repo/ // (plain URI only; put hooks in the repository hgrc on disk)
Defensive patterns
Strategy: validation
Validate before calling
// before saving or acting on a Mercurial URI, reject flag-like values
if (preg_match('/--(config|debugger)/i', (string)$uri)) {
throw new Exception('Refusing Mercurial URI containing --config/--debugger');
} Type guard
function isSafeMercurialArgument($arg) {
return is_string($arg) && !preg_match('/^--(config|debugger)/i', $arg);
} Try / catch
try {
$engine->execute();
} catch (DiffusionMercurialFlagInjectionException $ex) {
// Security event: log the rejected command and the acting user; never retry with the same arguments.
phlog($ex);
} Prevention
- Require edit permission on repository URIs so only trusted users can set them
- Never build hg command lines by string concatenation: pass values as separate argv entries and pre-screen each for leading dashes
- Treat any occurrence of this exception as a probe for T13012 and review URI audit logs
When it happens
Trigger: Any Mercurial operation (pull, push, clone, discovery) whose constructed command line contains an argument beginning with --config or --debugger. The usual carrier is a repository Remote URI such as '--config=...' or an ssh:// URI path containing '--debugger', because the URI is interpolated into commands like 'hg pull <uri>'.
Common situations: A malicious actor attempting the T13012 clone-URI attack; a user pasting a raw hg command line (including its --config flags) into the Diffusion Remote URI field; automation that appends hg flags to stored URIs.
Related errors
- You have an old version of Mercurial (%s) which has a severe
- 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/4c77907e9f9ac65f.
Report an issue: GitHub.