Skip to content

sec (6/9): run user-defined scanners in an isolated working directory#30

Open
jesse-merhi wants to merge 1 commit into
sec/05-windows-target-guardfrom
sec/06-isolated-cwd
Open

sec (6/9): run user-defined scanners in an isolated working directory#30
jesse-merhi wants to merge 1 commit into
sec/05-windows-target-guardfrom
sec/06-isolated-cwd

Conversation

@jesse-merhi

Copy link
Copy Markdown
Member

What this changes

Part 6 of 9 in the BYOS security-hardening stack. Stacked on sec (5/9) (#29).

Every process runs with a "working directory" — the folder it's in, which it can read and write by default. Before this change, ClawScan chose the user-defined scanner's working directory from the target:

func userDefinedScannerCWD(target string) string {
    // ... url? -> "" ; directory? -> the target dir ; file? -> the target's PARENT dir
}

So scanning /home/me/skills/suspect/skill.md ran the scanner inside /home/me/skills/suspect/ — with write access to everything next to the target. A malicious or buggy scanner could drop or overwrite files beside the thing it was scanning. Under the Docker sandbox this was worse: that parent directory got mounted into the container read-write, turning "scan this file" into "here's a writable mount of its whole folder."

The fix

The working directory is no longer derived from the target:

  • Host runs (--sandbox off): a fresh os.MkdirTemp("", "clawscan-scanner-") directory, deleted after the run. The scanner gets a private scratch dir, not the target's neighborhood.
  • Docker runs (the default): cwd stays "", so nothing target-derived is bind-mounted; the container's own workdir is already isolated.

The old userDefinedScannerCWD helper (and its net/url / path/filepath imports) is removed.

Verify

go test -count=1 ./internal/runner/ -run UserDefinedScannerUsesIsolatedCwd

New test TestUserDefinedScannerUsesIsolatedCwd: scans a file inside a temp dir with SandboxModeOff and asserts the recorded cwd is not the target dir (nor under it) and carries the clawscan-scanner- prefix.

The scanner used to run with a working directory derived from the target:
the target's parent directory, or the target itself when it was a directory.
That handed the scanner writable access to files sitting next to the target,
and under Docker that parent became a writable bind mount. Run host scanners
in a fresh os.MkdirTemp directory (removed after the run) and keep the Docker
cwd empty so nothing target-derived is mounted; the container workdir is
already isolated. Removes the now-unused userDefinedScannerCWD helper.
Copilot AI review requested due to automatic review settings July 23, 2026 12:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@clawsweeper

clawsweeper Bot commented Jul 23, 2026

Copy link
Copy Markdown

ClawSweeper status: review started.

I am starting a fresh review of this pull request: sec (6/9): run user-defined scanners in an isolated working directory This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

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.

2 participants