github kenryu42/cc-safety-net v2.6.0

2 hours ago

This release adds Factory Droid and Devin CLI protection, and makes shell analysis see destructive commands that were previously hidden inside ${...} parameter expansions.

Highlights

  • Added protection for Factory Droid and Devin CLI, including hook installation, doctor reporting, and built-in rules for their credential and config files. (#197, #198, #200)
  • Commands hidden inside a ${...} parameter expansion are now analyzed instead of skipped, so echo ${x:-$(rm -rf ~/)} is blocked. (#214)
  • Fixed false blocks on URL query text, so requests such as curl 'https://example.com/todos?order=id.asc' are no longer treated as reads of a sensitive .asc file. (#217)

Added

  • Added Factory Droid support with cc-safety-net install --droid, the -fd/--droid hook flags, and a managed PreToolUse entry in ~/.factory/hooks.json. (#198)
  • Added Devin CLI support with cc-safety-net install --devin, the -dv/--devin hook flags, and a managed PreToolUse entry in the user config ($XDG_CONFIG_HOME/devin/config.json, or %APPDATA%\devin\config.json on Windows). Comments in Devin's config.json are accepted. The adapter also analyzes the text sent by write_to_process. (#200)
  • Added built-in secret rules for Factory Droid credentials (~/.factory/auth.encrypted, auth.v2.file, auth.v2.key, auth.v2.loginkeychain) and config (~/.factory/settings.json, hooks.json, mcp.json, and a project .factory/mcp.json), and for Devin CLI credentials (~/.local/share/devin/credentials.toml, ~/.local/share/devin/mcp/oauth) and config (~/.config/devin/config.json). Relocations through XDG_DATA_HOME and XDG_CONFIG_HOME are honored. (#197)
  • Added sensitive-path checks for the folder and patterns inputs of glob tools, so a glob over a credential directory is blocked. (#198)

Changed

  • Shell analysis now refuses, at every safety level, constructs whose real meaning cannot be determined: ${ list; } function substitutions (including inside heredoc bodies, across line continuations, and when the parser's depth limit cuts them off), a backslash escape inside backticks, an unclosed ${, and a quote, backslash, or line continuation inside ${ } next to a substitution. Such a command is reported as unanalyzable and denied rather than allowed. (#211, #214)
  • shell: "posix" in the OpenCode plugin now accepts any shell that runs POSIX sh syntax, such as ash or mksh, by running a short probe through <shell> -c once per executable instead of matching a list of shell names. cmd.exe, fish, nushell, and tcsh are still rejected, and the probe ends at a 10-second deadline. (#209)
  • Atomic config writes now keep the replaced file's permission bits instead of resetting them to the default. (#198)

Fixed

  • Fixed destructive commands being skipped inside a ${...} parameter-expansion operand, a substitution glued to a variable in double quotes (echo "$x$(rm -rf ~/)"), and a double-quoted arithmetic substitution. (#214, #215)
  • Fixed strict-mode denials of commands that are in fact analyzable: each nested command substitution now tracks its own quote state, so echo $(dirname "$(command -v node)") and echo $(printf "x'$(git status)'y") are allowed instead of refused as unparseable. (#215)
  • Fixed built-in extension rules such as .pem and .asc matching URL query text. A word holding a query parameter (?key= or &key=) that names no existing file, and the value after a query's =, are no longer read as paths; a file that really has such a name stays protected. A curl -d, --data, --data-ascii, --data-binary, --data-urlencode, -F, or --form value is now checked only as the @file or <file upload it names. (#217)
  • Fixed the user policy being read as a project policy when a command runs from the home directory. policy check and policy apply now refuse and point to --global, rule write subcommands refuse, rule migrate skips the project scope, the policy GUI refuses to use the user policy as a project draft, and policy loading no longer counts the user policy twice. Symlinked home directories are matched as well. (#201, #202, #203, #205)
  • Fixed uninstall --droid deleting ~/.factory/hooks.json while ~/.factory/settings.json exists, which would have let the hooks in settings.json load again, and doctor now reports a managed Droid hook narrowed by commandRegex. (#198)

Don't miss a new cc-safety-net release

NewReleases is sending notifications on new releases.