Package: release.debian.org Severity: normal Tags: bookworm User: release.debian.org@packages.debian.org Usertags: pu X-Debbugs-Cc: symfony@packages.debian.org, Debian PHP PEAR Maintainers <pkg-php-pear@lists.alioth.debian.org> Control: affects -1 + src:symfony Hi, I’d like to fix the following two security issues in the next point release, as advised by the security team (they do not intend to issue a DSA for that). [TwigBridge] Ensure CodeExtension's filters properly escape their input [CVE-2023-46734] (Closes: #1055774) [Security] Fix possible session fixation when only the *token* changes [CVE-2023-46733] (Closes: #1055775) I didn’t test the packages thoroughly (and I’m not sure to have much time for a while), but at least the testsuites pass. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable Thanks in advance, taffit
diff -Nru symfony-5.4.23+dfsg/debian/changelog symfony-5.4.23+dfsg/debian/changelog --- symfony-5.4.23+dfsg/debian/changelog 2023-04-29 18:41:44.000000000 +0200 +++ symfony-5.4.23+dfsg/debian/changelog 2023-11-11 18:59:39.000000000 +0100 @@ -1,3 +1,14 @@ +symfony (5.4.23+dfsg-1+deb12u1) bookworm; urgency=medium + + * debian/gbp.conf: Track bookworm branch + * Backport security fixes from Symfony 5.4.31 + - [TwigBridge] Ensure CodeExtension's filters properly escape their input + [CVE-2023-46734] (Closes: #1055774) + - [Security] Fix possible session fixation when only the *token* changes + [CVE-2023-46733] (Closes: #1055775) + + -- David Prévot <taffit@debian.org> Sat, 11 Nov 2023 18:59:39 +0100 + symfony (5.4.23+dfsg-1) unstable; urgency=medium [ Fabien Potencier ] diff -Nru symfony-5.4.23+dfsg/debian/gbp.conf symfony-5.4.23+dfsg/debian/gbp.conf --- symfony-5.4.23+dfsg/debian/gbp.conf 2023-02-28 19:54:32.000000000 +0100 +++ symfony-5.4.23+dfsg/debian/gbp.conf 2023-11-11 18:59:39.000000000 +0100 @@ -1,5 +1,5 @@ [DEFAULT] -debian-branch = debian/latest +debian-branch = debian/bookworm pristine-tar = True filter = [ '.gitattributes' ] diff -Nru symfony-5.4.23+dfsg/debian/patches/Security-Fix-possible-session-fixation-when-only-the-toke.patch symfony-5.4.23+dfsg/debian/patches/Security-Fix-possible-session-fixation-when-only-the-toke.patch --- symfony-5.4.23+dfsg/debian/patches/Security-Fix-possible-session-fixation-when-only-the-toke.patch 1970-01-01 01:00:00.000000000 +0100 +++ symfony-5.4.23+dfsg/debian/patches/Security-Fix-possible-session-fixation-when-only-the-toke.patch 2023-11-11 18:59:39.000000000 +0100 @@ -0,0 +1,65 @@ +From: Robert <symfony@robert.meijers.dev> +Date: Fri, 3 Nov 2023 17:09:59 +0100 +Subject: [Security] Fix possible session fixation when only the *token* + changes + +Origin: upstream, https://github.com/symfony/symfony/commit/dc356499d5ceb86f7cf2b4c7f032eca97061ed74 +Bug: https://symfony.com/blog/cve-2023-46733-possible-session-fixation +Bug-Debian: https://bugs.debian.org/1055775 +--- + .../Http/EventListener/SessionStrategyListener.php | 2 +- + .../EventListener/SessionStrategyListenerTest.php | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php b/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php +index 311a52f..c6fcba8 100644 +--- a/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php ++++ b/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php +@@ -48,7 +48,7 @@ class SessionStrategyListener implements EventSubscriberInterface + $user = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); + $previousUser = method_exists($previousToken, 'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername(); + +- if ('' !== ($user ?? '') && $user === $previousUser) { ++ if ('' !== ($user ?? '') && $user === $previousUser && \get_class($token) === \get_class($previousToken)) { + return; + } + } +diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php +index 51b8dc1..29ef9b6 100644 +--- a/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php ++++ b/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php +@@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\Security\Core\Authentication\Token\NullToken; ++use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; + use Symfony\Component\Security\Core\User\InMemoryUser; + use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; + use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; +@@ -81,6 +82,26 @@ class SessionStrategyListenerTest extends TestCase + $this->listener->onSuccessfulLogin($event); + } + ++ public function testRequestWithSamePreviousUserButDifferentTokenType() ++ { ++ $this->configurePreviousSession(); ++ ++ $token = $this->createMock(NullToken::class); ++ $token->expects($this->once()) ++ ->method('getUserIdentifier') ++ ->willReturn('test'); ++ $previousToken = $this->createMock(UsernamePasswordToken::class); ++ $previousToken->expects($this->once()) ++ ->method('getUserIdentifier') ++ ->willReturn('test'); ++ ++ $this->sessionAuthenticationStrategy->expects($this->once())->method('onAuthentication')->with($this->request, $token); ++ ++ $event = new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function () {})), $token, $this->request, null, 'main_firewall', $previousToken); ++ ++ $this->listener->onSuccessfulLogin($event); ++ } ++ + private function createEvent($firewallName) + { + return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function ($username) { return new InMemoryUser($username, null); })), $this->token, $this->request, null, $firewallName); diff -Nru symfony-5.4.23+dfsg/debian/patches/series symfony-5.4.23+dfsg/debian/patches/series --- symfony-5.4.23+dfsg/debian/patches/series 2023-04-29 15:30:23.000000000 +0200 +++ symfony-5.4.23+dfsg/debian/patches/series 2023-11-11 18:59:39.000000000 +0100 @@ -31,3 +31,5 @@ Workaround-ICU-new-format.patch Allow-doctrine-event-manager-2.patch Drop-data-tests-failing-with-PHP-8.2.patch +TwigBridge-Ensure-CodeExtension-s-filters-properly-escape.patch +Security-Fix-possible-session-fixation-when-only-the-toke.patch diff -Nru symfony-5.4.23+dfsg/debian/patches/TwigBridge-Ensure-CodeExtension-s-filters-properly-escape.patch symfony-5.4.23+dfsg/debian/patches/TwigBridge-Ensure-CodeExtension-s-filters-properly-escape.patch --- symfony-5.4.23+dfsg/debian/patches/TwigBridge-Ensure-CodeExtension-s-filters-properly-escape.patch 1970-01-01 01:00:00.000000000 +0100 +++ symfony-5.4.23+dfsg/debian/patches/TwigBridge-Ensure-CodeExtension-s-filters-properly-escape.patch 2023-11-11 18:59:39.000000000 +0100 @@ -0,0 +1,76 @@ +From: Nicolas Grekas <nicolas.grekas@gmail.com> +Date: Fri, 3 Nov 2023 17:03:49 +0100 +Subject: [TwigBridge] Ensure CodeExtension's filters properly escape their + input + +Origin: upstream, https://github.com/symfony/symfony/commit/8128c302430394f639e818a7103b3f6815d8d962 +Bug: https://symfony.com/blog/cve-2023-46734-potential-xss-vulnerabilities-in-codeextension-filters +Bug-Debian: https://bugs.debian.org/1055774 +--- + .../Bridge/Twig/Extension/CodeExtension.php | 23 +++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +index 3bf8ccd..23f7280 100644 +--- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php ++++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +@@ -42,8 +42,8 @@ final class CodeExtension extends AbstractExtension + public function getFilters(): array + { + return [ +- new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]), +- new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html']]), ++ new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html'], 'pre_escape' => 'html']), ++ new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html'], 'pre_escape' => 'html']), + new TwigFilter('format_args', [$this, 'formatArgs'], ['is_safe' => ['html']]), + new TwigFilter('format_args_as_text', [$this, 'formatArgsAsText']), + new TwigFilter('file_excerpt', [$this, 'fileExcerpt'], ['is_safe' => ['html']]), +@@ -85,22 +85,23 @@ final class CodeExtension extends AbstractExtension + $result = []; + foreach ($args as $key => $item) { + if ('object' === $item[0]) { ++ $item[1] = htmlspecialchars($item[1], \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); + $parts = explode('\\', $item[1]); + $short = array_pop($parts); + $formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short); + } elseif ('array' === $item[0]) { +- $formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); ++ $formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)); + } elseif ('null' === $item[0]) { + $formattedValue = '<em>null</em>'; + } elseif ('boolean' === $item[0]) { +- $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>'; ++ $formattedValue = '<em>'.strtolower(htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)).'</em>'; + } elseif ('resource' === $item[0]) { + $formattedValue = '<em>resource</em>'; + } else { + $formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)); + } + +- $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); ++ $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", htmlspecialchars($key, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $formattedValue); + } + + return implode(', ', $result); +@@ -152,13 +153,17 @@ final class CodeExtension extends AbstractExtension + public function formatFile(string $file, int $line, string $text = null): string + { + $file = trim($file); ++ $line = (int) $line; + + if (null === $text) { +- $text = $file; +- if (null !== $rel = $this->getFileRelative($text)) { +- $rel = explode('/', $rel, 2); +- $text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', $this->projectDir, $rel[0], '/'.($rel[1] ?? '')); ++ if (null !== $rel = $this->getFileRelative($file)) { ++ $rel = explode('/', htmlspecialchars($rel, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), 2); ++ $text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', htmlspecialchars($this->projectDir, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $rel[0], '/'.($rel[1] ?? '')); ++ } else { ++ $text = htmlspecialchars($file, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); + } ++ } else { ++ $text = htmlspecialchars($text, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); + } + + if (0 < $line) {
Attachment:
signature.asc
Description: PGP signature