Problem/Motivation
Composer's security blocking feature completely prevents install and update working if any package has a security advisory and can't be updated with the current command/constraints.
At the same time, several of Drupal's dependencies (Symfony, Twig, Guzzle) release security updates as new minor versions, with no backport to prevous minor branches, on arbitrary schedules.
Recent examples:
#3599842: guzzlehttp/psr7 needs to be updated to >2.10.2 to fix 2 security issues
#3591179: Update main and 11.x to latest Twig and Symfony versions
#3592065: Drupal core-recommended pins vulnerable symfony/polyfill-intl-idn version affected by CVE-2026-46644
#3592382: Update Twig to v3.27.0
The drupal/core-recommended composer project was original added to pin Drupal's dependencies to known-good versions so that sites wouldn't accidentally update to minor versions that are incompatible with core, due to intentional or unintentional bc breaks to things core relies on. These incompatibilities do still happen, but at the moment it's at a much less frequent rate than off-schedule security releases attached to a new minor version.
A lot of Drupal users don't have deep composer familiarity, so the various workarounds for getting Drupal to install or update despite a vulnerable package have to be explained and learned all over again every time this happens. This is especially the case with Drupal CMS where composer is run via package_manager.
Steps to reproduce
Proposed resolution
Short term:
Remove the minor constraints from core-recommended for Symfony polyfills, Twig, and Guzzle
Longer term (perhaps in a follow-up issue):
Add a separate release process for core-recommended.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
drupal/core-recommended will no longer pin to minor versions of dependencies, so that security and other updates can be applied to sites without requiring a new Drupal core release.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3600889
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gábor hojtsyWould this have consequences for testing infratructure / matrix / setup on drupal.org? The recommended project is explained in its own readme as:
Comment #3
moshe weitzman commentedMakes sense to me as long as the core-recommended Git repo is archived, or otherwise marked as deprecated. Archived repos still function and no sites would be affected.
Comment #4
deviantintegral commented+1 on this. We're having discussions internally about adopting an ADR to always use drupal/core and never drupal/core-recommended due to how many times we've been blocked on these security upgrades. Improving this upstream would be much better.
Comment #5
longwave+1 to the general idea. This approach was fine until the sudden recent flurry of upstream security updates and I don't think those will decrease from here on in. And the problems that led us to this approach in the first place have largely been mitigated by removing the problematic dependencies altogether.
+1 to #3, we can still keep the namespace around and un-abandon it if we want to reintroduce something again in the future.
Comment #6
joelpittetWe all bought into the stability (even me who lives tends to live in -dev). I have always had a competing argument (with myself) that I’d rather have a broken site than a hacked site.
Supply-chain attacks slow my (addict level) updates down too.
I am on board with essentially moving back to Drupal/core but wonder if we can ~ the versions more (haven’t read the constraints yet, typing on phone) to let more patch releases through?
Comment #7
catchWhat I was thinking of was slightly different to #3. Uploading an MR that hopefully does that.
The idea is to keep core-recommended as a separate project template, but remove all the extra constraints. This way, if we want/need to add some constraints back later, we can do so without having to update documentation or anything else and people on core-recommended will automatically get that later.
On the other hand if we never do that, we can still deprecate/archive it later on and go only to drupal/core.
Fully expecting tests to fail, but hopefully in a way that shows the changes work, we'll find out. First time I've actually worked on one of these metapackage generators that I can remember.
@gábor hojtsy so we do have an updated dependencies pipeline on gitlab already, but it's pretty noisy and often ignored https://git.drupalcode.org/project/drupal/-/pipelines/849374 I think we need to change something but it probably needs its own issue to discuss and implement.
Comment #9
catchAlso - didn't make it explicit, but I think we should do this in 11.4.0 with a change record and release note, otherwise it's another year of pain ahead. We'll still have six months of 11.3.x and 10.6.x left to deal with, unless we take a decision to backport there too (something we can discuss after getting this into 11.x and probably 11.4).
Comment #11
catchComment #13
godotislateMRs look good, but I'll try to actually manually test tomorrow. Unless someone else RTBCs first.
Comment #14
catchComment #15
catchAdded a CR: https://www.drupal.org/node/3601304 and release notes snippet.
Comment #16
borisson_I like that this keeps the metapackage around since it doesn't require us to change all projects to remove core-recommended. That makes sense to me.
Comment #17
godotislateOK, manually tested with these steps:
composer -n create-project drupal/recommended-project:dev-main my-projectguzzlehttp/psr7 (2.10.4)composer update guzzlehttp/psr7 drupal/core-recommendedguzzlehttp/psr7can now update to2.11.0This RTBC +1 for me.
Edited: I also did a minor revision of the CR.
Comment #18
ressaThanks, this is great news and will make updates easier for casual Composer users. Adding issues as related, so that this issue is shown there as well.
Comment #19
longwave+1 for #9, let's initially ship this with 11.4.0 to remove the pain quicker.
Not yet sure about backporting to patch releases. Maybe if we don't hit anything unexpected in 11.4 and we get bitten by this again in some dependency in 11.3/10.6 then we could consider backporting at that point, given we'd be bumping dependencies anyway at that time.
Have not reviewed the MR or change record.
Comment #20
xjmI think this is incredibly hasty and not an appropriate release target for 11.4. I think if we wanted this in 11.4 it should have been decided like 3 months ago.
I am still not convinced we are not overreacting to the pain upstream is causing us and throwing the baby out with the bathwater. Like what is even the point of core-recommended without the minor constraints?
Comment #21
prudloff commentedI think this could also be solved by having better documentation/naming.
People probably use core-recommended because it is the recommended/better option but we should explain that there is no best option, it is a choice between stability and security.
We should make sure people using core-recommended are OK with waiting for a core release to apply some security patches (or overriding some constraints if needed).
Comment #22
joelpittet+1 @xjm and @prudloff in #20 and #21. It feels like an emotional reaction to the pain and better understanding of the choices (and workarounds/pain mitigations). Take a breath, sit with pain. Recall the breaking minor changes that needed a lot of work to untangle.
Comment #23
deviantintegral commentedFor our teams, I can see we've hit this class of issue 3 times since January. I think that's enough to warrant a change or improvement, whatever that is. From a new-to-Drupal (but not PHP) standpoint, I think the real confusion is that nearly all Drupal sites use drupal/recommended-project to start. If you review that composer.json you see broad constraints like ^11 you're likely to assume transient dependencies follow the same pattern, until you start work one day and everything is broken in your team's pipelines.
Given the core and Drupal CMS strategies, what if the spirit behind locking dependencies moved to Drupal CMS, leaving core free to follow Composer best practices and allow a wider set of versions?
Comment #24
catchThe current issues are arguably more of a problem for Drupal CMS sites because it's aimed at people who are less comfortable with composer - e.g. they're not expected to make a decision to switch from core-recommended to core, or allow-list CVEs temporarily, or necessarily to run composer from the cli at all. It's not even possible to install Drupal CMS at the moment.
We might decide to add constraints back at a later date, e.g. if Twig and Symfony start supporting older minor versions again, currently they're going backwards on that though. Or if a specific dependency causes more problems with non-security minor releases.
Or if not, we could deprecate it at a later date. But I don't think we need to decide that now, for me I'd leave it as it is in the MR to have the maximum amount of options later on.
Comment #25
solideogloria commentedI feel like a change or solution of some sort is warranted. AI is increasing the frequency of security updates in dependencies, and it's something we have to adapt to. It's incredibly frustrating when I run a composer command to update a module, but I get errors because some core dependency is vulnerable. I have to manually look up what the workaround is each time and add it, and then remove it later when it's fixed. This has happened for me 3-4 times in the last month, and I have to do it for each site I want to update anything on.
Comment #26
cmlaraThere is some sound logic there.
I'm not a fan of
core-recommended(I've suggested many times on Slack usedrupal/corefor flexibility) however it has for years had a defined purpose, tightly pin the release. I would not recommend changing that in a minor release, especially with near zero lead time to inform site owners.As a site owner (if I was using the package) I would hope for one of the following:
There is a significant of community documentation out there both on D.O. and not D.O. that needs to be considered as impacted by whatever decision is made here.
A good point, as I have seen a few times lately feel like knee jerk reactions.
Whatever the package future is I would suggest the core team should have that defined and documented for users. It should be clear to a site owner when and how it may be updated in the future and not a 'lets decide this later' if this change were to be adopted.
The team should likewise consider that any blocked upgrades will, no matter how the package is advertised, likely be expected to be remedied in short order, especially with a name containing "recommended", rebranding the package may be the teams best option.
To me that describes exactly why Drupal CMS should be responsible for locking requirements not core, they are intended to be the "hand holding" project, they can evaluate "is any recipe we include impacted" or "is any combination of 5 modules a threat vector for this flaw", they can make more controversial choices such as "lets de-register that class".
Drupal CMS is inherently an "opinionated" deployment, they can make these decisions that core can't/shouldn't.
Comment #27
godotislateguzzlehttp/psr7 has a new SA today and corresponding new minor release: https://github.com/guzzle/psr7/security/advisories/GHSA-vm85-hxw5-5432.
The SA has not yet hit Packagist, so composer isn't blocking installs yet, but presumably it will eventually.
#3603733: Update guzzlehttp/psr7 to 2.12.1 is issue on updating the package.
Comment #28
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #29
phenaproximaI had suggested in Slack that Drupal CMS could switch from depending on
drupal/core-recommendedto depending ondrupal/coredirectly. I think that would pretty much put these problems to bed for our target audience.However, I didn't want to do that without agreement from the core release management team. Drupal CMS can make these kinds of decisions, but we really shouldn't do it unless we're all on the same page. So I think there might still be some discussion needed before Drupal CMS makes this change, because if
core-recommendeddecides to loosen up, we don't need to change anything.And for the record, our strategy would not be to pin any core dependencies more tightly; we would be more likely to just let
drupal/core's dependency constraints do their thing, treating them the same way we already treat our normal contrib dependencies. We have found it very helpful that, when a contrib dependency has a security release, our official line has been "no worries, you're safe, we don't pin dependencies". I think that's best for end users and keeps friction and frustration to a minimum.Comment #30
steven jones commentedHow about a half-way between removing all the restrictions from
drupal/core-recommendedand staying as we are?For those dependencies where it's known that minor updates are likely to or have caused issues in the past because of how they are maintained or otherwise, like twig, those are kept pinned by core-recommended, but other dependencies that are more stable, aren't pinned.
As a user of
drupal/core-recommendedI very much appreciate that someone from the core team has reviewed and asserted that the new version of the dependency works with Drupal, and I very much appreciate that stability.Comment #31
catchThis is the problem though - Twig both releases minor updates that break things, and also does security releases in only minor releases, sometimes both at the same time (although tbh that's more excusable to accidentally break things when fixing a security issue). This is also to a fairly large extent the case for Symfony and Guzzle.
With Symfony the 11.x branch is on their LTS release as 11.2 goes out of support, so that will be better except the polyfills which have no release or support schedule. We have a problem on 12.x though that symfony minor releases are supported for 8 months while ours are supported for 12. Previously Symfony were prepared to backport fixes past EOL if we needed them, for the most recent one they were very resistant so we ended up doing a Symfony minor update on a security-only branch instead. It worked out OK in the end but it was a lot of fiddling about.
It would be easy to unpin the polyfills and leave everything else, but they were only one out of multiple SAs the past month.
Comment #32
catch@longwave's idea from slack.
Add a separate release process for core-recommended. When a dependency releases a security release, it would increase the constraints to include that dependency, but for regular minor releases, it wouldn't.
That would still prevent 'unnecessary' minor updates prior to core accounting for them, but would mean that people wouldn't be prevented from applying security updates in new minor releases as they have been for the past couple of months.
The downside to this is it's going to be a fair bit of work to set up, but I think we could initially relax the constraints as in this issue, then add that tooling/pipeline on top.
Comment #33
jurgenhaasWe've been avoiding
drupal/core-recommendedfor a long time without issues, but that's due to extensive e2e-pipelines that we run prior deployment. It's probably not a good path forward for the less technical users.However, the pain is real. And it's not just those DMCS users who are not really into the console, let alone composer.json. We've see many tech savy Drupal users in Slack and social media who really struggled with that stable-vs-security balance in the last few months. And there doesn't seem to be any sign that this is going away any time soon.
Changing the dependency from
drupal/core-recommendedtodrupal/corein project templates and in DMCS may be a solution for new installations in the future. But that leaves all existing installations still alone, feeling the pain, and getting frustrated with Drupal, although the issues comes from somewhere else.Therefore, keeping the recommended project and either remove the constraints or updating that project more frequently would be my preference. More frequent updates as mentioned in #32 sounds really tempting as it still goes through some vetting and users still get something that's recommended by the maintainers.
Comment #34
catchIn a slack convo @godotislate asked about version numbering of the more-frequently-updated recommended project.
I thought we could use the same numbering scheme but 'miss' numbers for actual core releases.
@godotislate suggested a four digit numbering scheme which I think is better. So today's release would have been 11.3.12.1 for recommended project.
Comment #35
nicxvan commentedI'd be in favor of this, getting around a single dependency is pretty straight forward, but the more recent one where there were two projects that needed the version as override that themselves had conflicts made it far harder to update.
It'd be good for recommended to know the minimum tested versions, e.g. don't go below x major.
Comment #36
lambert commentedPresumably at some point going forward ANY composer updates required will be added to the RELEASE page, exactly like this:
For example, from the enormous cascade of error messages when I ran the above, I need to do something about guzzle. But this:
is not actionable without doing a lot of detective work. This:
would be actionable, but that's not there.
The alert says "you should update immediately!"
Glad to, as I have been, if you give me the tools to do that. Same goes for updating composer.json and all the other suggestions for tweaks I saw floating about.
Comment #37
benjifisher+1 for the idea of more frequent releases of
drupal/core-recommendedand +1 for adding an extra component to the version string (as in Comments #32, #34).Famous last words: how hard can it be?
The generated repo for
drupal/core-recommendedis just one file (composer.json; two files, if you countREADME.mdin thedefaultandmasterbranches). So other changes to the main repo will have no effect: all that matters iscomposer/Metapackage/CoreRecommended/composer.json.All we need is a CI job, and it seems to me that the only questions are implementation details. For example: what triggers theCI job? Some possibilities:
11.3.12.1) is pushed to the repo. (Do we have to update other triggers to ignore 4-part tags?)composer/Metapackage/CoreRecommended/composer.json.If we want a simpler, short-term fix until that can be implemented, then I vote for relaxing the constraints on the known trouble makers:
twig/twig,guzzlehttp/*, maybesymfony/polyfill-*.Comment #39
catchYes now that we're only on LTS releases for Symfony on supported branches (for six months) those are the main problematic ones, at least so far.
I've added a new MR for that against main. If we think that's a good short term compromise happy to do 11.x and 11.4.x backports.
Comment #40
catchComment #41
benjifisherI left some comments on the MR. I see the issue status is already NW.
When the MR is updated and the tests still pass, I will re-review unless someone else does it first. If I set the status to RTBC, it will be with the understanding that the release managers still have to decide whether this short-term fix is a good idea.
Comment #43
quietone commentedTagging for a followup for this comment.
Comment #44
quietone commentedI updated the issue summary with the latest proposal.
I prefer this more nuanced approach than the more drastic, 'remove all constaints'. My concern remains communication and documentation. How will this change be communicated to sites so they understand what it means when updating, the risks and the advantages. And what about the README for core/recommended. How does this change that?
Comment #45
catchI think I addressed @benjifisher's review - sorted the list, fixed the guzzle typos.
I've marked the previous MRs draft so it's clearer which one to review. We'll need 11.x/11.4.x backport MRs but can do this once the approach is RTBCed/agreed.
Comment #46
catchI don't think it changes it much - a release note should be enough. It's certainly a lot less in terms of communication and documentation updates than if we have to tell everyone to use
drupal/corebecausedrupal/core-recommendedis unusable 3/4 weeks every month so we can't recommend core-recommended any more.Comment #47
benjifisherI reviewed the changes in MR !16151, and they match the Proposed resolution. Thanks to @quietone for updating that. (A refinement to that section: we are keeping the minor-version constraint for
guzzlehttp/promisesbut not the other twoguzzlehttppackages.)I had in mind sorting within each section. I see that the MR now sorts the entire list, which is at least as good.
For testing, I realize that
composer/Metapackage/CoreRecommended/composer.jsonis a generated file. In the top-levelcomposer.json, I see the following in thescriptssection:So I hacked that file, adding another line to the
scriptssection:Then I deleted
composer/Metapackage/CoreRecommended/composer.jsonand regenerated it withcomposer gmp. There were no changes.I now see how the hyphens in the Builder class are related to the two
guzzlepackages not being removed from the generatedcomposer.json. (See my comment on the MR, now resolved.)Comment #48
quietone commentedAnd here is the follow up, #3606820: Add a separate release process for core-recommended
Comment #49
quietone commentedI reviewed the change record and it was out of date. I have updated putting the change first and listing the affected dependencies. Back to NR for just that part.
Comment #50
quietone commentedThat is from @phenaproxima in Slack after reviewing the change record.
I have removed the duplicate line and nothing to do for the other item as we did pin to minor. Therefore restoring the RTBC
Comment #51
longwaveThe new approach looks good to me but there is a comment out of place and we will need a separate MR for 11.x as we should include the PHP 8.4/8.5 polyfills too (and also I am not sure the main MR will apply to those branches anyway).
Comment #52
catchI added guzzlehttp/promises into the list, and moved the comment to where it should be.
Comment #55
longwaveCommitted 0ed786c and pushed to main. Thanks!
Will commit the backport as soon as it's green.
Comment #62
longwaveCommitted and pushed 8db15f2346c to 11.x and e257fc7d212 to 11.4.x. Thanks!
Also published the change record.
Discussed with @catch whether to change the current approach to wildcards, because we will have to remember to update this in future if new transitive dependencies get added; it would be cleaner to be able to say
symfony/polyfill-*for example, but let's deal with that in a followup.