fed8b2eed7
Build and push multi-arch DocsGPT Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Has been cancelled
Backend release / release (push) Has been cancelled
Bandit Security Scan / bandit_scan (push) Has been cancelled
Build and push multi-arch DocsGPT Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Has been cancelled
Build and push multi-arch DocsGPT Docker image / manifest (push) Has been cancelled
Build and push DocsGPT FE Docker image for development / build (linux/amd64, ubuntu-latest, amd64) (push) Has been cancelled
Build and push DocsGPT FE Docker image for development / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Has been cancelled
Build and push DocsGPT FE Docker image for development / manifest (push) Has been cancelled
Python linting / ruff (push) Has been cancelled
Run python tests with pytest / Run tests and count coverage (3.12) (push) Has been cancelled
React Widget Build / build (push) Has been cancelled
213 lines
5.3 KiB
Python
213 lines
5.3 KiB
Python
"""Tests for application.devices.denylist."""
|
|
|
|
from application.devices.denylist import check_denylist
|
|
|
|
|
|
def test_rm_rf_slash():
|
|
assert check_denylist("rm -rf /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_short_flag_order():
|
|
assert check_denylist("rm -fr /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_slash_star():
|
|
assert check_denylist("rm -rf /*") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_long_flags():
|
|
assert check_denylist("rm --recursive --force /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_no_preserve_root():
|
|
assert check_denylist("rm -rf --no-preserve-root /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_no_preserve_root_before_flags():
|
|
assert check_denylist("rm --no-preserve-root -rf /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_no_preserve_root_slash_star():
|
|
assert check_denylist("rm -rf --no-preserve-root /*") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_long_flags_with_no_preserve_root():
|
|
assert (
|
|
check_denylist("rm --recursive --no-preserve-root --force /")
|
|
== "rm -rf /"
|
|
)
|
|
|
|
|
|
def test_rm_separated_flags_r_then_f():
|
|
# ``rm -r -f /`` (flags as separate tokens) must still trip.
|
|
assert check_denylist("rm -r -f /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_separated_flags_f_then_r():
|
|
assert check_denylist("rm -f -r /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rfv_bundle_root():
|
|
assert check_denylist("rm -rfv /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_short_recursive_long_force():
|
|
assert check_denylist("rm -r --force /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_long_recursive_short_force_slash_star():
|
|
assert check_denylist("rm --recursive -f /*") == "rm -rf /"
|
|
|
|
|
|
def test_rm_rf_tmp_subpath_safe():
|
|
assert check_denylist("rm -rf /tmp/foo") is None
|
|
|
|
|
|
def test_rm_rf_relative_build_safe():
|
|
assert check_denylist("rm -rf ./build") is None
|
|
|
|
|
|
def test_rm_rf_home_subpath_safe():
|
|
assert check_denylist("rm -rf /home/x") is None
|
|
|
|
|
|
def test_rm_recursive_only_safe():
|
|
# Recursive without force isn't the catastrophic root-wipe form.
|
|
assert check_denylist("rm -r /tmp") is None
|
|
|
|
|
|
def test_rm_force_only_slash_safe():
|
|
# Force without recursive (``rm -f /``) fails on a non-empty dir; not denied.
|
|
assert check_denylist("rm -f /") is None
|
|
|
|
|
|
def test_rm_force_only_etc_safe():
|
|
# Force without recursive on a real path is not the root-wipe form.
|
|
assert check_denylist("rm -f /etc/hosts") is None
|
|
|
|
|
|
def test_rm_separated_flags_subpath_safe():
|
|
# Separated recursive+force on a subpath stays safe.
|
|
assert check_denylist("rm -r -f /tmp/x") is None
|
|
|
|
|
|
def test_rm_wrapped_timeout_separated_flags():
|
|
# ``timeout 5 rm -r -f /`` — wrapper + separated flags must still trip.
|
|
assert check_denylist("timeout 5 rm -r -f /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_wrapped_nice_separated_flags():
|
|
assert check_denylist("nice rm -f -r /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_wrapped_nohup_bundle():
|
|
assert check_denylist("nohup rm -rf /") == "rm -rf /"
|
|
|
|
|
|
def test_rm_wrapped_timeout_duration_slash_star():
|
|
# ``timeout 30s rm -rf /*`` — duration token skipped, root-star target.
|
|
assert check_denylist("timeout 30s rm -rf /*") == "rm -rf /"
|
|
|
|
|
|
def test_wrapped_safe_ls_not_denied():
|
|
# ``timeout 5 ls`` is harmless even though it's wrapped.
|
|
assert check_denylist("timeout 5 ls") is None
|
|
|
|
|
|
def test_wrapped_rm_subpath_safe():
|
|
# ``nice rm -rf /tmp/foo`` is a subpath wipe; stays safe.
|
|
assert check_denylist("nice rm -rf /tmp/foo") is None
|
|
|
|
|
|
def test_rm_rf_home_tilde():
|
|
assert check_denylist("rm -rf ~") == "rm -rf ~"
|
|
|
|
|
|
def test_rm_rf_home_var():
|
|
assert check_denylist("rm -rf $HOME") == "rm -rf $HOME"
|
|
|
|
|
|
def test_fork_bomb():
|
|
assert check_denylist(":(){:|:&};:") == "fork bomb"
|
|
|
|
|
|
def test_fork_bomb_with_spaces():
|
|
assert check_denylist(":(){ :|:& };:") == "fork bomb"
|
|
|
|
|
|
def test_dd_to_block_device():
|
|
assert (
|
|
check_denylist("dd if=/dev/zero of=/dev/sda")
|
|
== "dd to block device"
|
|
)
|
|
|
|
|
|
def test_dd_with_random_to_nvme():
|
|
assert (
|
|
check_denylist("dd if=/dev/random of=/dev/nvme0n1")
|
|
== "dd to block device"
|
|
)
|
|
|
|
|
|
def test_mkfs():
|
|
assert check_denylist("mkfs.ext4 /dev/sda1") == "mkfs"
|
|
|
|
|
|
def test_mkfs_bare():
|
|
assert check_denylist("mkfs /dev/sda1") == "mkfs"
|
|
|
|
|
|
def test_shutdown():
|
|
assert check_denylist("shutdown -h now") == "shutdown"
|
|
|
|
|
|
def test_halt():
|
|
assert check_denylist("halt") == "halt"
|
|
|
|
|
|
def test_poweroff():
|
|
assert check_denylist("poweroff") == "poweroff"
|
|
|
|
|
|
def test_init_0():
|
|
assert check_denylist("init 0") == "init 0/6"
|
|
|
|
|
|
def test_init_6():
|
|
assert check_denylist("init 6") == "init 0/6"
|
|
|
|
|
|
def test_init_other_levels_safe():
|
|
# ``init 3`` shouldn't trigger.
|
|
assert check_denylist("init 3") is None
|
|
|
|
|
|
def test_git_push_force_long():
|
|
assert check_denylist("git push --force origin main") == "git push --force"
|
|
|
|
|
|
def test_git_push_force_with_lease_safe():
|
|
# --force-with-lease is allowed.
|
|
assert check_denylist("git push --force-with-lease origin main") is None
|
|
|
|
|
|
def test_git_push_short_flag():
|
|
assert check_denylist("git push -f origin main") == "git push --force"
|
|
|
|
|
|
def test_git_push_mirror():
|
|
assert check_denylist("git push --mirror origin") == "git push --force"
|
|
|
|
|
|
def test_safe_command_no_match():
|
|
assert check_denylist("ls -la /tmp") is None
|
|
|
|
|
|
def test_compound_with_dangerous_segment():
|
|
# ``echo safe && rm -rf /`` must still trip.
|
|
assert check_denylist("echo safe && rm -rf /") == "rm -rf /"
|
|
|
|
|
|
def test_empty_command():
|
|
assert check_denylist("") is None
|