Skip to content

Harden untrusted input at process, file, and protocol boundaries - #757

Open
SnaetWarre wants to merge 6 commits into
athasdev:mainfrom
SnaetWarre:security-hardening
Open

SnaetWarre wants to merge 6 commits into
athasdev:mainfrom
SnaetWarre:security-hardening

Conversation

@SnaetWarre

Copy link
Copy Markdown
Contributor

Untrusted input reaches process spawns, filesystem writes, and
protocol readers across several trust boundaries with only shape
checks in between. A malicious extension, workspace, or server can
turn that into code execution, credential theft, or backend OOM.

This closes the paths in six focused commits: verified extension
downloads, shell-free tool configs, capped protocol frames, quoted
debugger and terminal inputs, workspace-confined agents, and
credential-safe connection handling.

  • How to test:
  1. bun check:rust (clean, including clippy and fmt)
  2. cargo test -p athas-extensions -p athas-debugger -p athas-ai -p athas-version-control (all pass)
  3. bunx tsc --noEmit (clean) and the debugger plus terminal suites
  4. Install an extension, save a file with format-on-save, and confirm
    formatting still works; try command: "sh" in a formatter config
    and confirm it is rejected

Screenshots:

Not applicable (no visual change).

Scope: extension download and staging, formatter and linter exec
validation, LSP and debug-adapter frame readers, debug terminal
command building, terminal file drops, ACP file and terminal tools,
database credential encoding, and git URL handling. Deliberately
excluded: capability allowlist tightening (needs per-surface approval
UX for custom providers and views), the plaintext keyring fallback
(needs an explicit opt-in flow), and first-run tool approval prompts.
Those are the follow-ups.

Refuse extension installs without a checksum instead of skipping
verification, and enforce HTTPS at the crate layer so a future caller
cannot regress the command-level allowlist. Stream response bodies with
a 512 MiB cap matching the tool installer instead of buffering an
unbounded body into memory. Stage archives under unpredictable,
exclusively created names so a pre-planted symlink in the temp
directory cannot redirect the install write.
Reject known shell interpreters by basename so a formatter or linter
config can no longer smuggle `command: "sh"` with `-c` arguments into
a spawned process. Reject commands staged under temporary directories
and NUL bytes in commands or arguments, which would otherwise panic
the process spawn. Forbid NODE_OPTIONS and JVM tool options in tool
environments since they inject code into spawned runtimes. Wire
argument validation into the format and lint call sites.
Bound protocol reads to 64 MiB so a rogue server or adapter cannot
OOM the backend by advertising a huge Content-Length. The LSP reader
stops the offending server; the debug adapter reader rejects the
message as a protocol violation.
Always single-quote debug adapter terminal arguments instead of
passing them through raw when the adapter claims shell readiness.
That flag arrives from workspace-controlled adapters, so honoring it
splices metacharacters straight into the user's terminal.

Quote dropped terminal paths with POSIX single quotes and strip line
breaks first, since a pasted carriage return submits the line even
inside quotes. A file name carrying newlines or pipes can no longer
break out of its argument.
Resolve agent file paths against the session workspace and reject
absolute paths, parent traversal, and symlink escapes instead of
passing them to the filesystem verbatim. Deny terminal sessions
whose working directory leaves the workspace, and strip loader and
runtime code-execution variables from agent-supplied environments.
Honest agents working inside the project see no behavior change.
Percent-encode database usernames and passwords when building
connection URLs so metacharacters cannot shift the parsed host and
redirect credentials to the wrong server. Reject the git ext
transport on clone because it executes local commands, and redact
embedded userinfo from git failure output before it reaches UI
errors and logs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant