@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+37 -5
+37 -5
src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
··· 395 395 } 396 396 } 397 397 398 - $repository->execxRemoteCommand( 399 - 'clone --noupdate -- %P %s', 400 - $remote, 401 - $path); 398 + try { 399 + $repository->execxRemoteCommand( 400 + 'clone --noupdate -- %P %s', 401 + $remote, 402 + $path); 403 + } catch (Exception $ex) { 404 + $message = $ex->getMessage(); 405 + $message = $this->censorMercurialErrorMessage($message); 406 + throw new Exception($message); 407 + } 402 408 } 403 409 } 404 410 ··· 438 444 if ($err == 1 && preg_match('/no changes found/', $stdout)) { 439 445 return; 440 446 } else { 441 - throw $ex; 447 + $message = $ex->getMessage(); 448 + $message = $this->censorMercurialErrorMessage($message); 449 + throw new Exception($message); 442 450 } 443 451 } 452 + } 453 + 454 + 455 + /** 456 + * Censor response bodies from Mercurial error messages. 457 + * 458 + * When Mercurial attempts to clone an HTTP repository but does not 459 + * receive a response it expects, it emits the response body in the 460 + * command output. 461 + * 462 + * This represents a potential SSRF issue, because an attacker with 463 + * permission to create repositories can create one which points at the 464 + * remote URI for some local service, then read the response from the 465 + * error message. To prevent this, censor response bodies out of error 466 + * messages. 467 + * 468 + * @param string Uncensored Mercurial command output. 469 + * @return string Censored Mercurial command output. 470 + */ 471 + private function censorMercurialErrorMessage($message) { 472 + return preg_replace( 473 + '/^---%<---.*/sm', 474 + pht('<Response body omitted from Mercurial error message.>')."\n", 475 + $message); 444 476 } 445 477 446 478