Files

10 KiB

chguard Threat Model and Security Scope

chguard is a command-line systems administration tool. It is designed to be executed intentionally by an operator, sometimes with elevated privileges, to snapshot and restore filesystem ownership and permission metadata.

Because of that design, chguard's security model is different from that of a network service, web application, daemon, sandbox, or setuid program. chguard does not attempt to defend against arbitrary local compromise of the account executing it. If an attacker can control the command line, environment, working directory, PATH, selected database, installed Python package, or wrapped system command used by the operator, they may be able to influence what chguard does. That situation is considered a local trust-boundary failure outside chguard's intended security model.

chguard only manages filesystem metadata. It does not read, store, compare, restore, or protect file contents.

Core Assumptions

chguard assumes that the person running the tool understands what they are asking it to do.

In particular:

  • If chguard is run as root, the root user is assumed to control and understand the command line, environment, database path, restore root, and wrapped command being used.
  • If --db is used, the selected SQLite database path and its contents are assumed to be trusted local administrative state chosen by the operator.
  • If --root is used during restore, the alternate restore root is assumed to be intentionally selected by the operator.
  • If --yes is used, the operator is intentionally bypassing the interactive confirmation prompt.
  • Wrapper mode commands are assumed to be the trusted chown, chmod, or chgrp implementation that the operator intended to execute.
  • The operator is expected to understand the impact of restoring ownership and permission bits, especially when restoring as root.

What chguard Records

chguard snapshots a narrow set of filesystem metadata:

  • Relative path under the snapshot root.
  • Entry type: regular file, directory, or symbolic link.
  • Permission bits.
  • Numeric uid.
  • Numeric gid.

chguard deliberately does not snapshot:

  • File contents.
  • File hashes.
  • ACLs.
  • Extended attributes.
  • Capabilities.
  • SELinux, AppArmor, or other MAC labels.
  • Deleted files.
  • Newly created files.
  • Device nodes, sockets, FIFOs, or other special files.

User and group names are display-only. Numeric uid and gid values are the source of truth.

What Is In Scope

chguard tries to protect careful administrators from common and serious mistakes that can occur when a privileged CLI tool records and restores filesystem metadata.

In-scope security concerns include:

  • Restore must not create, delete, move, rename, or rewrite files.
  • Restore must not change file contents.
  • Restore must preview applicable owner and mode changes before applying them.
  • Mutating restore must require confirmation unless --yes is provided.
  • Mutating prune operations must require confirmation unless --yes is provided.
  • Preview and dry-run restore should remain usable without root.
  • chguard must not automatically run sudo or otherwise escalate privileges.
  • Scanning and restoring should use no-follow filesystem operations and avoid following symlink targets.
  • Restore should re-check current filesystem state before applying chmod or chown operations.
  • Restore should skip missing paths, unsupported file types, and type mismatches rather than replacing them.
  • Wrapper mode should stay limited to ownership and permission commands: chown, chmod, and chgrp.
  • Wrapper mode should not use a shell to execute the wrapped command.
  • SQLite access should use parameterized queries for operator-provided names and paths.
  • A state created by chguard through normal scanning should not contain relative paths that escape the snapshot root.

These measures are defense-in-depth. They are intended to reduce the chance of accidental metadata changes, symlink traversal, unintended privilege changes, or unsafe restore behavior when chguard is used normally by an administrator.

What Is Out Of Scope

The following are generally out of scope and should not be reported as chguard vulnerabilities unless they also bypass one of chguard's explicit hardening mechanisms:

  • A malicious local user who can already control the root user's command line, shell environment, working directory, PATH, Python environment, installed package, or invoked binaries.
  • A root user intentionally selecting a malicious or manually edited SQLite database with --db.
  • A root user intentionally restoring a snapshot that sets unsafe ownership or permissions.
  • A root user intentionally using --root to apply a trusted snapshot under a different filesystem tree.
  • A root user intentionally passing --yes and bypassing confirmation.
  • A user intentionally wrapping a malicious binary whose basename is chown, chmod, or chgrp.
  • A user relying on chguard to restore file contents, deleted files, ACLs, extended attributes, capabilities, MAC labels, or full undo semantics.
  • A user relying on chguard as a sandbox for untrusted local users or untrusted command execution.
  • A compromised system where an attacker already controls root-owned files, root's shell, root's Python packages, root's environment, or the privileged tools chguard invokes.
  • Reports that amount to "if root runs this tool with malicious options, root can make the system do dangerous things."

chguard is a tool for administrators, not a sandbox for hostile local users. It cannot make unsafe local trust decisions safe if the operator's own execution environment is already attacker-controlled.

Trusted Snapshot Databases

chguard snapshots are stored in a local SQLite database. By default, chguard uses the platform-specific user data directory for the invoking account. Operators may override this with --db.

Snapshot databases should be treated as trusted administrative state. They can contain filesystem paths, ownership, group, permission, timestamp, and snapshot root information. They do not contain file contents, but the metadata can still reveal operational details about a system.

Before running restore, especially as root or with --yes, the operator should be confident that the selected database is the intended one and has not been tampered with.

chguard-created snapshots are expected to contain paths relative to the snapshot root. chguard does not treat an arbitrary attacker-supplied SQLite database as untrusted input to be safely enforced.

Wrapper Mode

Wrapper mode exists to take an automatic pre-command snapshot before running a metadata-changing command:

chguard -- chmod 755 path
chguard -- chown user:group path
chguard -- chgrp group path

Wrapper mode is intentionally limited to chmod, chown, and chgrp by command basename. chguard snapshots existing non-option path arguments that it can identify, then runs the wrapped command and returns that command's exit code.

Wrapper mode is not a full parser for every possible option accepted by those commands. It is a guardrail for common ownership and permission changes, not a general command supervision framework.

chguard uses lstat() and no-follow operations while scanning and restoring. It records symbolic link entries and attempts no-follow ownership or permission restoration where the platform supports it. It should not follow a symbolic link target and apply changes to the target as part of scanning or restore.

Restore is best-effort across platforms. Some operations, such as changing symlink permissions, are not supported everywhere and may be skipped.

Because chguard operates on a live filesystem, concurrent filesystem changes can still affect what exists at the moment restore runs. chguard mitigates this by re-checking paths before applying changes and by skipping missing paths, special files, and type mismatches. It does not claim to provide a transactional filesystem restore.

Local Compromise

chguard includes hardening against some local filesystem attack patterns because it is often run with high privileges. For example, it avoids symlink traversal, does not use a shell for wrapper mode, previews restore changes, and does not automatically escalate privileges.

However, local compromise cannot be ruled out completely for a privileged CLI tool. If an attacker can influence the administrator's shell, environment, database, binaries, Python packages, current working directory, or command-line arguments, they may be able to influence chguard's behavior.

Such scenarios are treated as local compromise or operator trust failures, not as vulnerabilities in chguard by themselves.

Security Report Guidance

Useful vulnerability reports include issues where chguard behaves unsafely despite the documented trust model. Examples include:

  • chguard follows a symlink target during save or restore in a way that causes unintended privileged chmod or chown operations.
  • Restore creates, deletes, moves, renames, or rewrites files.
  • Restore applies owner or mode changes without previewing them first.
  • Restore applies changes without confirmation when --yes was not provided.
  • Dry-run or preview applies filesystem changes.
  • chguard automatically escalates privileges or invokes sudo.
  • A snapshot produced by normal chguard scanning can contain paths that escape the snapshot root during restore.
  • Wrapper mode accepts and executes unsupported command classes outside chown, chmod, or chgrp.
  • Wrapper mode introduces shell injection when running ordinary operator-provided path names or arguments.
  • SQLite operations allow operator-provided state names or paths to alter unintended database rows through injection.
  • A failed safety check is silently ignored and chguard proceeds with a dangerous operation anyway.

Less useful reports, and normally out of scope, include:

  • "Root can restore dangerous permissions."
  • "Root can pass --yes and bypass the confirmation prompt."
  • "Root can point --db at a malicious SQLite database."
  • "Root can use --root to restore metadata into a different tree."
  • "A malicious local user can compromise chguard after already controlling root's environment, Python packages, or binaries."
  • "chguard does not restore file contents, ACLs, xattrs, capabilities, or full deleted-file state."

Reports about concrete bypasses of chguard's hardening are welcome. The project does not treat intentional administrator-controlled execution as a vulnerability by itself.