What happened?
In tools environment_file_write and environment_file_edit, attacker-controlled file names are passed to git add without sanitization or a -- option terminator:
RunGitCommand(ctx, worktreePath, "add", fileName)
Flag-like values are interpreted as Git command-line options rather than file paths. This is an argument injection issue in Git option parsing.
To reproduce
Interact with the MCP server and call the file-writing tool with a flag-like file name --all:
{
"method": "tools/call",
"params": {
"name": "environment_file_write",
"arguments": {
"target_file": "--all",
"contents": "poc",
"explanation": "poc"
}
}
}
This tool writes the attacker-controlled file name into the worktree and then immediately triggers the repository update path, which reaches:
RunGitCommand(ctx, worktreePath, "add", fileName)
Expected
User-controlled file names should be passed to Git as paths, not as options. A file literally named --all should be staged as that file only.
Actual
When the repository already contains other pending changes, the injected --all value broadens the staging scope. Instead of staging only the file literally named --all, the update path behaves like git add --all and stages unrelated changes as well.
Impact
An attacker who can control file names through MCP tools can alter Git staging semantics and cause container-use to commit changes beyond the intended target file. This can broaden commit scope, include unrelated modifications, and produce commits that do not match the caller's requested file operation.
Version
container-use version 0.4.2
commit: 89ebe7765ec067a07c51de104822056eb217c1b9
built: 2025-08-19T22:23:38Z
What happened?
In tools
environment_file_writeandenvironment_file_edit, attacker-controlled file names are passed togit addwithout sanitization or a--option terminator:Flag-like values are interpreted as Git command-line options rather than file paths. This is an argument injection issue in Git option parsing.
To reproduce
Interact with the MCP server and call the file-writing tool with a flag-like file name
--all:{ "method": "tools/call", "params": { "name": "environment_file_write", "arguments": { "target_file": "--all", "contents": "poc", "explanation": "poc" } } }This tool writes the attacker-controlled file name into the worktree and then immediately triggers the repository update path, which reaches:
Expected
User-controlled file names should be passed to Git as paths, not as options. A file literally named
--allshould be staged as that file only.Actual
When the repository already contains other pending changes, the injected
--allvalue broadens the staging scope. Instead of staging only the file literally named--all, the update path behaves likegit add --alland stages unrelated changes as well.Impact
An attacker who can control file names through MCP tools can alter Git staging semantics and cause
container-useto commit changes beyond the intended target file. This can broaden commit scope, include unrelated modifications, and produce commits that do not match the caller's requested file operation.Version