ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
814 stars 1.49k forks source link

composer: Warn users about running composer as root, based on upstream warning #2388

Open gangelop opened 3 years ago

gangelop commented 3 years ago

Summary

Issue Type

Bug Report

Component Name

composer

Ansible Version

$ ansible --version
ansible 2.10.8
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/george/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  executable location = /bin/ansible
  python version = 3.9.4 (default, Apr 20 2021, 15:51:38) [GCC 10.2.0]

Configuration

$ ansible-config dump --only-changed

OS / Environment

Any

Steps to Reproduce

Run this playbook with root privilege escalation (as you normally would).

---
- hosts: gombuter
  gather_facts: false
  tasks:
    - name: reproducer
      composer:
        working_dir: /opt/gomboser

Expected Results

I expect to receive a warning re-stating the upstream warning about running composer as root.

Actual Results

Actual results at the time of writing: the task hangs indefinitely because of an interactive root warning prompt by composer. Actual results with #2348 merged: the task will succeed without warning about the potential security issue.

Code of Conduct

ansibullbot commented 3 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 3 years ago

cc @dmtrs @resmo click here for bot help

felixfontein commented 3 years ago

This should definitely be documented. I'm not sure whether the module should re-create the composer warning (which would be necessary to show it to the user).

gangelop commented 3 years ago

This should definitely be documented. I'm not sure whether the module should re-create the composer warning (which would be necessary to show it to the user).

What's the alternative? Failure requiring a "force" option in the task?

gangelop commented 3 years ago

ok, I have two questions:

felixfontein commented 3 years ago
* If composer allows third-party packages to execute arbitrary code, then those packages can also attempt to use `sudo` or whatever other escalation method ansible uses. Wouldn't that mean that even running it as a non-root user, but with the capability of privilege escalation, would still be unsafe?

If sudo does not need a password, yes. You could also use become: true with become_user set to a user which cannot do passwordless sudo though.

* Do other packagers suffer from this same issue? For example, does `npm` allow packagers to execute arbitrary code?

I think both npm and pip (setup.py is executed) have the same problem (they do not have such a warning, or I never noticed). Other package managers such as apt or pacman do not.

felixfontein commented 3 years ago

This should definitely be documented. I'm not sure whether the module should re-create the composer warning (which would be necessary to show it to the user).

What's the alternative? Failure requiring a "force" option in the task?

I think there are three alternatives:

  1. Make sure it just works.

  2. Make sure it works, but emit a warning. (The module needs extra code to determine whether the warning needs to be emitted.)

  3. Make sure it fails, but allow to overwrite. (Also needs that extra code.)

  4. would be a breaking change, since that interactive warning wasn't there always, so this changes behavior for people using older composer versions. 1. would be the minimal fix for this issue (and definitely should come with updated documentation). 2. could be a preparation for 3. (i.e. add a new option to force running, and show a deprecation warning when used with root without that option with the message that this will change to fail in the future).

gangelop commented 3 years ago

fyi, I just learned in https://github.com/composer/composer/issues/9860 that composer has COMPOSER_ALLOW_SUPERUSER

gangelop commented 3 years ago

I think both npm and pip (setup.py is executed) have the same problem (they do not have such a warning, or I never noticed). Other package managers such as apt or pacman do not.

Actually, I think post_install scripts in pacman can execute anything they like as root. But an OS package manager has a different security model and trust assumptions than a language library manager. And generally, when I run pacman -S $pkg I could be installing anything from an icon pack to a kernel module (i.e. a rootkit) and there's never a distinction made between the two. So the assumption is that I trust all OS packages ultimately.

But the reason I asked about npm compared to composer is because I noticed that npm handles the resulting directory permissions differently. This might not be related to the main question of whether or not they all allow arbitary code execution. It's just something I noticed.

ubuntu@ubuntu:/opt/aylmao$ whoami
ubuntu
ubuntu@ubuntu:/opt/aylmao$ ls -la
total 16
drwxr-xr-x 2 bob  bob  4096 May  1 16:30 .
drwxr-xr-x 4 root root 4096 May  1 16:22 ..
-rw-rw-r-- 1 bob  bob   730 May  1 16:29 package-lock.json
-rw-rw-r-- 1 bob  bob    51 May  1 16:24 package.json
ubuntu@ubuntu:/opt/aylmao$ sudo whoami
root
ubuntu@ubuntu:/opt/aylmao$ sudo npm install

added 1 package, and audited 2 packages in 2s

found 0 vulnerabilities
ubuntu@ubuntu:/opt/aylmao$ ls -la
total 20
drwxr-xr-x 3 bob  bob  4096 May  1 16:31 .
drwxr-xr-x 4 root root 4096 May  1 16:22 ..
drwxr-xr-x 3 bob  bob  4096 May  1 16:31 node_modules     # <= OWNED BY PARENT DIR USER:GROUP
-rw-rw-r-- 1 bob  bob   730 May  1 16:31 package-lock.json
-rw-rw-r-- 1 bob  bob    51 May  1 16:24 package.json
ubuntu@ubuntu:/opt/aylmao$ 
ubuntu@ubuntu:/opt/gomboser$ whoami
ubuntu
ubuntu@ubuntu:/opt/gomboser$ ls -la
total 36
drwxr-xr-x 2 bob  bob   4096 May  1 16:30 .
drwxr-xr-x 4 root root  4096 May  1 16:22 ..
-rw-rw-r-- 1 bob  bob     27 May  1 10:56 composer.json
-rw-rw-r-- 1 bob  bob     62 Apr 30 17:08 composer.json.bak
-rw-rw-r-- 1 bob  bob  16555 Apr 30 17:08 composer.lock
ubuntu@ubuntu:/opt/gomboser$ sudo whoami
root
ubuntu@ubuntu:/opt/gomboser$ sudo php /usr/local/bin/composer install -n
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`.
Package operations: 6 installs, 0 updates, 0 removals
  - Installing symfony/polyfill-php80 (v1.22.1): Extracting archive
  - Installing symfony/polyfill-mbstring (v1.22.1): Extracting archive
  - Installing symfony/polyfill-ctype (v1.22.1): Extracting archive
  - Installing phpoption/phpoption (1.7.5): Extracting archive
  - Installing graham-campbell/result-type (v1.0.1): Extracting archive
  - Installing vlucas/phpdotenv (v5.3.0): Extracting archive
Generating autoload files
6 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
ubuntu@ubuntu:/opt/gomboser$ ls -la
total 40
drwxr-xr-x 3 bob  bob   4096 May  1 16:33 .
drwxr-xr-x 4 root root  4096 May  1 16:22 ..
-rw-rw-r-- 1 bob  bob     27 May  1 10:56 composer.json
-rw-rw-r-- 1 bob  bob     62 Apr 30 17:08 composer.json.bak
-rw-rw-r-- 1 bob  bob  16555 Apr 30 17:08 composer.lock
drwxr-xr-x 7 root root  4096 May  1 16:33 vendor            # <= OWNED BY root!
ubuntu@ubuntu:/opt/gomboser$ 
gangelop commented 3 years ago

Also dropping this here for my own reference: https://stackoverflow.com/questions/4938592/how-why-does-npm-recommend-not-running-as-root

ansibullbot commented 1 year ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help