Compare commits

...
This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.

21 Commits
5.4 ... 2.8

Author SHA1 Message Date
Fabien Potencier 88f3ef62d6
Merge pull request #34349 from fabpot/release-2.8.52
released v2.8.52
2019-11-13 09:36:42 +01:00
Fabien Potencier 44dbe046a5 updated VERSION for 2.8.52 2019-11-13 09:36:16 +01:00
Fabien Potencier be612fe316 updated CHANGELOG for 2.8.52 2019-11-13 09:36:05 +01:00
Fabien Potencier 2d6bf2e689 Fix CHANGELOG 2019-11-13 09:35:55 +01:00
Nicolas Grekas af70ccb73b security #cve-2019-18888 [HttpFoundation] fix guessing mime-types of files with leading dash (nicolas-grekas)
This PR was merged into the 2.8 branch.
2019-11-12 13:45:28 +01:00
Nicolas Grekas d41bd42ad5 security #cve-2019-18887 [HttpKernel] Use constant time comparison in UriSigner (stof)
This PR was merged into the 2.8 branch.
2019-11-12 13:42:27 +01:00
Nicolas Grekas 2dfc115f6d [HttpFoundation] fix guessing mime-types of files with leading dash 2019-11-12 13:34:41 +01:00
Christophe Coevoet 9a50fc5722 [HttpKernel] Use constant time comparison in UriSigner 2019-11-11 13:20:20 +01:00
Fabien Potencier 78d86f8516 bumped version 2019-04-17 18:42:28 +02:00
Fabien Potencier d4843fe948 fixed version 2019-04-17 18:42:21 +02:00
Fabien Potencier 2ef4e09343
Merge pull request #31145 from fabpot/release-2.8.50
released v2.8.50
2019-04-17 17:54:07 +02:00
Fabien Potencier 9fc1016a6c updated VERSION for 2.8.50 2019-04-17 17:53:47 +02:00
Fabien Potencier 266b07f813 updated CHANGELOG for 2.8.50 2019-04-17 17:53:36 +02:00
Nicolas Grekas 3876c75f85 security #cve-2019-10910 [DI] Check service IDs are valid (nicolas-grekas)
This PR was merged into the 2.8 branch.

Discussion
----------

[DI] Check service IDs are valid

Based on #87

Commits
-------

7fdfeefdfb [DI] Check service IDs are valid
2019-04-16 13:33:46 +02:00
Nicolas Grekas 41e9ec3e04 security #cve-2019-10909 [FrameworkBundle][Form] Fix XSS issues in the form theme of the PHP templating engine (stof)
This PR was merged into the 2.8 branch.

Discussion
----------

[FrameworkBundle][Form] Fix XSS issues in the form theme of the PHP templating engine

Based on #88

Commits
-------

f7c95b4cd5 Fix XSS issues in the form theme of the PHP templating engine
2019-04-16 12:01:35 +02:00
Nicolas Grekas 63eda69c32 security #cve-2019-10912 [PHPUnit Bridge] Prevent destructors with side-effects from being unserialized (nicolas-grekas)
This PR was merged into the 2.8 branch.

Discussion
----------

[PHPUnit Bridge] Prevent destructors with side-effects from being unserialized

| Q             | A
| ------------- | ---
| Branch?       | 2.8
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Commits
-------

908b64d17e [2.8][PHPUnit Bridge] Prevent destructors with side-effects from being unserialized - CVE-2019-10912
2019-04-16 12:01:26 +02:00
Nicolas Grekas 938b21a72e security #cve-2019-10911 [Security] Add a separator in the remember me cookie hash (pborreli)
This PR was merged into the 2.8 branch.

Discussion
----------

[Security] Add a separator in the remember me cookie hash

Based on #89

Commits
-------

9044e3b65d [Security] Add a separator in the remember me cookie hash
2019-04-16 12:01:12 +02:00
Nicolas Grekas e88a63114a security #cve-2019-10913 [HttpFoundation] reject invalid method override (nicolas-grekas)
This PR was merged into the 2.8 branch.

Discussion
----------

[HttpFoundation] reject invalid method override

Based on #86

Commits
-------

d7dcedbf1d [HttpFoundation] reject invalid method override
2019-04-16 12:00:53 +02:00
Fabien Potencier f8ac64c075
Merge pull request #29487 from fabpot/release-2.8.49
released v2.8.49
2018-12-06 14:45:26 +00:00
Fabien Potencier adeee139cf bumped version 2018-12-06 14:45:07 +00:00
Fabien Potencier 8552386f0b updated CHANGELOG for 2.8.49 2018-12-06 14:44:32 +00:00
17 changed files with 145 additions and 38 deletions

View File

@ -7,6 +7,28 @@ in 2.8 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.8.0...v2.8.1
* 2.8.52 (2019-11-13)
* security #cve-2019-18888 [HttpFoundation] fix guessing mime-types of files with leading dash (nicolas-grekas)
* security #cve-2019-18887 [HttpKernel] Use constant time comparison in UriSigner (stof)
* 2.8.51 (2019-04-17)
* no changes
* 2.8.50 (2019-04-17)
* security #cve-2019-10910 [DI] Check service IDs are valid (nicolas-grekas)
* security #cve-2019-10909 [FrameworkBundle][Form] Fix XSS issues in the form theme of the PHP templating engine (stof)
* security #cve-2019-10912 [PHPUnit Bridge] Prevent destructors with side-effects from being unserialized (nicolas-grekas)
* security #cve-2019-10911 [Security] Add a separator in the remember me cookie hash (pborreli)
* security #cve-2019-10913 [HttpFoundation] reject invalid method override (nicolas-grekas)
* 2.8.49 (2018-12-06)
* security #cve-2018-19790 [Security\Http] detect bad redirect targets using backslashes (xabbuh)
* security #cve-2018-19789 [Form] Filter file uploads out of regular form types (nicolas-grekas)
* 2.8.48 (2018-11-26)
* bug #28917 [DoctrineBridge] catch errors while converting to db values in data collector (alekitto)

View File

@ -61,6 +61,16 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
}
}
public function __sleep()
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
public function __wakeup()
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
public function __destruct()
{
if (0 < $this->state) {

View File

@ -53,15 +53,17 @@ class ProxyDumper implements DumperInterface
public function getProxyFactoryCode(Definition $definition, $id)
{
$instantiation = 'return';
$scope = '';
if ($definition->isShared()) {
$instantiation .= " \$this->services['$id'] =";
$instantiation .= ' $this->services[%s] =';
if (\defined('Symfony\Component\DependencyInjection\ContainerInterface::SCOPE_CONTAINER') && ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
$instantiation .= " \$this->scopedServices['$scope']['$id'] =";
$instantiation .= ' $this->scopedServices[%s][%1$s] =';
}
}
$instantiation = sprintf($instantiation, var_export($id, true), var_export($scope, true));
$methodName = 'get'.Container::camelize($id).'Service';
$proxyClass = $this->getProxyClassName($definition);

View File

@ -11,7 +11,7 @@
<?php if (count($preferred_choices) > 0): ?>
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
<?php if (count($choices) > 0 && null !== $separator): ?>
<option disabled="disabled"><?php echo $separator ?></option>
<option disabled="disabled"><?php echo $view->escape($separator) ?></option>
<?php endif ?>
<?php endif ?>
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $choices)) ?>

View File

@ -1,7 +1,7 @@
<?php if (count($errors) > 0): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo $error->getMessage() ?></li>
<li><?php echo $view->escape($error->getMessage()) ?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>

View File

@ -1,6 +1,6 @@
<?php $method = strtoupper($method) ?>
<?php $form_method = $method === 'GET' || $method === 'POST' ? $method : 'POST' ?>
<form name="<?php echo $name ?>" method="<?php echo strtolower($form_method) ?>"<?php if ($action !== ''): ?> action="<?php echo $action ?>"<?php endif ?><?php foreach ($attr as $k => $v) { printf(' %s="%s"', $view->escape($k), $view->escape($v)); } ?><?php if ($multipart): ?> enctype="multipart/form-data"<?php endif ?>>
<form name="<?php echo $name ?>" method="<?php echo strtolower($form_method) ?>"<?php if ($action !== ''): ?> action="<?php echo $view->escape($action) ?>"<?php endif ?><?php foreach ($attr as $k => $v) { printf(' %s="%s"', $view->escape($k), $view->escape($v)); } ?><?php if ($multipart): ?> enctype="multipart/form-data"<?php endif ?>>
<?php if ($form_method !== $method): ?>
<input type="hidden" name="_method" value="<?php echo $method ?>" />
<input type="hidden" name="_method" value="<?php echo $view->escape($method) ?>" />
<?php endif ?>

View File

@ -641,6 +641,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
{
$alias = strtolower($alias);
if ('' === $alias || '\\' === substr($alias, -1) || \strlen($alias) !== strcspn($alias, "\0\r\n'")) {
throw new InvalidArgumentException(sprintf('Invalid alias id: "%s"', $alias));
}
if (\is_string($id)) {
$id = new Alias($id);
} elseif (!$id instanceof Alias) {
@ -775,6 +779,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$id = strtolower($id);
if ('' === $id || '\\' === substr($id, -1) || \strlen($id) !== strcspn($id, "\0\r\n'")) {
throw new InvalidArgumentException(sprintf('Invalid service id: "%s"', $id));
}
unset($this->aliasDefinitions[$id]);
return $this->definitions[$id] = $definition;

View File

@ -379,9 +379,9 @@ class PhpDumper extends Dumper
$instantiation = '';
if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
$instantiation = sprintf('$this->services[%s] = %s', var_export($id, true), $simple ? '' : '$instance');
} elseif (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
$instantiation = sprintf('$this->services[%s] = $this->scopedServices[%s][%1$s] = %s', var_export($id, true), var_export($scope, true), $simple ? '' : '$instance');
} elseif (!$simple) {
$instantiation = '$instance';
}
@ -609,6 +609,9 @@ class PhpDumper extends Dumper
* Gets the $public '$id'$shared$autowired service.
*
* $return
EOF;
$code = str_replace('*/', ' ', $code).<<<EOF
*/
{$visibility} function get{$this->camelize($id)}Service($lazyInitialization)
{
@ -620,7 +623,7 @@ EOF;
if (!\in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
$code .= <<<EOF
if (!isset(\$this->scopedServices['$scope'])) {
throw new InactiveScopeException('$id', '$scope');
throw new InactiveScopeException({$this->export($id)}, '$scope');
}
@ -628,7 +631,7 @@ EOF;
}
if ($definition->isSynthetic()) {
$code .= sprintf(" throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n }\n", $id);
$code .= sprintf(" throw new RuntimeException(%s);\n }\n", var_export("You have requested a synthetic service (\"$id\"). The DIC does not know how to construct this service.", true));
} else {
if ($definition->isDeprecated()) {
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", var_export($definition->getDeprecationMessage($id), true));
@ -706,10 +709,11 @@ EOF;
$arguments[] = $this->dumpValue($value);
}
$call = $this->wrapServiceConditionals($call[1], sprintf("\$this->get('%s')->%s(%s);", $definitionId, $call[0], implode(', ', $arguments)));
$definitionId = var_export($definitionId, true);
$call = $this->wrapServiceConditionals($call[1], sprintf('$this->get(%s)->%s(%s);', $definitionId, $call[0], implode(', ', $arguments)));
$code .= <<<EOF
if (\$this->initialized('$definitionId')) {
if (\$this->initialized($definitionId)) {
$call
}
@ -1142,7 +1146,7 @@ EOF;
$conditions = array();
foreach ($services as $service) {
$conditions[] = sprintf("\$this->has('%s')", $service);
$conditions[] = sprintf('$this->has(%s)', var_export($service, true));
}
// re-indent the wrapped code
@ -1419,11 +1423,13 @@ EOF;
*/
public function dumpParameter($name)
{
$name = (string) $name;
if ($this->container->isFrozen() && $this->container->hasParameter($name)) {
return $this->dumpValue($this->container->getParameter($name), false);
}
return sprintf("\$this->getParameter('%s')", strtolower($name));
return sprintf('$this->getParameter(%s)', var_export($name, true));
}
/**
@ -1458,10 +1464,10 @@ EOF;
}
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
return sprintf('$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)', $id);
return sprintf('$this->get(%s, ContainerInterface::NULL_ON_INVALID_REFERENCE)', var_export($id, true));
}
return sprintf('$this->get(\'%s\')', $id);
return sprintf('$this->get(%s)', var_export($id, true));
}
/**

View File

@ -131,6 +131,38 @@ class ContainerBuilderTest extends TestCase
$this->assertNotSame($builder->get('bar'), $builder->get('bar'));
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @dataProvider provideBadId
*/
public function testBadAliasId($id)
{
$builder = new ContainerBuilder();
$builder->setAlias($id, 'foo');
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @dataProvider provideBadId
*/
public function testBadDefinitionId($id)
{
$builder = new ContainerBuilder();
$builder->setDefinition($id, new Definition('Foo'));
}
public function provideBadId()
{
return [
[''],
["\0"],
["\r"],
["\n"],
["'"],
['ab\\'],
];
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage You have requested a synthetic service ("foo"). The DIC does not know how to construct this service.

View File

@ -31,7 +31,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
*
* @param string $cmd The command to run to get the mime type of a file
*/
public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
public function __construct($cmd = 'file -b --mime -- %s 2>/dev/null')
{
$this->cmd = $cmd;
}
@ -80,7 +80,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
ob_start();
// need to use --mime instead of -i. see #6641
passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
passthru(sprintf($this->cmd, escapeshellarg((0 === strpos($path, '-') ? './' : '').$path)), $return);
if ($return > 0) {
ob_end_clean();

View File

@ -1269,22 +1269,37 @@ class Request
*/
public function getMethod()
{
if (null === $this->method) {
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
if ('POST' === $this->method) {
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
$this->method = strtoupper($method);
} elseif (self::$httpMethodParameterOverride) {
$method = $this->request->get('_method', $this->query->get('_method', 'POST'));
if (\is_string($method)) {
$this->method = strtoupper($method);
}
}
}
if (null !== $this->method) {
return $this->method;
}
return $this->method;
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
if ('POST' !== $this->method) {
return $this->method;
}
$method = $this->headers->get('X-HTTP-METHOD-OVERRIDE');
if (!$method && self::$httpMethodParameterOverride) {
$method = $this->request->get('_method', $this->query->get('_method', 'POST'));
}
if (!\is_string($method)) {
return $this->method;
}
$method = strtoupper($method);
if (\in_array($method, array('GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'), true)) {
return $this->method = $method;
}
if (!preg_match('/^[A-Z]++$/D', $method)) {
throw new \UnexpectedValueException(sprintf('Invalid method override "%s".', $method));
}
return $this->method = $method;
}
/**

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 B

View File

@ -20,7 +20,18 @@ use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
*/
class MimeTypeTest extends TestCase
{
protected $path;
public function testGuessWithLeadingDash()
{
$cwd = getcwd();
chdir(__DIR__.'/../Fixtures');
try {
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess('-test'));
chdir($cwd);
} catch(\Exception $e) {
chdir($cwd);
throw $e;
}
}
public function testGuessImageWithoutExtension()
{

View File

@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
const VERSION = '2.8.48';
const VERSION_ID = 20848;
const VERSION = '2.8.52';
const VERSION_ID = 20852;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 8;
const RELEASE_VERSION = 48;
const RELEASE_VERSION = 52;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '11/2018';

View File

@ -75,7 +75,7 @@ class UriSigner
$hash = urlencode($params['_hash']);
unset($params['_hash']);
return $this->computeHash($this->buildUrl($url, $params)) === $hash;
return hash_equals($this->computeHash($this->buildUrl($url, $params)), $hash);
}
private function computeHash($uri)

View File

@ -21,6 +21,7 @@
"symfony/http-foundation": "~2.7.36|~2.8.29|~3.1.6",
"symfony/debug": "^2.6.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-php56": "~1.8",
"psr/log": "~1.0"
},
"require-dev": {

View File

@ -120,6 +120,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function generateCookieHash($class, $username, $expires, $password)
{
return hash_hmac('sha256', $class.$username.$expires.$password, $this->getSecret());
return hash_hmac('sha256', $class.self::COOKIE_DELIMITER.$username.self::COOKIE_DELIMITER.$expires.self::COOKIE_DELIMITER.$password, $this->getSecret());
}
}