Files
kubeshark/cmd/createNoFollow_windows.go
T
Volodymyr StoikoandGitHub a76a1920dc mcp: confine download_file destination and harden start_kubeshark argument handling (#1957)
* mcp: confine download_file dest and fix start_kubeshark arg injection

download_file wrote fetched bytes to a caller-supplied dest with no
validation, and appended the caller-supplied pod_regex to 'kubeshark tap'
with no end-of-options separator. Both are reachable via induced-agent
(prompt-injection) tool arguments.

- download_file: resolve dest through secureDownloadDest, confined to a base
  directory (CWD by default, relocatable via KUBESHARK_MCP_DOWNLOAD_DIR);
  reject dest that escapes the base (../ or absolute) and '..' in the Hub
  path (CWE-22).
- start_kubeshark: append pod_regex last, after a '--' separator, so it is
  always the [POD REGEX] positional and never parsed as a --set flag (CWE-88).
- tests: set downloadDir in the download tests; add a traversal-rejection test.

Reported by novice-22 via coordinated disclosure.

* mcp: reject download destinations that escape the base via symlink

Containment in secureDownloadDest was lexical only, so a symlinked
subdirectory inside the download dir (or a dest that is itself a symlink)
could still redirect the write outside it. Resolve symlinks on the
deepest existing ancestor and re-check containment, and open the file
with O_NOFOLLOW where available to narrow the TOCTOU window.
2026-08-12 13:00:04 -07:00

13 lines
511 B
Go

package cmd
import "os"
// createNoFollow mirrors the Unix helper. Windows has no O_NOFOLLOW; creating a
// symlink there requires either administrator rights or developer mode, so the
// symlink-planting scenario the flag guards against does not apply in the same
// way. secureDownloadDest still rejects destinations that resolve through a
// symlink outside the download directory.
func createNoFollow(name string) (*os.File, error) {
return os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
}