Problem/Motivation
When you browse modules in project browser, the information about security coverage is displayed. Currently it seems like that this is a global information (based on a module), rather than information about the security coverage of the specific release/branch, which is going to be installed on a site by project browser. I have not found any place, where you can check which version of the specific module will be installed if you click so.
So it can happen, that for example Webform has the icon, that the project is covered, but you do not see a version and when you install it, you will get Webform 6.3.0-alpha2, which is not covered. And in addition with that you will end up with an alpha version of a module without even knowing that.
Installing a module without knowledge of the version seems risky and displaying the coverage status globally based on a fact if a module has at least one covered release/branch is misleading to the end user too. This has a potential to cause a lot of confusion for users and a false sense of security (there was an icon, so why I am not covered, etc..).
(I selected Webform as an example, but this can be even more risky on smaller modules)
I suppose we need to do two things:
- The most important - for each module displayed in PB (in the list/grid view and in a modal detail view), display a version, which is going to be installed
- Show the SA coverage icon based on the release/branch going to be installed, not globally (created an issue here: #3492209: Display SA coverage icon based on a release/branch of the module going to be installed)
I have added a Security tag and a Critical priority, as this have security implications.
Steps to reproduce
On Drupal 11.1RC:
Open project browser (/admin/modules/browse)
Find Webform module
Observe that there is a SA coverage icon displayed
Try to find a version, which is going to be installed if you click so - you will be unable to find it
Install Webform
Observe that Webform 6.3.0-alpha2 was installed, which is not covered by SA policy
Proposed resolution
I suppose we need to do two things:
- The most important - for each module displayed in PB (in the list/grid view and in a modal detail view), display a version, which is going to be installed
- Show the SA coverage icon based on the release/branch going to be installed, not globally (created an issue here: #3492209: Display SA coverage icon based on a release/branch of the module going to be installed)
Comments
Comment #2
poker10 commentedComment #3
greggles+1 to the proposed resolutions.
Comment #4
chrisfromredfinI have had a vision for a pre-or-post confirmation in the works, it would need some effort to get it implemented, and we'd need to know what's possible from Package Manager in order to display the confirmation, ex.g. It also may not be possible until half-way through the process before PM re-applies to the site.
Comment #5
catchThere seems to be two ways to tackle this:
Hmm this sounds like we want a human-readable version of the output from composer require drupal/whatever --dry-run
e.g. if I run this on 11.1.x:
I can't find an API method for this in package_manager, but it looks like one could be created out of StageBase::require() adding a --dry-run and skipping all the staging logic.
This would allow the version to be shown in any context in project_browser without having to create a staging directory first.
Related to this, does project_browser/package_manager respect a minimum stabiility flag? Ideally we'd make this configurable, default to stable releases only, then give people options if they try to install a release that doesn't have a compatible stable release.
Comment #6
chrisfromredfinYes, PM does the equivalent of `composer require drupal/some_project` so that's why we don't really know what package will be installed, because it specifically depends on Minimum Stability.
What is the minimum-stability set to in drupal/recommended-project? In institutional settings, I imagine a power user would set minimum-stability to their comfort level and users using PB would just click install, not caring about module versions. That's very much in our user world - I would be reticent to add more additional info to cards, and would be more inclined to support pre-or-post messaging to the user per #3343805: Add confirmation page when installing module or applying a recipe or #3348868: Show users what's changed on confirmation screen.
A pre-or-post confirmation screen also may relate to #3489665: Create a way to accept recipe input when applying one with Project Browser.
Comment #7
phenaproxima@chrisfromredfin asked me to reply to #5.
From Package Manager's perspective, we could pass a
--dry-runflag tocomposer require. The problem is that the output isn't really human-readable (and I'm not sure if it can be made machine-readable), and if Composer doesn't leave behind any artifacts for us to parse (for example, the lock file that would result from a real run), then I'm not sure we have anything we can produce a user-facing summary from.As for minimum-stability, Package Manager has no real opinion on that as far as I know. We just delegate to Composer. We could certainly supply stability flags to the
StageBase::require()method to override whatever the minimum-stability is, same as you could do withcomposer require.Comment #8
poker10 commented@chrisfromredfin - Was there any research done on this topic? From the security point of view, I do not think this will be a general practice. If we look at the Wordpress, you can see, that there is a plugin version displayed if you click on the plugin - so you are aware, what you are going to install. Modules can also have multiple branches, with some new features and/or BC breaks (so you will be affected even if minimum stability will be stable). Not saying that you can jump from security covered release to not covered (without even knowing that). This seems to me very important that users are aware, what is going to be installed.
And Drupal CMS set minimum stability to alpha (as of now), so that is even worse: #3493335: Change minimum-stability to stable for 1.0 release . And we are talking about non-dev users here.
Comment #9
catchYes this is the problem - if people install from composer templates that set minimum stability to something other than stable, which will be the case for any pre-release of a distribution like Drupal CMS (and maybe stable releases if the stability doesn't get raised before the release day), then they'll be defaulted to alpha or beta or rc without knowing about it. This might not be project browser's problem as such but the combination of the two seems very bad.
Comment #10
phenaproximaTo be clear, Drupal CMS does use a permissive
minimum-stability, but it also hasprefer-stableengaged, which I'd hope would mitigate the possibility of weirdness to some degree. But I do agree that the wider net Drupal CMS casts around its dependencies makes things slightly less predictable.Comment #11
catchI don't think this can be relied on.
For example Gin has never had a stable release, and it's quite likely that someone would want to install Gin with project_browser. If their minimum_stability is stable, they won't be able to do that, so they'll be searching how to install a release candidate.
Overall I think it's a good thing if there's some friction involved in that.
But assuming they figure out how to change their minimum stability globally, the next project they install could also be in permanent beta/rc and project browser will happily install it without them even realising it's not stable.
This makes sense.
If we got the release data from the d.o API instead (which I assume project browser actually uses), could we then cross-reference this against what the site has set for composer minimum stability?
This would also potentially pre-warn people when they're not going to be able to install the project then - not sure what the messaging looks like when project browser fails to install a project.
Comment #12
phenaproximaI think that might be doable. It'd be imperfect, since Composer is a bit of a black box, and the solving of transitive dependencies could affect what happens to higher-level dependencies, but at the very least we could probably give some kind of indication of what stability could be expected.
Comment #13
catchYeah I think we could probably detect when something will definitely not get installed, but not when it might be possible to install but its own dependencies cause it to be not-installable, especially given some of those could be non-Drupal projects from packagist etc. But if we can detect that a site is only allowing stable releases and a project only has non-stable releases, that would be a pretty clear not-going-to-install state and similarly with filtering down the list of possibly branches that might get installed.
Comment #14
phenaproximaTo be clear -- the site is only allowing stable releases in the absence of a stability flag to override that. Project Browser can install anything it wants regardless of the preferences in composer.json if it makes calls like
$installer->require(['drupal/webform:@alpha']);.If we do that, though, it's hard to say what will happen to the transitive/secondary dependencies. That's probably where the most risk lies, and that's why
--dry-runexists.Comment #15
catchTo do that, would it not need to know that webform:@beta didn't work first? I guess it could try with gradually decreasing levels of stability though?
Comment #16
catchComment #17
phenaproximaThis is a tough nut to crack, but it's not impossible. It's a very good use case for the
InstallStateservice.We could maybe do something like this:
InstallerController::require()route could return a JSON-encoded dump of InstallState, which would effectively tell the frontend what the sandbox looks like (i.e., what is going to be installed). Maybe a summary could be presented to power users at that time, in a modal, with the option to proceed or abort the installation.The tricky part of this is that we'd also need to cross-reference all of that with up-to-date information about every extension that might be installed. That would really be bad from a performance perspective. Ideally, the drupal.org JSON API would give us this information (assuming it doesn't already?), rather than forcing us to figure it out by fetching update manager XML.
Comment #18
phenaproximaI discussed this with @poker10 in Slack.
While I appreciate that we definitely do not want Composer to ever accidentally choose a non-covered version of a project, I feel fairly strongly that surfacing the incoming versions to our users is NOT the correct solution to this problem.
Why? Because, well...an incoming version number is probably utterly meaningless to most of Project Browser's intended audience. Unless a user is willing to research the specifics about an incoming version (and I think we can safely assume they won't)...what do we expect people to do with the information? I can't think of anything.
All this will do, I feel, is add friction to Project Browser, and reinforce the perception that you need a Ph.D. to use Drupal.
But as I said, the underlying motivation here seems legitimate. Composer has no concept of "not covered by security updates", so there is nothing to prevent it from choosing poorly.
What I would suggest instead is, internally, the
Installer::require()method should try to find a reasonable version constraint to give to Composer, basing that on inspecting the configuration in composer.json and cross-referencing that with metadata gleaned from the Update Manager module (which is a dependency of Package Manager). That way we can ensure we never allow non-covered versions. Another way to accomplish this would be to add aconflictsection to the sandboxed composer.json, which would explicitly disallow versions that the Update Manager module states are not covered by security advisories. And we can let Composer sort things out from there.I also don't think this is truly critical. It's a major thing, and potentially blocks a stable release of Project Browser (a decision I will leave to the maintainers), but I don't see any particular justification for critical.
Comment #19
catchAdding #3501826: Round 1.1: Test user understanding of the difference between Modules and Recipes as a related issue which indicates usability testing participants wanted more information about what will happen when installing a recipe (which installs modules) rather than less. That doesn't necessarily apply to version numbers of modules but it might.