Merge pull request #61 from 0xbyt4/fix/write-deny-macos-symlink
fix: resolve symlink bypass in write deny list on macOS
This commit is contained in:
83
tests/tools/test_write_deny.py
Normal file
83
tests/tools/test_write_deny.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""Tests for _is_write_denied() — verifies deny list blocks sensitive paths on all platforms."""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
from tools.file_operations import _is_write_denied
|
||||
|
||||
|
||||
class TestWriteDenyExactPaths:
|
||||
def test_etc_shadow(self):
|
||||
assert _is_write_denied("/etc/shadow") is True
|
||||
|
||||
def test_etc_passwd(self):
|
||||
assert _is_write_denied("/etc/passwd") is True
|
||||
|
||||
def test_etc_sudoers(self):
|
||||
assert _is_write_denied("/etc/sudoers") is True
|
||||
|
||||
def test_ssh_authorized_keys(self):
|
||||
assert _is_write_denied("~/.ssh/authorized_keys") is True
|
||||
|
||||
def test_ssh_id_rsa(self):
|
||||
path = os.path.join(str(Path.home()), ".ssh", "id_rsa")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_ssh_id_ed25519(self):
|
||||
path = os.path.join(str(Path.home()), ".ssh", "id_ed25519")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_netrc(self):
|
||||
path = os.path.join(str(Path.home()), ".netrc")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_hermes_env(self):
|
||||
path = os.path.join(str(Path.home()), ".hermes", ".env")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_shell_profiles(self):
|
||||
home = str(Path.home())
|
||||
for name in [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile"]:
|
||||
assert _is_write_denied(os.path.join(home, name)) is True, f"{name} should be denied"
|
||||
|
||||
def test_package_manager_configs(self):
|
||||
home = str(Path.home())
|
||||
for name in [".npmrc", ".pypirc", ".pgpass"]:
|
||||
assert _is_write_denied(os.path.join(home, name)) is True, f"{name} should be denied"
|
||||
|
||||
|
||||
class TestWriteDenyPrefixes:
|
||||
def test_ssh_prefix(self):
|
||||
path = os.path.join(str(Path.home()), ".ssh", "some_key")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_aws_prefix(self):
|
||||
path = os.path.join(str(Path.home()), ".aws", "credentials")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_gnupg_prefix(self):
|
||||
path = os.path.join(str(Path.home()), ".gnupg", "secring.gpg")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_kube_prefix(self):
|
||||
path = os.path.join(str(Path.home()), ".kube", "config")
|
||||
assert _is_write_denied(path) is True
|
||||
|
||||
def test_sudoers_d_prefix(self):
|
||||
assert _is_write_denied("/etc/sudoers.d/custom") is True
|
||||
|
||||
def test_systemd_prefix(self):
|
||||
assert _is_write_denied("/etc/systemd/system/evil.service") is True
|
||||
|
||||
|
||||
class TestWriteAllowed:
|
||||
def test_tmp_file(self):
|
||||
assert _is_write_denied("/tmp/safe_file.txt") is False
|
||||
|
||||
def test_project_file(self):
|
||||
assert _is_write_denied("/home/user/project/main.py") is False
|
||||
|
||||
def test_hermes_config_not_env(self):
|
||||
path = os.path.join(str(Path.home()), ".hermes", "config.yaml")
|
||||
assert _is_write_denied(path) is False
|
||||
@@ -42,32 +42,36 @@ from pathlib import Path
|
||||
_HOME = str(Path.home())
|
||||
|
||||
WRITE_DENIED_PATHS = {
|
||||
os.path.join(_HOME, ".ssh", "authorized_keys"),
|
||||
os.path.join(_HOME, ".ssh", "id_rsa"),
|
||||
os.path.join(_HOME, ".ssh", "id_ed25519"),
|
||||
os.path.join(_HOME, ".ssh", "config"),
|
||||
os.path.join(_HOME, ".hermes", ".env"),
|
||||
os.path.join(_HOME, ".bashrc"),
|
||||
os.path.join(_HOME, ".zshrc"),
|
||||
os.path.join(_HOME, ".profile"),
|
||||
os.path.join(_HOME, ".bash_profile"),
|
||||
os.path.join(_HOME, ".zprofile"),
|
||||
os.path.join(_HOME, ".netrc"),
|
||||
os.path.join(_HOME, ".pgpass"),
|
||||
os.path.join(_HOME, ".npmrc"),
|
||||
os.path.join(_HOME, ".pypirc"),
|
||||
"/etc/sudoers",
|
||||
"/etc/passwd",
|
||||
"/etc/shadow",
|
||||
os.path.realpath(p) for p in [
|
||||
os.path.join(_HOME, ".ssh", "authorized_keys"),
|
||||
os.path.join(_HOME, ".ssh", "id_rsa"),
|
||||
os.path.join(_HOME, ".ssh", "id_ed25519"),
|
||||
os.path.join(_HOME, ".ssh", "config"),
|
||||
os.path.join(_HOME, ".hermes", ".env"),
|
||||
os.path.join(_HOME, ".bashrc"),
|
||||
os.path.join(_HOME, ".zshrc"),
|
||||
os.path.join(_HOME, ".profile"),
|
||||
os.path.join(_HOME, ".bash_profile"),
|
||||
os.path.join(_HOME, ".zprofile"),
|
||||
os.path.join(_HOME, ".netrc"),
|
||||
os.path.join(_HOME, ".pgpass"),
|
||||
os.path.join(_HOME, ".npmrc"),
|
||||
os.path.join(_HOME, ".pypirc"),
|
||||
"/etc/sudoers",
|
||||
"/etc/passwd",
|
||||
"/etc/shadow",
|
||||
]
|
||||
}
|
||||
|
||||
WRITE_DENIED_PREFIXES = [
|
||||
os.path.join(_HOME, ".ssh") + os.sep,
|
||||
os.path.join(_HOME, ".aws") + os.sep,
|
||||
os.path.join(_HOME, ".gnupg") + os.sep,
|
||||
os.path.join(_HOME, ".kube") + os.sep,
|
||||
"/etc/sudoers.d" + os.sep,
|
||||
"/etc/systemd" + os.sep,
|
||||
os.path.realpath(p) + os.sep for p in [
|
||||
os.path.join(_HOME, ".ssh"),
|
||||
os.path.join(_HOME, ".aws"),
|
||||
os.path.join(_HOME, ".gnupg"),
|
||||
os.path.join(_HOME, ".kube"),
|
||||
"/etc/sudoers.d",
|
||||
"/etc/systemd",
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user