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

  1. 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
  2. If you genuinely need custom hg configuration, place it in the server-side repository hgrc (or Phabricator environment config) instead of the URI
  3. If nobody intentionally added the offending flag, audit the URI edit history and treat this as an attempted command-injection attack
  4. 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

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


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