Skip to content

Security hardening: setting scopes, workspace-confined agent fs access, permission matching - #1

Merged
paydii merged 4 commits into
developmentfrom
claude/security-design-review-lmt6le
Jul 6, 2026
Merged

Security hardening: setting scopes, workspace-confined agent fs access, permission matching#1
paydii merged 4 commits into
developmentfrom
claude/security-design-review-lmt6le

Conversation

@paydii

@paydii paydii commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator
  • Scope sigit.agents, sigit.agent.default, sigit.registry.url, and
    sigit.permission.mode as machine settings so a workspace's
    .vscode/settings.json can no longer inject an arbitrary agent command,
    flip the permission mode to allow, or point the registry at a
    malicious catalog.
  • Declare untrustedWorkspaces/virtualWorkspaces capabilities so the
    extension stays disabled in Restricted Mode instead of silently
    spawning agents.
  • Confine the agent's fs/read_text_file and fs/write_text_file channel
    to the workspace folders; paths outside the workspace now follow
    sigit.permission.mode (allow / deny / modal prompt) instead of being
    granted unconditionally.
  • Classify permission options by the ACP kind field first; the previous
    unanchored name regex let agent-chosen labels like "Allow now" match
    /no/ and be auto-selected as the deny option (and vice versa). The
    name fallback is now word-bounded.
  • Reject in-flight JSON-RPC requests when the agent closes the
    connection, so a crashed agent no longer leaves the chat stuck busy.
  • Cap the ndjson read buffer at 16 MiB and truncate unparseable lines
    in error messages.
  • Honor the ACP line/limit parameters in fs/read_text_file instead of
    always returning the whole file.
  • Generate the webview CSP nonce with crypto.randomBytes instead of
    Math.random.
  • Run the registry parser test in CI alongside smoke and webview tests.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01YDM1YxP1jqcjSGpcXwKtwG

paydii and others added 4 commits June 26, 2026 05:30
Promote the 1.0.1 release: GUI-launch PATH/ENOENT fix, model-cache EPERM fix,
in-place tool-call streaming, ACP agent registry browser, VSIX packaging
cleanup, and publish CI/CD for the VS Code Marketplace and Open VSX.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s, permission matching

- Scope sigit.agents, sigit.agent.default, sigit.registry.url, and
  sigit.permission.mode as machine settings so a workspace's
  .vscode/settings.json can no longer inject an arbitrary agent command,
  flip the permission mode to allow, or point the registry at a
  malicious catalog.
- Declare untrustedWorkspaces/virtualWorkspaces capabilities so the
  extension stays disabled in Restricted Mode instead of silently
  spawning agents.
- Confine the agent's fs/read_text_file and fs/write_text_file channel
  to the workspace folders; paths outside the workspace now follow
  sigit.permission.mode (allow / deny / modal prompt) instead of being
  granted unconditionally.
- Classify permission options by the ACP kind field first; the previous
  unanchored name regex let agent-chosen labels like "Allow now" match
  /no/ and be auto-selected as the deny option (and vice versa). The
  name fallback is now word-bounded.
- Reject in-flight JSON-RPC requests when the agent closes the
  connection, so a crashed agent no longer leaves the chat stuck busy.
- Cap the ndjson read buffer at 16 MiB and truncate unparseable lines
  in error messages.
- Honor the ACP line/limit parameters in fs/read_text_file instead of
  always returning the whole file.
- Generate the webview CSP nonce with crypto.randomBytes instead of
  Math.random.
- Run the registry parser test in CI alongside smoke and webview tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDM1YxP1jqcjSGpcXwKtwG

@sigit-code sigit-code Bot 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.

Security hardening across the extension. Config keys (sigit.agents, sigit.agent.default, sigit.registry.url, sigit.permission.mode) become machine-scoped so workspaces can't override them, and untrusted/virtual workspace capabilities are declared. The ACP Connection now fails in-flight requests on close, caps the read buffer at 16 MiB, and truncates unparseable lines. chatView.ts confines agent fs read/write to workspace folders (falling back to permission.mode), classifies permission options by ACP kind before a word-bounded name regex, honors read line/limit params, and uses crypto.randomBytes for the CSP nonce.

Reviewers should check the isInWorkspace path-containment logic and the read line/limit slicing for off-by-one and symlink edge cases.


Automated review by siGit Code · commit 2e06c39

Comment thread src/chatView.ts
if (typeof line === "number" || typeof limit === "number") {
const lines = text.split("\n");
const start = typeof line === "number" ? Math.max(0, line - 1) : 0;
const end = typeof limit === "number" ? start + limit : lines.length;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

warninglimit is applied as a line count from start, but ACP limit is typically a byte or character limit, not a line count; confirm the semantics match the spec, otherwise agents get wrong content.

Comment thread src/chatView.ts
const folders = vscode.workspace.workspaceFolders ?? [];
return folders.some((folder) => {
const rel = path.relative(folder.uri.fsPath, uri.fsPath);
return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

warningisInWorkspace compares resolved fsPaths but doesn't resolve symlinks; a symlink inside the workspace pointing outside (or a path with symlinked ancestors) can bypass the confinement check.

Comment thread src/acp/connection.ts

private onData(text: string): void {
this.buffer += text;
if (this.buffer.length > Connection.MAX_BUFFER_LENGTH && !this.buffer.includes("\n")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit — The buffer cap only triggers when there is no newline at all; an agent streaming many small valid lines plus one huge unterminated tail could still accumulate up to 16 MiB per chunk boundary, which is acceptable but the guard won't fire until the whole buffer lacks a newline.

@paydii
paydii changed the base branch from main to development July 6, 2026 07:21
@paydii
paydii merged commit 9d25f6e into development Jul 6, 2026
2 checks passed
@paydii
paydii deleted the claude/security-design-review-lmt6le branch July 6, 2026 21:19
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.

3 participants