1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-15 10:00:55 +01:00

(stable) Promote 2017 Week 45

This commit is contained in:
epriestley 2017-11-10 08:43:37 -08:00
commit d2d5a1f283
9 changed files with 97 additions and 13 deletions

View file

@ -768,6 +768,7 @@ phutil_register_library_map(array(
'DiffusionMercurialBlameQuery' => 'applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php', 'DiffusionMercurialBlameQuery' => 'applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php',
'DiffusionMercurialCommandEngine' => 'applications/diffusion/protocol/DiffusionMercurialCommandEngine.php', 'DiffusionMercurialCommandEngine' => 'applications/diffusion/protocol/DiffusionMercurialCommandEngine.php',
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php', 'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
'DiffusionMercurialFlagInjectionException' => 'applications/diffusion/exception/DiffusionMercurialFlagInjectionException.php',
'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php', 'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php', 'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
'DiffusionMercurialResponse' => 'applications/diffusion/response/DiffusionMercurialResponse.php', 'DiffusionMercurialResponse' => 'applications/diffusion/response/DiffusionMercurialResponse.php',
@ -5814,6 +5815,7 @@ phutil_register_library_map(array(
'DiffusionMercurialBlameQuery' => 'DiffusionBlameQuery', 'DiffusionMercurialBlameQuery' => 'DiffusionBlameQuery',
'DiffusionMercurialCommandEngine' => 'DiffusionCommandEngine', 'DiffusionMercurialCommandEngine' => 'DiffusionCommandEngine',
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialFlagInjectionException' => 'Exception',
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery', 'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest', 'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMercurialResponse' => 'AphrontResponse', 'DiffusionMercurialResponse' => 'AphrontResponse',

View file

@ -47,7 +47,7 @@ final class DiffusionExistsQueryConduitAPIMethod
$commit = $request->getValue('commit'); $commit = $request->getValue('commit');
list($err, $stdout) = $repository->execLocalCommand( list($err, $stdout) = $repository->execLocalCommand(
'id --rev %s', 'id --rev %s',
$commit); hgsprintf('%s', $commit));
return !$err; return !$err;
} }

View file

@ -123,21 +123,23 @@ final class DiffusionHistoryQueryConduitAPIMethod
// branches). // branches).
if (strlen($path)) { if (strlen($path)) {
$path_arg = csprintf('-- %s', $path); $path_arg = csprintf('%s', $path);
$branch_arg = ''; $revset_arg = hgsprintf(
'reverse(ancestors(%s))',
$commit_hash);
} else { } else {
$path_arg = ''; $path_arg = '';
// NOTE: --branch used to be called --only-branch; use -b for $revset_arg = hgsprintf(
// compatibility. 'branch(%s) and reverse(ancestors(%s))',
$branch_arg = csprintf('-b %s', $drequest->getBranch()); $drequest->getBranch(),
$commit_hash);
} }
list($stdout) = $repository->execxLocalCommand( list($stdout) = $repository->execxLocalCommand(
'log --debug --template %s --limit %d %C --rev %s %C', 'log --debug --template %s --limit %d --rev %s -- %C',
'{node};{parents}\\n', '{node};{parents}\\n',
($offset + $limit), // No '--skip' in Mercurial. ($offset + $limit), // No '--skip' in Mercurial.
$branch_arg, $revset_arg,
hgsprintf('reverse(ancestors(%s))', $commit_hash),
$path_arg); $path_arg);
$stdout = DiffusionMercurialCommandEngine::filterMercurialDebugOutput( $stdout = DiffusionMercurialCommandEngine::filterMercurialDebugOutput(

View file

@ -77,7 +77,7 @@ final class DiffusionMergedCommitsQueryConduitAPIMethod
list($parents) = $repository->execxLocalCommand( list($parents) = $repository->execxLocalCommand(
'parents --template=%s --rev %s', 'parents --template=%s --rev %s',
'{node}\\n', '{node}\\n',
$commit); hgsprintf('%s', $commit));
$parents = explode("\n", trim($parents)); $parents = explode("\n", trim($parents));
if (count($parents) < 2) { if (count($parents) < 2) {

View file

@ -97,7 +97,7 @@ final class DiffusionSearchQueryConduitAPIMethod
$results = array(); $results = array();
$future = $repository->getLocalCommandFuture( $future = $repository->getLocalCommandFuture(
'grep --rev %s --print0 --line-number %s %s', 'grep --rev %s --print0 --line-number -- %s %s',
hgsprintf('ancestors(%s)', $drequest->getStableCommit()), hgsprintf('ancestors(%s)', $drequest->getStableCommit()),
$grep, $grep,
$path); $path);

View file

@ -0,0 +1,3 @@
<?php
final class DiffusionMercurialFlagInjectionException extends Exception {}

View file

@ -11,6 +11,27 @@ final class DiffusionMercurialCommandEngine
protected function newFormattedCommand($pattern, array $argv) { protected function newFormattedCommand($pattern, array $argv) {
$args = array(); $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 // 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 // if the repository does not use an SSH remote, since our SSH wrapper
// defuses an attack against older versions of Mercurial, Git and // defuses an attack against older versions of Mercurial, Git and

View file

@ -123,6 +123,62 @@ final class DiffusionCommandEngineTestCase extends PhabricatorTestCase {
'argv' => 'xyz', 'argv' => 'xyz',
'protocol' => 'https', 'protocol' => 'https',
)); ));
// Test that filtering defenses for "--config" and "--debugger" flag
// injections in Mercurial are functional. See T13012.
$caught = null;
try {
$this->assertCommandEngineFormat(
'',
array(),
array(
'vcs' => $type_hg,
'argv' => '--debugger',
));
} catch (DiffusionMercurialFlagInjectionException $ex) {
$caught = $ex;
}
$this->assertTrue(
($caught instanceof DiffusionMercurialFlagInjectionException),
pht('Expected "--debugger" injection in Mercurial to throw.'));
$caught = null;
try {
$this->assertCommandEngineFormat(
'',
array(),
array(
'vcs' => $type_hg,
'argv' => '--config=x',
));
} catch (DiffusionMercurialFlagInjectionException $ex) {
$caught = $ex;
}
$this->assertTrue(
($caught instanceof DiffusionMercurialFlagInjectionException),
pht('Expected "--config" injection in Mercurial to throw.'));
$caught = null;
try {
$this->assertCommandEngineFormat(
'',
array(),
array(
'vcs' => $type_hg,
'argv' => (string)csprintf('%s', '--config=x'),
));
} catch (DiffusionMercurialFlagInjectionException $ex) {
$caught = $ex;
}
$this->assertTrue(
($caught instanceof DiffusionMercurialFlagInjectionException),
pht('Expected quoted "--config" injection in Mercurial to throw.'));
} }
private function assertCommandEngineFormat( private function assertCommandEngineFormat(

View file

@ -16,14 +16,14 @@ final class DiffusionMercurialRawDiffQuery extends DiffusionRawDiffQuery {
// If `$commit` has no parents (usually because it's the first commit // If `$commit` has no parents (usually because it's the first commit
// in the repository), we want to diff against `null`. This revset will // in the repository), we want to diff against `null`. This revset will
// do that for us automatically. // do that for us automatically.
$against = '('.$commit.'^ or null)'; $against = hgsprintf('(%s^ or null)', $commit);
} }
$future = $repository->getLocalCommandFuture( $future = $repository->getLocalCommandFuture(
'diff -U %d --git --rev %s --rev %s -- %s', 'diff -U %d --git --rev %s --rev %s -- %s',
$this->getLinesOfContext(), $this->getLinesOfContext(),
$against, $against,
$commit, hgsprintf('%s', $commit),
$path); $path);
return $future; return $future;