Package: release.debian.org Severity: normal Tags: bookworm X-Debbugs-Cc: composer@packages.debian.org Control: affects -1 + src:composer User: release.debian.org@packages.debian.org Usertags: pu [ Same as #1124354 for trixie, with a smaller diff. ] Hi, As agreed with the security team, I’d like to fix CVE-2025-67746 in a point release rather than a DSA since it mostly fixes a display issue. [ 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 Regards, taffit
diff -Nru composer-2.5.5/debian/changelog composer-2.5.5/debian/changelog
--- composer-2.5.5/debian/changelog 2024-06-14 08:01:19.000000000 +0200
+++ composer-2.5.5/debian/changelog 2025-12-30 17:01:22.000000000 +0100
@@ -1,3 +1,10 @@
+composer (2.5.5-1+deb12u3) bookworm; urgency=medium
+
+ * Backport fix from composer 2.2.26:
+ Fixed ANSI sequence injection [CVE-2025-67746]
+
+ -- David Prévot <taffit@debian.org> Tue, 30 Dec 2025 17:01:22 +0100
+
composer (2.5.5-1+deb12u2) bookworm-security; urgency=medium
* Include security fixes from 2.7.7:
diff -Nru composer-2.5.5/debian/patches/0018-Merge-commit-from-fork.patch composer-2.5.5/debian/patches/0018-Merge-commit-from-fork.patch
--- composer-2.5.5/debian/patches/0018-Merge-commit-from-fork.patch 1970-01-01 01:00:00.000000000 +0100
+++ composer-2.5.5/debian/patches/0018-Merge-commit-from-fork.patch 2025-12-30 17:00:22.000000000 +0100
@@ -0,0 +1,122 @@
+From: Jordi Boggiano <j.boggiano@seld.be>
+Date: Tue, 30 Dec 2025 13:18:16 +0100
+Subject: Merge commit from fork
+
+Origin: upstream, https://github.com/composer/composer/commit/1d40a95c9d39a6b7f80d404ab30336c586da9917
+Bug: https://github.com/composer/composer/security/advisories/GHSA-59pp-r3rg-353g
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2025-67746
+---
+ src/Composer/IO/ConsoleIO.php | 46 ++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 41 insertions(+), 5 deletions(-)
+
+diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php
+index 8ecea42..16d285c 100644
+--- a/src/Composer/IO/ConsoleIO.php
++++ b/src/Composer/IO/ConsoleIO.php
+@@ -12,6 +12,7 @@
+
+ namespace Composer\IO;
+
++use Composer\Pcre\Preg;
+ use Composer\Question\StrictConfirmationQuestion;
+ use Symfony\Component\Console\Helper\HelperSet;
+ use Symfony\Component\Console\Helper\ProgressBar;
+@@ -120,6 +121,8 @@ class ConsoleIO extends BaseIO
+ */
+ public function write($messages, bool $newline = true, int $verbosity = self::NORMAL)
+ {
++ $messages = self::sanitize($messages);
++
+ $this->doWrite($messages, $newline, false, $verbosity);
+ }
+
+@@ -128,6 +131,8 @@ class ConsoleIO extends BaseIO
+ */
+ public function writeError($messages, bool $newline = true, int $verbosity = self::NORMAL)
+ {
++ $messages = self::sanitize($messages);
++
+ $this->doWrite($messages, $newline, true, $verbosity);
+ }
+
+@@ -252,7 +257,7 @@ class ConsoleIO extends BaseIO
+ {
+ /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
+ $helper = $this->helperSet->get('question');
+- $question = new Question($question, $default);
++ $question = new Question(self::sanitize($question), is_string($default) ? self::sanitize($default) : $default);
+
+ return $helper->ask($this->input, $this->getErrorOutput(), $question);
+ }
+@@ -264,7 +269,7 @@ class ConsoleIO extends BaseIO
+ {
+ /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
+ $helper = $this->helperSet->get('question');
+- $question = new StrictConfirmationQuestion($question, $default);
++ $question = new StrictConfirmationQuestion(self::sanitize($question), is_string($default) ? self::sanitize($default) : $default);
+
+ return $helper->ask($this->input, $this->getErrorOutput(), $question);
+ }
+@@ -276,7 +281,7 @@ class ConsoleIO extends BaseIO
+ {
+ /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
+ $helper = $this->helperSet->get('question');
+- $question = new Question($question, $default);
++ $question = new Question(self::sanitize($question), is_string($default) ? self::sanitize($default) : $default);
+ $question->setValidator($validator);
+ $question->setMaxAttempts($attempts);
+
+@@ -290,7 +295,7 @@ class ConsoleIO extends BaseIO
+ {
+ /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
+ $helper = $this->helperSet->get('question');
+- $question = new Question($question);
++ $question = new Question(self::sanitize($question));
+ $question->setHidden(true);
+
+ return $helper->ask($this->input, $this->getErrorOutput(), $question);
+@@ -303,7 +308,7 @@ class ConsoleIO extends BaseIO
+ {
+ /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
+ $helper = $this->helperSet->get('question');
+- $question = new ChoiceQuestion($question, $choices, $default);
++ $question = new ChoiceQuestion(self::sanitize($question), self::sanitize($choices), is_string($default) ? self::sanitize($default) : $default);
+ $question->setMaxAttempts($attempts ?: null); // IOInterface requires false, and Question requires null or int
+ $question->setErrorMessage($errorMessage);
+ $question->setMultiselect($multiselect);
+@@ -342,4 +347,35 @@ class ConsoleIO extends BaseIO
+
+ return $this->output;
+ }
++
++ /**
++ * Sanitize string to remove control characters
++ *
++ * If $allowNewlines is true, \x0A (\n) and \x0D\x0A (\r\n) are let through. Single \r are still sanitized away to prevent overwriting whole lines.
++ *
++ * All other control chars (except NULL bytes) as well as ANSI escape sequences are removed.
++ *
++ * @param string|iterable<string> $messages
++ * @return string|array<string>
++ * @phpstan-return ($messages is string ? string : array<string>)
++ */
++ public static function sanitize($messages, $allowNewlines = true)
++ {
++ // Match ANSI escape sequences:
++ // - CSI (Control Sequence Introducer): ESC [ params intermediate final
++ // - OSC (Operating System Command): ESC ] ... ESC \ or BEL
++ // - Other ESC sequences: ESC followed by any character
++ $escapePattern = '\x1B\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]|\x1B\].*?(?:\x1B\\\\|\x07)|\x1B.';
++ $pattern = $allowNewlines ? "{{$escapePattern}|[\x01-\x09\x0B\x0C\x0E-\x1A]|\r(?!\n)}u" : "{{$escapePattern}|[\x01-\x1A]}u";
++ if (is_string($messages)) {
++ return Preg::replace($pattern, '', $messages);
++ }
++
++ $sanitized = array();
++ foreach ($messages as $key => $message) {
++ $sanitized[$key] = Preg::replace($pattern, '', $message);
++ }
++
++ return $sanitized;
++ }
+ }
diff -Nru composer-2.5.5/debian/patches/series composer-2.5.5/debian/patches/series
--- composer-2.5.5/debian/patches/series 2024-06-14 08:01:19.000000000 +0200
+++ composer-2.5.5/debian/patches/series 2025-12-30 17:00:22.000000000 +0100
@@ -15,3 +15,4 @@
0015-Merge-pull-request-from-GHSA-v9qv-c7wm-wgmf.patch
0016-Merge-pull-request-from-GHSA-47f6-5gq3-vx9c.patch
0017-Fix-test.patch
+0018-Merge-commit-from-fork.patch
Attachment:
signature.asc
Description: PGP signature