pyupio / safety

Safety checks Python dependencies for known security vulnerabilities and suggests the proper remediations for vulnerabilities detected.
https://safetycli.com/product/safety-cli
MIT License
1.66k stars 141 forks source link

Enhancement: Environment Variable to Override USER_CONFIG_DIR #506

Open airpaio opened 4 months ago

airpaio commented 4 months ago

Description

When running the safety tool within a Docker container with a specified non-root user (using --user flag), the tool attempts to create a .safetydirectory in the root (/) directory, leading to a PermissionError. This issue arises because the tool tries to write to /.safety when it cannot determine the user's home directory correctly or when the user does not have a home directory set up within the container.

What I Did

We use a Gitlab Runner running on a linux EC2, and a Makefile to aggregate our pipeline scripts like safety scan. Here is a snippet of our setup:

.gitlab-ci.yml:

safety:
    stage: security
    script: |
        docker run \
        --volume $(pwd):/analytics \
        --user $(id -u):$(id -g) \
        --env PYUP_KEY=$PYUP_KEY \
        --workdir /analytics \
        --rm \
        sf-ingest:dev make securitycheck

Makefile:

securitycheck: ## Run security scans (safety)
    test -d logs || mkdir logs
    safety --key $$PYUP_KEY --stage production scan \
        --detailed-output --output screen > ./logs/safety.txt

The Gitlab Runner on the underlying host is running as user gitlab-runner with some random uid:gid, say 995:994. When the docker run command is executed by the Gitlab runner, the user 995:994 is not an actual user in the container and so it falls back to using the root directory, /, as the USER_CONFIG_DIR (/.safety) and causes the PermissionError.

...
  File "/usr/local/lib/python3.12/site-packages/safety/auth/cli_utils.py", line 189, in inner
    return func(ctx, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/safety/cli.py", line 76, in cli
    initializate_config_dirs()
  File "/usr/local/lib/python3.12/site-packages/safety/util.py", line 862, in initializate_config_dirs
    USER_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
  File "/usr/local/lib/python3.12/pathlib.py", line 1311, in mkdir
    os.mkdir(self, mode)
PermissionError: [Errno 13] Permission denied: '/.safety'

My Workaraound

It took some tinkering to find a solution that worked. Overriding HOME in our Makefile is what worked...

securitycheck: ## Run security scans (safety)
    test -d logs || mkdir logs
        echo "whoami = $$(whoami)"
    echo "uid:gid = $$(id -u):$$(id -g)"
    echo "HOME = $$(echo $$HOME)"
    export HOME=/tmp/safety; mkdir -p $$HOME; \
    safety --key $$PYUP_KEY --stage production scan \
        --detailed-output --output screen > ./logs/safety.txt && \
        rm -rf /tmp/safety

Proposed Solution

Introduce a new environment variable (e.g., SAFETY_USER_CONFIG_PATH, similar to what was done with SAFETY_SYSTEM_CONFIG_PATH) that allows users to specify the path for the .safety user config directory. This change would provide greater flexibility for running safety in containerized or constrained environments, where the user's home directory may not follow conventional setups or where permissions are restricted, and prevent the tool from defaulting to /.safety when the home directory is not appropriately set or writable.