Your message dated Sat, 16 May 2026 10:23:16 +0000
with message-id <[email protected]>
and subject line Released with 13.5
has caused the Debian Bug report #1134502,
regarding trixie-pu: package composer/2.8.8-1+deb13u2
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 [email protected]
immediately.)


-- 
1134502: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1134502
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:composer
User: [email protected]
Usertags: pu

Hi,

As agreed with the security team, I’d like to get CVE-2026-40261 and
CVE-2026-40261 fixed via an upcoming point release. The changes are
limited, and only about a niche feature.

[ 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,

Regards,

taffit
diff -Nru composer-2.8.8/debian/changelog composer-2.8.8/debian/changelog
--- composer-2.8.8/debian/changelog	2025-12-30 16:35:23.000000000 +0100
+++ composer-2.8.8/debian/changelog	2026-04-15 10:50:08.000000000 +0200
@@ -1,3 +1,12 @@
+composer (2.8.8-1+deb13u2) trixie; urgency=medium
+
+  * Fix command injection via malicious Perforce repository definition
+    [CVE-2026-40261]
+  * Fix command injection via malicious Perforce source reference/url
+    [CVE-2026-40176]
+
+ -- David Prévot <[email protected]>  Wed, 15 Apr 2026 10:50:08 +0200
+
 composer (2.8.8-1+deb13u1) trixie; urgency=medium
 
   * Backport fix from composer 2.9.3:
diff -Nru composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch
--- composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch	1970-01-01 01:00:00.000000000 +0100
+++ composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch	2026-04-15 10:50:08.000000000 +0200
@@ -0,0 +1,47 @@
+From: Jordi Boggiano <[email protected]>
+Date: Tue, 14 Apr 2026 10:34:08 +0200
+Subject: Merge commit from fork
+
+Origin: upstream, https://github.com/composer/composer/commit/91f077050c13e49e22554b991c81378ce8b5ee16
+Bug: https://github.com/composer/composer/security/advisories/GHSA-gqw4-4w2p-838q
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-40261
+---
+ src/Composer/Util/Perforce.php            | 2 +-
+ tests/Composer/Test/Util/PerforceTest.php | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/Composer/Util/Perforce.php b/src/Composer/Util/Perforce.php
+index bfed834..3b6ff9f 100644
+--- a/src/Composer/Util/Perforce.php
++++ b/src/Composer/Util/Perforce.php
+@@ -354,7 +354,7 @@ class Perforce
+         chdir($this->path);
+         $p4SyncCommand = $this->generateP4Command('sync -f ');
+         if (null !== $sourceReference) {
+-            $p4SyncCommand .= '@' . $sourceReference;
++            $p4SyncCommand .= ProcessExecutor::escape('@' . $sourceReference);
+         }
+         $this->executeCommand($p4SyncCommand);
+         chdir($prevDir);
+diff --git a/tests/Composer/Test/Util/PerforceTest.php b/tests/Composer/Test/Util/PerforceTest.php
+index 99a908c..53e3b31 100644
+--- a/tests/Composer/Test/Util/PerforceTest.php
++++ b/tests/Composer/Test/Util/PerforceTest.php
+@@ -539,7 +539,7 @@ class PerforceTest extends TestCase
+     public function testSyncCodeBaseWithoutStream(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f @label'],
++            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f \'@label\''],
+             true
+         );
+ 
+@@ -551,7 +551,7 @@ class PerforceTest extends TestCase
+         $this->setPerforceToStream();
+ 
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f @label'],
++            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f \'@label\''],
+             true
+         );
+ 
diff -Nru composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch
--- composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch	1970-01-01 01:00:00.000000000 +0100
+++ composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch	2026-04-15 10:50:08.000000000 +0200
@@ -0,0 +1,236 @@
+From: Jordi Boggiano <[email protected]>
+Date: Tue, 14 Apr 2026 10:41:57 +0200
+Subject: Merge commit from fork
+
+Co-authored-by: Stephan Vock <[email protected]>
+
+Origin: upstream, https://github.com/composer/composer/commit/4f02616e6fba3b1baf8d45725f847841b44fc15c
+Bug: https://github.com/composer/composer/security/advisories/GHSA-wg36-wvj6-r67p
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-40176
+---
+ src/Composer/Util/Perforce.php            |  6 +--
+ tests/Composer/Test/Util/PerforceTest.php | 82 ++++++++++++++++++++++++-------
+ 2 files changed, 67 insertions(+), 21 deletions(-)
+
+diff --git a/src/Composer/Util/Perforce.php b/src/Composer/Util/Perforce.php
+index 3b6ff9f..331daf3 100644
+--- a/src/Composer/Util/Perforce.php
++++ b/src/Composer/Util/Perforce.php
+@@ -311,11 +311,11 @@ class Perforce
+     public function generateP4Command(string $command, bool $useClient = true): string
+     {
+         $p4Command = $this->getP4Executable().' ';
+-        $p4Command .= '-u ' . $this->getUser() . ' ';
++        $p4Command .= '-u ' . ProcessExecutor::escape($this->getUser()) . ' ';
+         if ($useClient) {
+-            $p4Command .= '-c ' . $this->getClient() . ' ';
++            $p4Command .= '-c ' . ProcessExecutor::escape($this->getClient()) . ' ';
+         }
+-        $p4Command .= '-p ' . $this->getPort() . ' ' . $command;
++        $p4Command .= '-p ' . ProcessExecutor::escape($this->getPort()) . ' ' . $command;
+ 
+         return $p4Command;
+     }
+diff --git a/tests/Composer/Test/Util/PerforceTest.php b/tests/Composer/Test/Util/PerforceTest.php
+index 53e3b31..752079c 100644
+--- a/tests/Composer/Test/Util/PerforceTest.php
++++ b/tests/Composer/Test/Util/PerforceTest.php
+@@ -128,10 +128,56 @@ class PerforceTest extends TestCase
+     {
+         $command = 'do something';
+         $p4Command = $this->perforce->generateP4Command($command);
+-        $expected = 'p4 -u user -c composer_perforce_TEST_depot -p port do something';
++        $expected = "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' do something";
+         self::assertEquals($expected, $p4Command);
+     }
+ 
++    public function testGenerateP4CommandEscapesPortInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'depot', 'branch' => 'branch', 'p4user' => 'user', 'unique_perforce_client_name' => 'TEST'],
++            'localhost:1666; touch /tmp/pwned',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('login -s', false);
++        self::assertStringNotContainsString('-p localhost:1666; touch /tmp/pwned', $command);
++        self::assertStringContainsString('-p '.ProcessExecutor::escape('localhost:1666; touch /tmp/pwned'), $command);
++    }
++
++    public function testGenerateP4CommandEscapesUserInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'depot', 'branch' => 'branch', 'p4user' => 'user; id', 'unique_perforce_client_name' => 'TEST'],
++            'port',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('login -s', false);
++        self::assertStringNotContainsString('-u user; id', $command);
++        self::assertStringContainsString('-u '.ProcessExecutor::escape('user; id'), $command);
++    }
++
++    public function testGenerateP4CommandEscapesClientInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'foo; id #', 'branch' => 'branch', 'p4user' => 'user', 'unique_perforce_client_name' => 'TEST'],
++            'port',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('do something');
++        $expectedClient = 'composer_perforce_TEST_foo; id #';
++        self::assertStringNotContainsString('-c '.$expectedClient.' ', $command);
++        self::assertStringContainsString('-c '.ProcessExecutor::escape($expectedClient), $command);
++    }
++
+     public function testQueryP4UserWithUserAlreadySet(): void
+     {
+         $this->perforce->queryP4user();
+@@ -319,7 +365,7 @@ class PerforceTest extends TestCase
+     public function testIsLoggedIn(): void
+     {
+         $this->processExecutor->expects(
+-            [['cmd' => 'p4 -u user -p port login -s']],
++            [['cmd' => "p4 -u 'user' -p 'port' login -s"]],
+             true
+         );
+         $this->perforce->isLoggedIn();
+@@ -328,7 +374,7 @@ class PerforceTest extends TestCase
+     public function testConnectClient(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port client -i < '.ProcessExecutor::escape('path/composer_perforce_TEST_depot.p4.spec')],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' client -i < ".ProcessExecutor::escape('path/composer_perforce_TEST_depot.p4.spec')],
+             true
+         );
+ 
+@@ -342,11 +388,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port streams '.ProcessExecutor::escape('//depot/...'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' streams ".ProcessExecutor::escape('//depot/...'),
+                     'stdout' => 'Stream //depot/branch mainline none \'branch\'' . PHP_EOL,
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/branch/...'),
++                    'cmd' => "p4 -u 'user' -p 'port' changes ".ProcessExecutor::escape('//depot/branch/...'),
+                     'stdout' => 'Change 1234 on 2014/03/19 by [email protected]_test_client \'test changelist\'',
+                 ],
+             ],
+@@ -362,7 +408,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/...'),
++                    'cmd' => "p4 -u 'user' -p 'port' changes ".ProcessExecutor::escape('//depot/...'),
+                     'stdout' => 'Change 5678 on 2014/03/19 by [email protected]_test_client \'test changelist\'',
+                 ],
+             ],
+@@ -378,7 +424,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port labels',
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' labels",
+                     'stdout' => 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL,
+                 ],
+             ],
+@@ -397,7 +443,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port labels',
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' labels",
+                     'stdout' => 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL,
+                 ],
+             ],
+@@ -421,7 +467,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port depots',
++                    'cmd' => "p4 -u 'user' -p 'port' depots",
+                     'stdout' => 'Depot depot 2013/06/25 stream /p4/1/depots/depot/... \'Created by Me\'',
+                 ],
+             ],
+@@ -438,7 +484,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port  print '.ProcessExecutor::escape('//depot/composer.json'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port'  print ".ProcessExecutor::escape('//depot/composer.json'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -460,11 +506,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port  files '.ProcessExecutor::escape('//depot/[email protected]'),
++                    'cmd' => "p4 -u 'user' -p 'port'  files ".ProcessExecutor::escape('//depot/[email protected]'),
+                     'stdout' => '//depot/composer.json#1 - branch change 10001 (text)',
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port  print '.ProcessExecutor::escape('//depot/composer.json@10001'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port'  print ".ProcessExecutor::escape('//depot/composer.json@10001'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -489,7 +535,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port  print '.ProcessExecutor::escape('//depot/branch/composer.json'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port'  print ".ProcessExecutor::escape('//depot/branch/composer.json'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -512,11 +558,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port  files '.ProcessExecutor::escape('//depot/branch/[email protected]'),
++                    'cmd' => "p4 -u 'user' -p 'port'  files ".ProcessExecutor::escape('//depot/branch/[email protected]'),
+                     'stdout' => '//depot/composer.json#1 - branch change 10001 (text)',
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port  print '.ProcessExecutor::escape('//depot/branch/composer.json@10001'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port'  print ".ProcessExecutor::escape('//depot/branch/composer.json@10001'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -539,7 +585,7 @@ class PerforceTest extends TestCase
+     public function testSyncCodeBaseWithoutStream(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f \'@label\''],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' sync -f '@label'"],
+             true
+         );
+ 
+@@ -551,7 +597,7 @@ class PerforceTest extends TestCase
+         $this->setPerforceToStream();
+ 
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f \'@label\''],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' sync -f '@label'"],
+             true
+         );
+ 
+@@ -649,7 +695,7 @@ class PerforceTest extends TestCase
+ 
+         $testClient = $this->perforce->getClient();
+         $this->processExecutor->expects(
+-            ['p4 -u ' . self::TEST_P4USER . ' -p ' . self::TEST_PORT . ' client -d ' . ProcessExecutor::escape($testClient)],
++            ["p4 -u '" . self::TEST_P4USER . "' -p '" . self::TEST_PORT . "' client -d " . ProcessExecutor::escape($testClient)],
+             true
+         );
+ 
diff -Nru composer-2.8.8/debian/patches/series composer-2.8.8/debian/patches/series
--- composer-2.8.8/debian/patches/series	2025-12-30 16:33:32.000000000 +0100
+++ composer-2.8.8/debian/patches/series	2026-04-15 10:50:08.000000000 +0200
@@ -15,3 +15,5 @@
 0015-Revert-Fix-regression-from-12233-in-InstalledVersion.patch
 0016-Modernize-PHPUnit-syntax.patch
 0017-Merge-commit-from-fork.patch
+0018-Merge-commit-from-fork.patch
+0019-Merge-commit-from-fork.patch

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 13.5

This update has been released as part of Debian 13.5.

--- End Message ---

Reply via email to