Your message dated Thu, 02 Apr 2015 09:50:33 +0200 with message-id <551CF4C9.10803@thykier.net> and subject line Re: Bug#781709: unblock: symfony/2.3.21+dfsg-4 has caused the Debian Bug report #781709, regarding unblock: symfony/2.3.21+dfsg-4 to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) -- 781709: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=781709 Debian Bug Tracking System Contact owner@bugs.debian.org with problems
--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: unblock: symfony/2.3.21+dfsg-4
- From: David Prévot <taffit@debian.org>
- Date: Wed, 1 Apr 2015 17:41:19 -0400
- Message-id: <[🔎] 20150401214119.GA20648@mikado.tilapin.org>
Package: release.debian.org Severity: normal User: release.debian.org@packages.debian.org Usertags: unblock Please unblock package symfony It cherry-picks to security fixes from upstrem: symfony (2.3.21+dfsg-4) unstable; urgency=medium * Backport security fixes from 2.3.27: - Esi Code Injection [CVE-2015-2308] - Unsafe methods in the Request class [CVE-2015-2309] -- David Prévot <taffit@debian.org> Wed, 01 Apr 2015 16:53:00 -0400 unblock symfony/2.3.21+dfsg-4 Thanks in advance. Regards Daviddiff -Nru symfony-2.3.21+dfsg/debian/changelog symfony-2.3.21+dfsg/debian/changelog --- symfony-2.3.21+dfsg/debian/changelog 2015-01-30 09:22:17.000000000 -0400 +++ symfony-2.3.21+dfsg/debian/changelog 2015-04-01 16:53:36.000000000 -0400 @@ -1,3 +1,11 @@ +symfony (2.3.21+dfsg-4) unstable; urgency=medium + + * Backport security fixes from 2.3.27: + - Esi Code Injection [CVE-2015-2308] + - Unsafe methods in the Request class [CVE-2015-2309] + + -- David Prévot <taffit@debian.org> Wed, 01 Apr 2015 16:53:00 -0400 + symfony (2.3.21+dfsg-3) unstable; urgency=medium [ Daniel Beyer ] diff -Nru symfony-2.3.21+dfsg/debian/patches/0007-isFromTrustedProxy-to-confirm-request-came-from-a-tr.patch symfony-2.3.21+dfsg/debian/patches/0007-isFromTrustedProxy-to-confirm-request-came-from-a-tr.patch --- symfony-2.3.21+dfsg/debian/patches/0007-isFromTrustedProxy-to-confirm-request-came-from-a-tr.patch 1969-12-31 20:00:00.000000000 -0400 +++ symfony-2.3.21+dfsg/debian/patches/0007-isFromTrustedProxy-to-confirm-request-came-from-a-tr.patch 2015-04-01 16:44:25.000000000 -0400 @@ -0,0 +1,140 @@ +From: James Gilliland <jgilliland@apqc.org> +Date: Tue, 17 Feb 2015 11:56:59 -0600 +Subject: isFromTrustedProxy to confirm request came from a trusted proxy. + +Origin: upstream, https://github.com/symfony/symfony/commit/6c73f0ce9302a0091bbfbb96f317e400ce16ef84 +--- + src/Symfony/Component/HttpFoundation/Request.php | 13 +++++--- + .../Component/HttpFoundation/Tests/RequestTest.php | 38 ++++++++++++++-------- + 2 files changed, 34 insertions(+), 17 deletions(-) + +diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php +index 9fd02cc..00fdbc4 100644 +--- a/src/Symfony/Component/HttpFoundation/Request.php ++++ b/src/Symfony/Component/HttpFoundation/Request.php +@@ -763,7 +763,7 @@ class Request + { + $ip = $this->server->get('REMOTE_ADDR'); + +- if (!self::$trustedProxies) { ++ if (!$this->isFromTrustedProxy()) { + return array($ip); + } + +@@ -924,7 +924,7 @@ class Request + */ + public function getPort() + { +- if (self::$trustedProxies) { ++ if ($this->isFromTrustedProxy()) { + if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { + return $port; + } +@@ -1105,7 +1105,7 @@ class Request + */ + public function isSecure() + { +- if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { ++ if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { + return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1')); + } + +@@ -1133,7 +1133,7 @@ class Request + */ + public function getHost() + { +- if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { ++ if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { + $elements = explode(',', $host); + + $host = $elements[count($elements) - 1]; +@@ -1819,4 +1819,9 @@ class Request + + return false; + } ++ ++ private function isFromTrustedProxy() ++ { ++ return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); ++ } + } +diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +index 6059969..e57f702 100644 +--- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php ++++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +@@ -707,35 +707,37 @@ class RequestTest extends \PHPUnit_Framework_TestCase + 'HTTP_X_FORWARDED_PROTO' => 'https', + 'HTTP_X_FORWARDED_PORT' => '8443', + )); +- $port = $request->getPort(); +- +- $this->assertEquals(8443, $port, 'With PROTO and PORT set PORT takes precedence.'); ++ $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.'); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); ++ $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.'); + + $request = Request::create('http://example.com', 'GET', array(), array(), array(), array( + 'HTTP_X_FORWARDED_PROTO' => 'https', + )); +- $port = $request->getPort(); +- +- $this->assertEquals(443, $port, 'With only PROTO set getPort() defaults to 443.'); ++ $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.'); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); ++ $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.'); + + $request = Request::create('http://example.com', 'GET', array(), array(), array(), array( + 'HTTP_X_FORWARDED_PROTO' => 'http', + )); +- $port = $request->getPort(); +- +- $this->assertEquals(80, $port, 'If X_FORWARDED_PROTO is set to HTTP return 80.'); ++ $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.'); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); ++ $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.'); + + $request = Request::create('http://example.com', 'GET', array(), array(), array(), array( + 'HTTP_X_FORWARDED_PROTO' => 'On', + )); +- $port = $request->getPort(); +- $this->assertEquals(443, $port, 'With only PROTO set and value is On, getPort() defaults to 443.'); ++ $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.'); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); ++ $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.'); + + $request = Request::create('http://example.com', 'GET', array(), array(), array(), array( + 'HTTP_X_FORWARDED_PROTO' => '1', + )); +- $port = $request->getPort(); +- $this->assertEquals(443, $port, 'With only PROTO set and value is 1, getPort() defaults to 443.'); ++ $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.'); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); ++ $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.'); + + $request = Request::create('http://example.com', 'GET', array(), array(), array(), array( + 'HTTP_X_FORWARDED_PROTO' => 'something-else', +@@ -1002,6 +1004,8 @@ class RequestTest extends \PHPUnit_Framework_TestCase + $request->headers->set('X_FORWARDED_PROTO', 'https'); + + Request::setTrustedProxies(array('1.1.1.1')); ++ $this->assertFalse($request->isSecure()); ++ $request->server->set('REMOTE_ADDR', '1.1.1.1'); + $this->assertTrue($request->isSecure()); + Request::setTrustedProxies(array()); + +@@ -1437,7 +1441,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase + $this->assertEquals(443, $request->getPort()); + $this->assertTrue($request->isSecure()); + ++ // trusted proxy via setTrustedProxies() ++ Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2')); ++ $this->assertEquals('3.3.3.3', $request->getClientIp()); ++ $this->assertEquals('example.com', $request->getHost()); ++ $this->assertEquals(80, $request->getPort()); ++ $this->assertFalse($request->isSecure()); ++ + // check various X_FORWARDED_PROTO header values ++ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2')); + $request->headers->set('X_FORWARDED_PROTO', 'ssl'); + $this->assertTrue($request->isSecure()); + diff -Nru symfony-2.3.21+dfsg/debian/patches/0008-Safe-escaping-of-fragments-for-eval.patch symfony-2.3.21+dfsg/debian/patches/0008-Safe-escaping-of-fragments-for-eval.patch --- symfony-2.3.21+dfsg/debian/patches/0008-Safe-escaping-of-fragments-for-eval.patch 1969-12-31 20:00:00.000000000 -0400 +++ symfony-2.3.21+dfsg/debian/patches/0008-Safe-escaping-of-fragments-for-eval.patch 2015-04-01 16:44:25.000000000 -0400 @@ -0,0 +1,113 @@ +From: Nicolas Grekas <nicolas.grekas@gmail.com> +Date: Mon, 16 Mar 2015 15:12:02 +0100 +Subject: Safe escaping of fragments for eval() + +https://github.com/symfony/symfony/commit/195c57e1f50765aff33137689b16e126a689056a +--- + src/Symfony/Component/HttpKernel/HttpCache/Esi.php | 62 +++++++++++----------- + .../HttpKernel/Tests/HttpCache/EsiTest.php | 4 +- + 2 files changed, 33 insertions(+), 33 deletions(-) + +diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +index 9dd99d6..ad63267 100644 +--- a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php ++++ b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +@@ -29,6 +29,10 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; + class Esi + { + private $contentTypes; ++ private $phpEscapeMap = array( ++ array('<?', '<%', '<s', '<S'), ++ array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'), ++ ); + + /** + * Constructor. +@@ -158,10 +162,34 @@ class Esi + + // we don't use a proper XML parser here as we can have ESI tags in a plain text response + $content = $response->getContent(); +- $content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content); +- $content = preg_replace_callback('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', array($this, 'handleEsiIncludeTag'), $content); +- $content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content); + $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content); ++ $content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content); ++ ++ $chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, PREG_SPLIT_DELIM_CAPTURE); ++ $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); ++ ++ $i = 1; ++ while (isset($chunks[$i])) { ++ $options = array(); ++ preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER); ++ foreach ($matches as $set) { ++ $options[$set[1]] = $set[2]; ++ } ++ ++ if (!isset($options['src'])) { ++ throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); ++ } ++ ++ $chunks[$i] = sprintf('<?php echo $this->esi->handle($this, %s, %s, %s) ?>'."\n", ++ var_export($options['src'], true), ++ var_export(isset($options['alt']) ? $options['alt'] : '', true), ++ isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false' ++ ); ++ ++$i; ++ $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]); ++ ++$i; ++ } ++ $content = implode('', $chunks); + + $response->setContent($content); + $response->headers->set('X-Body-Eval', 'ESI'); +@@ -214,32 +242,4 @@ class Esi + } + } + } +- +- /** +- * Handles an ESI include tag (called internally). +- * +- * @param array $attributes An array containing the attributes. +- * +- * @return string The response content for the include. +- * +- * @throws \RuntimeException +- */ +- private function handleEsiIncludeTag($attributes) +- { +- $options = array(); +- preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER); +- foreach ($matches as $set) { +- $options[$set[1]] = $set[2]; +- } +- +- if (!isset($options['src'])) { +- throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); +- } +- +- return sprintf('<?php echo $this->esi->handle($this, %s, %s, %s) ?>'."\n", +- var_export($options['src'], true), +- var_export(isset($options['alt']) ? $options['alt'] : '', true), +- isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false' +- ); +- } + } +diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php +index 23e256e..8ab3d47 100644 +--- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php ++++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php +@@ -131,10 +131,10 @@ class EsiTest extends \PHPUnit_Framework_TestCase + $esi = new Esi(); + + $request = Request::create('/'); +- $response = new Response('foo <?php die("foo"); ?><%= "lala" %>'); ++ $response = new Response('<?php <? <% <script language=php>'); + $esi->process($request, $response); + +- $this->assertEquals('foo <?php echo "<?"; ?>php die("foo"); ?><?php echo "<%"; ?>= "lala" %>', $response->getContent()); ++ $this->assertEquals('<?php echo "<?"; ?>php <?php echo "<?"; ?> <?php echo "<%"; ?> <?php echo "<s"; ?>cript language=php>', $response->getContent()); + } + + /** diff -Nru symfony-2.3.21+dfsg/debian/patches/series symfony-2.3.21+dfsg/debian/patches/series --- symfony-2.3.21+dfsg/debian/patches/series 2015-01-30 09:17:03.000000000 -0400 +++ symfony-2.3.21+dfsg/debian/patches/series 2015-04-01 16:44:25.000000000 -0400 @@ -4,3 +4,5 @@ 0004-Add-more-tests-to-group-tty.patch 0005-Process-Make-test-AbstractProcessTest-testStartAfter.patch 0006-Increasing-timeout-in-test-AbstractProcessTest-testS.patch +0007-isFromTrustedProxy-to-confirm-request-came-from-a-tr.patch +0008-Safe-escaping-of-fragments-for-eval.patchAttachment: signature.asc
Description: Digital signature
--- End Message ---
--- Begin Message ---
- To: David Prévot <taffit@debian.org>, 781709-done@bugs.debian.org
- Subject: Re: Bug#781709: unblock: symfony/2.3.21+dfsg-4
- From: Niels Thykier <niels@thykier.net>
- Date: Thu, 02 Apr 2015 09:50:33 +0200
- Message-id: <551CF4C9.10803@thykier.net>
- In-reply-to: <[🔎] 20150401214119.GA20648@mikado.tilapin.org>
- References: <[🔎] 20150401214119.GA20648@mikado.tilapin.org>
On 2015-04-01 23:41, David Prévot wrote: > Package: release.debian.org > Severity: normal > User: release.debian.org@packages.debian.org > Usertags: unblock > > Please unblock package symfony > > It cherry-picks to security fixes from upstrem: > > symfony (2.3.21+dfsg-4) unstable; urgency=medium > > * Backport security fixes from 2.3.27: > - Esi Code Injection [CVE-2015-2308] > - Unsafe methods in the Request class [CVE-2015-2309] > > -- David Prévot <taffit@debian.org> Wed, 01 Apr 2015 16:53:00 -0400 > > unblock symfony/2.3.21+dfsg-4 > > Thanks in advance. > > Regards > > David > Unblocked, thanks. ~Niels
--- End Message ---