fix(scripts): flag allow rules for secrets read/delete in check-permissions #61
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/scripts/flag-secrets-read-delete-allow"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
Расширил
DANGEROUS_PATTERNSв.opencode/scripts/check-permissions.py— 16 новых паттернов, флагающихallowдля чтения/удаления/копирования/перемещения секретных файлов (.env*):cat/head/tail/less/more/grep(чтение),rm(удаление),cp/mv(копирование/перемещение) — паттерны^<cmd> .*\.env.git rm .env*,git -C * rm .env*— удаление секретов через git.ssh * cat .env*(чтение на remote),ssh * rm .env*(удаление на remote) — закрывает дыру, которую не покрывал existingssh * rm *(он ловит только черезdeny, аallowдляssh * rm .env*не флагался).docker exec * cat .env*,docker exec * rm .env*— секреты в контейнерах.Добавил 20 тест-кейсов в
tests/test_check_permissions.py:test_secrets_read_delete_pattern_violation(17 parametrized) — каждый новый паттерн флагается приallow.test_rm_rf_env_already_caught_by_existing_pattern— edge case:rm -rf .env*ловится existing^rm -rfпаттерном (приоритет existing), hole closed.test_secrets_deny_not_violation—deny/askдля секретов НЕ флагаются (контракт: толькоallow).test_docker_rm_still_allowed— 5 паттернов из PR #55 (docker rm *,docker system prune*,docker volume rm *,git push --force*,git push -f*) продолжают НЕ флагаться (инвариант).Отдельным коммитом: ruff format
tests/test_create_changelog_tool.py(pre-existing formatting issue, пришёл с main — блокировал create-pr gate).Почему
Линтер не флагал
allowдляrm .env*иcat .env*— прямая дыра безопасности (issue #57). Агент мог читать или удалять файлы секретов безask/deny. Обнаружено во время PR #55 при проверке, что линтер ловит реальные угрозы после ослабления для docker/force-push паттернов. Новые паттерны попадают в проверкуcheck_rules()автоматически (список расширен, функция не менялась). Scope"all"по умолчанию — секреты опасны везде (global + agents).Watch out
^<cmd> .*\.env(.envбез$), покрывая.env,.env.local,.env.productionчерез суффикс.rm -rf .env*ловится существующим паттерном^rm -rf(reason "recursive force delete"), не новым — это норма, hole закрыт обоими, приоритет у existing.cat */head*/tail*вopencode.json(global) и агентах НЕ флагаются — линтер проверяет точные ключи правил, а не резолвинг glob'ов; это по дизайну (агенты имеют broad allow для read-only операций, а.env*отдельноdeny/ask).opencode.jsonи агентах нетallowдля секретов (все.env*правила —deny/ask).Pending
—
Closes #57
Code Review Summary
PR добавляет 16 новых паттернов в
DANGEROUS_PATTERNS(check-permissions.py:100-114) для флагаallow-правил на чтение/удаление/копирование/перемещение секретных файлов.env*(локально, через git, ssh, docker exec) + 20 тест-кейсов. Закрывает реальную дыру безопасности (issue #57): до фиксаallowдляrm .env*/cat .env*не флагалось. Качество высокое, тесты покрывают каждый паттерн и edge cases.Positives
cat/head/tail/less/more/grep/rm/cp/mv), git (git rm,git -C * rm), ssh (ssh * cat,ssh * rm), docker (docker exec * cat,docker exec * rm) векторы. Regex^<cmd> .*\.envбез$корректно покрывает.env.local/.env.productionчерез суффикс.test_docker_rm_still_allowedявно проверяет 5 паттернов из PR #55 (docker rm *,docker system prune*,docker volume rm *,git push --force*,git push -f*) → 0 violations. Тест прошёл.rm -rf .env*покрыт отдельным тестом (test_rm_rf_env_already_caught_by_existing_pattern): ловится existing^rm -rf(приоритет first-match), hole закрыт обоими паттернами — корректно.allow-only сохранён:test_secrets_deny_not_violationпроверяет, чтоdeny/askдля секретов НЕ флагаются.test_check_permissions.py(uv run pytest). Линтер exit 0 на текущем конфиге подтверждёнtest_clean_configs_pass(subprocess black-box, returncode 0 + "OK" message) иtest_permissions.py::test_check_permissions_passes. CI green (pipeline-status).## Что сделано,## Почему,## Watch out,## Pending) заполнены осмысленно;## Pending=—(допустимо). Closes #57.check_rules15 строк (< 50),main21 строка. Новые паттерны — 2-элементные tuples (scope"all"по умолчанию черезentry[2] if len(entry) > 2), существующие agent-scoped — 3-элементные. Стиль консистентен.DANGEROUS_PATTERNS(writer) → readers:check_rules()(paired в PR, тот же файл),tests/test_check_permissions.py(paired в PR),tests/test_permissions.py::test_check_permissions_passes(black-box, не зависит от количества паттернов), CIpermissions-check.yml(запускает скрипт, не парсит список). Missing paired update нет.Suggestions (info, not blocking)
grep * .env*— паттерн с пробелом между*и.env*(соответствует regex^grep .*\.env). Покрыто, но стоит иметь в виду, чтоgrep .env*(без*) тоже матчится тем же regex — тест можно было бы расширить, но не критично.Verdict: APPROVE