1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-19 11:11:10 +01:00

Censor response bodies from Mercurial error messages

Summary:
Ref T6755. In Git and Subversion, running `git clone http://google.com/` or `svn checkout http://google.com/` does not echo the response body.

In Mercurial, it does. Censor it from the output of `hg pull` and `hg clone`. This prevents an attacker from:

  - Creating a Mercurial remote repository with URI `http://10.0.0.1/secrets/`; and
  - reading the secrets out of the error message after the clone fails.

Test Plan: Set a Mercurial remote URI to a non-Mercurial repository, ran `repository update`, saw censored error message.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6755

Differential Revision: https://secure.phabricator.com/D12170
This commit is contained in:
epriestley 2015-03-26 11:13:17 -07:00
parent 40fb0f98df
commit a4bfed8415

View file

@ -395,10 +395,16 @@ final class PhabricatorRepositoryPullEngine
} }
} }
$repository->execxRemoteCommand( try {
'clone --noupdate -- %P %s', $repository->execxRemoteCommand(
$remote, 'clone --noupdate -- %P %s',
$path); $remote,
$path);
} catch (Exception $ex) {
$message = $ex->getMessage();
$message = $this->censorMercurialErrorMessage($message);
throw new Exception($message);
}
} }
} }
@ -438,12 +444,38 @@ final class PhabricatorRepositoryPullEngine
if ($err == 1 && preg_match('/no changes found/', $stdout)) { if ($err == 1 && preg_match('/no changes found/', $stdout)) {
return; return;
} else { } else {
throw $ex; $message = $ex->getMessage();
$message = $this->censorMercurialErrorMessage($message);
throw new Exception($message);
} }
} }
} }
/**
* Censor response bodies from Mercurial error messages.
*
* When Mercurial attempts to clone an HTTP repository but does not
* receive a response it expects, it emits the response body in the
* command output.
*
* This represents a potential SSRF issue, because an attacker with
* permission to create repositories can create one which points at the
* remote URI for some local service, then read the response from the
* error message. To prevent this, censor response bodies out of error
* messages.
*
* @param string Uncensored Mercurial command output.
* @return string Censored Mercurial command output.
*/
private function censorMercurialErrorMessage($message) {
return preg_replace(
'/^---%<---.*/sm',
pht('<Response body omitted from Mercurial error message.>')."\n",
$message);
}
/** /**
* @task hg * @task hg
*/ */