Problem/Motivation

Quoting @xjm in #3278162-3: Update Composer dependencies to the latest minor and patch versions.2:

+++ b/composer/Metapackage/CoreRecommended/composer.json
@@ -9,18 +9,18 @@
-        "composer/semver": "3.2.6",
+        "composer/semver": "3.3.2",
...
-        "laminas/laminas-diactoros": "2.8.0",
+        "laminas/laminas-diactoros": "2.9.2",
         "laminas/laminas-escaper": "2.9.0",
-        "laminas/laminas-feed": "2.15.0",
-        "laminas/laminas-stdlib": "3.6.1",
+        "laminas/laminas-feed": "2.17.0",
+        "laminas/laminas-stdlib": "3.7.1",

Minor updates for 9.4.x. Should we increase constraints for forward-compatibility with the latest minors in case of sec releases? Could be a followup.

This is that follow-up.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

Issue tags: -Drupal 9.4 target

I have been inspecting the commit history of composer/Metapackage/CoreRecommended/composer.json but cannot find any prior example like this. So … after spending a good while reading and diffing and googling, I still don't know what the concrete increases would/could be.

The updates cited have already been committed to 9.4.x. So … forward compatibility in/with what? Of 9.3.x with 9.4.x? 9.4.x with 10.0.x?

The closest examples I found are #3199199: [meta] Add compatibility for the latest major and minor versions of dependencies to Drupal 9 and #3267879: [meta] Add compatibility for the latest major and minor versions of dependencies to Drupal 10, but neither of those seem to cover what @xjm wrote in that comment.

xjm’s picture

So here's the issue. Take Diactoros for example:

In 9.4, the version used in the lockfile (and therefore core-recommended and the tarballs) is 2.9.2. However, the minimum constraint for it in core/composer.json is:
"laminas/laminas-diactoros": "^2.1"

Say Diactoros issues a security update for something that's exploitable in core, as (say) 2.9.4. If core is vulnerable, it's our policy to increase core's constraint to require the secure version of Diactoros. However, if we increase the constraint from ^2.1 to ^2.9.4 in a security release, that could force sites that were not using core-recommended to have a minor update of Diactoros in a patch release, which breaks many folks' expectations about semver.

So the thing to discuss is whether to increase our constraints to require the minor versions used in the lockfiles, as a forward mitigation against this problem, or whether it's better to allow sites that are not using core-recommended the freedom to use an older version of Diactoros (with the risk that they might then have a minor update forced on them in a security window if such a security release happened).

wim leers’s picture

👍 Thanks for that clarification! 🙏

I think that forward mitigation is then the prudent and least disruptive choice we can make.

It’s in line with what can be expected of a Drupal core minor release. And helps make Drupal core security releases also be in line with expectations.

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new1.62 KB

I inspected everything in core/composer.json's require and compared to what's in composer/Metapackage/CoreRecommended/composer.json. Whenever the latter requires a newer patch version, I didn't make any changes. Whenever the latter requires a new minor version, I did update core/composer.json accordingly. (No major version differences exist — that's impossible.)

But then there are at least some things to pay extra attention to:

  1. twig/twig: core/composer.json was explicitly updated to use Twig 2.14.11 in #3262583: Twig 2.14.11 update, but with zero context provided in that issue. 😬🤔 And #3278162: Update Composer dependencies to the latest minor and patch versions then updated only composer/Metapackage/CoreRecommended/composer.json to Twig 2.14.13. After some digging, that was AFAICT because of https://www.symfony-news.com/news/details/twig-security-release-disallow..., which resulted in https://www.drupal.org/project/drupal/releases/9.3.5.
  2. doctrine/reflection was still at ^1.1 in core/composer.json but has been at 1.2.2 in composer/Metapackage/CoreRecommended/composer.json since October 2020. For consistency sake, I updated core/composer.json to ^1.2.
  3. doctrine/annotations: similar thing: a minor increment, but the recommended version was specified in August 2021.
  4. … and apparently also similar story for symfony-cmf/routing, egulias/email-validator, masterminds/html5, symfony/psr-http-message-bridge, asm89/stack-cors and psr/log.

End result: every require dependency in core/composer.json gets updated with the exception of:

  • PHP version + extensions
  • All Symfony packages (except symfony/psr-http-message-bridge)
  • typo3/phar-stream-wrapper
  • twig/twig
  • guzzlehttp/guzzle
  • stack/builder
  • pear/archive_tar

… which remain unchanged.

wim leers’s picture

Issue tags: +Security improvements
xjm’s picture

Many thanks @Wim Leers -- now to get feedback on this change. I didn't realize so many dependencies were that far behind. Tagging.

catch’s picture

+1 from me, decreases the likelihood of a disruptive change later, and seems fairly unlikely that many (any?) sites are explicitly relying on the lower versions.

xjm’s picture

Status: Needs review » Needs work
Issue tags: -Needs framework manager review, -Needs release manager review

OK, it sounds like we have signoffs on this change.

Unfortunately, the patch no longer applies because of the Guzzle release...

We should also make sure that the 10.0.x constraints are higher than these; it might be 9.5.x/9.4.x only if they are all on later major versions (or totally absent) in 10.0.x's core/composer.json.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new198 bytes
new1.62 KB

Reroll for 9.4.x

quietone’s picture

StatusFileSize
new1.11 KB

Same for 10.0x

wim leers’s picture

Thanks for the reroll, @quietone!

Queued a test for #12 too.

wim leers’s picture

Status: Needs review » Needs work

Well that's interesting:

Testing Drupal\Tests\ComposerIntegrationTest
F........S.....S..............................................    62 / 62 (100%)

Time: 00:00.094, Memory: 6.00 MB

There was 1 failure:

1) Drupal\Tests\ComposerIntegrationTest::testComposerLockHash
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-'c19318bd4afee3527153bbbbfc0e1ca89e127fc0'
+'78bbfc3df240b4eda4a4862733490c55dacbf5d1'

Fortunately there's this:

  /**
   * Tests composer.lock content-hash.
   *
   * If you have made a change to composer.json, you may need to reconstruct
   * composer.lock. Follow the link below for further instructions.
   *
   * @see https://www.drupal.org/about/core/policies/core-dependencies-policies/managing-composer-updates-for-drupal-core
   */
  public function testComposerLockHash() {

… unfortunately it does not mention content-hash at all. It only mentions "hash" once. And composer update --lock does not actually update the content-hash for me.

Those docs were added in #3192842: Make our README more welcoming by converting it into an "entrypoint" into the Drupal ecosystem. I tried pretty much all the composer commands listed there. (Twice: once with 2.1.9, once on the latest: 2.4-dev+556450b15b6c47c55ffa46bd9048b410d56c3983).

My composer-fu is not strong enough for this one 😬 I really wonder what I'm doing wrong 🙈 Really curious about this one!

wim leers’s picture

I can actually reproduce this failure locally. A single change in core/composer.json will cause a different content-hash.

But … it fails on both 10.0.x and 9.5.x. Why does it on d.o only fail on one of the two branches?! 🤯

wim leers’s picture

Status: Needs work » Needs review
StatusFileSize
new2.61 KB
new4.28 KB
new1.94 KB
new3.1 KB

Looking at the commit history, there's a lot of times where the hash (well, one of the two hashes that get checked — the test method is named pretty confusingly) got out of sync, and caused problems only on some environments. I'll accept that I do not fully grok composer.

As far as I can tell, we need more changes in both patches. Trying that here. 🤞

Both of these are with the patches above applied, then composer update --lock to generate an interdiff, the combination of the two makes for the patch.

effulgentsia’s picture

Status: Needs review » Reviewed & tested by the community

This looks good with respect to the production dependencies. Should we have a followup to do the same for dev dependencies?

xjm’s picture

@effulgentsia Backend dev dependencies don't have quite the same risk, because we don't package them in tagged releases nor issue security advisories for them in general. So I think it's sufficient just to harden the constraints for production dependencies for this.

xjm’s picture

Title: Consider increasing constraints for forward compatibility » Increase Composer dependency constraints to latest minors for forward-compatibility

  • xjm committed 2dc7612 on 10.0.x
    Issue #3281578 by Wim Leers, quietone, xjm, catch: Increase Composer...

  • xjm committed be96621 on 9.5.x
    Issue #3281578 by Wim Leers, quietone, xjm, catch: Increase Composer...

  • xjm committed a1f189f on 9.4.x
    Issue #3281578 by Wim Leers, quietone, xjm, catch: Increase Composer...
xjm’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +9.4.0 release notes, +10.0.0 release notes

Committed to 10.0.x and 9.5.x, and cherry-picked to 9.4.x. Thanks!

We'll need to mention this in the release notes (probably just adding a sentence to the existing note).

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.