Allow package_manager to work with non-web-writable directory permissions

Created on 2 June 2025, about 1 month ago

Problem/Motivation

Package manager currently requires code directories to be writable by the webserver. This creates a larger attack surface than we would otherwise like - e.g. if someone is able to upload a .php file to a web-accessible directory, or even worse, overwrite an existing file, it could result in RCE.

There are currently two main ways that package_manager currently gets invoked:

1. Something in the web interface (project browser or automatic updates) triggers a composer command directly.
2. Something on cron triggers a composer command, usually automatic updates. Issues related to this are πŸ“Œ Create documentation for using the auto-update terminal command Active and πŸ“Œ Create documentation for using the auto-update terminal command Active .

I'm wondering if package_manager could provide a mode where it doesn't require web-writable directories, instead, only the cli would need write access.

With this mode, sites could set up cron-based unattended updates (e.g. for updating to security releases quickly) without allowing any other package_manager operations on a site.

We could potentially allow attended updates and project browser operations to run via cron too - e.g. add the commands to a queue from the UI, have a fairly frequent queue runner set to run on cron, set something in state when the items are completed, and notify the admin on the front end when it's done.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component

package_manager.module

Created by

πŸ‡¬πŸ‡§United Kingdom catch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @catch
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    At least?

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    How 'bout this:

    What if Package Manager maintained a setting, maybe something like package_manager_allow_sapi, that can either be * (default; any server interface is allowed to write) or an array of possible values for PHP_SAPI, like ['cli', 'cgi-fcgi']?

    Then WritableFilesystemValidator could confirm that, if that setting is an array, the current PHP_SAPI is in the allow-list before confirming that the directories it needs to write to, are in fact writable.

    This would be pretty easy to implement, if it sounds like a reasonable way to approach this. A site owner could set $settings['package_manager_allow_sapi'] = 'cli'; to only allow Package Manager to write the site if the operation is taking place at the command line.

  • πŸ‡¬πŸ‡§United Kingdom catch

    That could work.

    Where do you think queued operations should live? E.g. if package manager is set to only allow cli operations, but project browser allows to queue operations in the UI to then run via cron, is that queue entirely controlled by project browser or should it be putting things in a queue owned by package manager?

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    We could potentially allow attended updates and project browser operations to run via cron too - e.g. add the commands to a queue from the UI, have a fairly frequent queue runner set to run on cron

    I'm not sure we'd want to queue up Project Browser operations -- or, indeed, any attended operation -- to run on cron -- that seems like it would fly in the face of user expectations about how this works. If someone hits the install button, we probably don't want to send back a message like "Great! This will be installed the next time cron runs [which, by the way, we don't know when that will be because that's a system-level thing we have no insight into]".

    How do you envision it working for end users? What am I missing here?

  • πŸ‡¬πŸ‡§United Kingdom catch

    It would have to be something that was explicitly set-up on sites:

    1. A cron job on the server-side that runs either Drupal cron or a specific drush command etc. that will run the queue. If/when we have Drupal able to run in frankenphp's worker mode it wouldn't need to be cron any more, could be a daemon.

    2. Putting project browser/automatic updates into a cli-only mode that queues for running on cli. It set a flag when it puts something in the queue and clear it when the queue is emptied so that it can show an 'x operation is queued' message in the meantime.

    This is for people that would like to be able to use the UI, but are concerned about letting the webserver write code and would be prepared to follow the instructions to set it up like this.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    That seems quite a bit more complicated, and I guess I'm still not clear on the benefits of an approach like that compared to simply uninstalling Package Manager in the production environment, and only using Automatic Updates or Project Browser locally.

    I think it's sort of an inescapable thing that if you want to do Package Manager stuff in the UI, the UI needs write access. Automatic unattended updates are a little different because they intuitively make sense as a cron job, but attended operations are UI-facing by definition, and demand immediate feedback.

    Unless the UI has a reliable way to start a process as another user, which would itself be a massive security hole, I don't see any easy way out of this catch-22 (no pun intended).

    The only way I can see out of this is, like, being able to signal the system to run a queue-processing operation as another user with write access. Sort of an IPC-like thing. But I don't know of any mechanisms that would work for this.

  • πŸ‡¬πŸ‡§United Kingdom catch

    I guess you could set up a second cron job, that runs much more frequently (like every 30 seconds), and processes the queue. We can never expect non-technical users to take that path, but it doesn't sound like you're aiming at non-technical people with this idea.

    Yes something like this. Not really non-technical people - the broad idea would either be Drupal devs trying to run a small site (personal blog, community site etc.) or technical-but-not-Drupal people (someone making a website for their indie game, this sort of thing).

Production build 0.71.5 2024