Back to skill

Security audit

vscode-tunnel

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to do what it says, but it starts a background remote VS Code tunnel and runs a downloaded CLI without strong safeguards, so it should be reviewed before use.

Install this only if you intentionally want a VS Code Remote Tunnel from the container and understand that it can provide remote terminal access to the environment after Microsoft authorization. Prefer using it in a low-privilege container, start it only on explicit request, stop it when finished, and consider adding CLI integrity verification and narrower activation wording before relying on it.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Warning
Location
tunnel.sh:17
Finding
Unverified Remote VS Code CLI Download and Execution<![CDATA[ ## Vulnerability Details **File Location**: `tunnel.sh`, lines 17 and 78-96 **Vulnerability Type**: Remote executable retrieval without integrity verification **Risk Level**: Medium ### Vulnerable Code ```bash CLI_URL="https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-x64" ``` ```bash download_cli() { local cli_bin="$CLI_DIR/code" if [ -f "$cli_bin" ]; then log_info "CLI already exists, skipping download" return 0 fi log_info "Downloading VS Code CLI..." local tmp_file="$CLI_DIR/vscode_cli.tar.gz" if ! curl -sL "$CLI_URL" -o "$tmp_file"; then log_error "Download failed" rm -f "$tmp_file" exit 1 fi log_info "Extracting CLI..." if ! tar -xzf "$tmp_file" -C "$CLI_DIR"; then log_error "Extraction failed" rm -f "$tmp_file" exit 1 fi rm -f "$tmp_file" chmod +x "$cli_bin" log_success "CLI downloaded: $cli_bin" } ``` ### Technical Analysis The script downloads a mutable VS Code CLI archive from an external URL, follows redirects with `curl -L`, extracts the archive, marks the resulting binary executable, and subsequently launches it. It does not verify a cryptographic checksum, digital signature, pinned release version, final redirect destination, or archive contents. HTTPS protects the connection under normal conditions, and the configured URL belongs to the expected VS Code service. Nevertheless, transport security alone does not establish artifact integrity if the upstream distribution service, redirect destination, signing infrastructure, or served artifact is compromised. The effective executable payload can also change after the Skill package has been reviewed because the URL selects the current stable build. The existing-file check introduces an additional trust assumption: any preexisting regular file at `$CLI_DIR/code` is accepted without validation and later executed. ### Attack ...[truncated 1408 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the CLI to an explicit, reviewed version instead of using a mutable `stable` download selector. 2. Obtain a vendor-published SHA-256 or stronger digest through a separately authenticated channel and verify it before extraction. 3. Prefer vendor-supported cryptographic signature verification when signatures and trusted signing keys are available. 4. Download with strict failure handling, such as `curl --fail --show-error`, and validate the final redirect destination against an explicit allowlist. 5. Inspect the archive file list before extraction and reject absolute paths, `..` traversal entries, unexpected symlinks, and unexpected filenames. 6. Extract into a newly created private temporary directory, validate the resulting binary, and then install it atomically. 7. Ensure `$CLI_DIR` is owned by the expected user and is not writable by untrusted users. Use restrictive directory permissions such as `0700`. 8. Do not trust an existing `$CLI_DIR/code` solely because it is a regular file. Verify its checksum, signature, ownership, permissions, and expected version before every execution. 9. Fail closed and remove unverified artifacts whenever any integrity or validation check fails. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
tunnel.sh:126
Finding
Broad Process Matching Can Terminate an Unrelated Process<![CDATA[ ## Vulnerability Details **File Location**: `tunnel.sh`, lines 126-127 and 186-200 **Vulnerability Type**: Insufficient process identity validation **Risk Level**: Low ### Vulnerable Code ```bash # Fallback: find by process name pgrep -f "code tunnel" 2>/dev/null | head -1 ``` ```bash cmd_stop() { log_info "Stopping VS Code Tunnel..." local pid=$(get_tunnel_pid) if [ -z "$pid" ]; then log_warn "No running tunnel found" exit 0 fi if kill "$pid" 2>/dev/null; then rm -f "$PID_FILE" log_success "Tunnel stopped (PID: $pid)" else log_error "Failed to stop, may lack permissions" exit 1 fi } ``` ### Technical Analysis If the PID file is missing, stale, or does not identify a live process, `get_tunnel_pid` searches all visible command lines for the substring `code tunnel` and selects the first match. The script does not verify that the selected process: - Was started by this script. - Uses the expected `$CLI_DIR/code` executable. - Belongs to the expected user. - Uses the expected CLI directory or log file. - Has a start time corresponding to the stored process instance. - Is actually the managed VS Code Tunnel rather than an unrelated command with matching arguments. `cmd_stop` then sends the default termination signal to that PID. Full-command-line substring matching is insufficient as a security or ownership boundary and can produce false positives. A deliberately crafted same-user process can also satisfy the search pattern. ### Attack Path 1. The tunnel PID file is absent, stale, corrupted, or references a process that is no longer running. 2. Another process visible to the invoking user has `code tunnel` somewhere in its command line. 3. The user invokes `tunnel.sh stop`. 4. The fallback `pgrep -f` search selects the first matching process without validating its executable or ownership relationship to this Skill. 5. `cmd_stop` sends a termination signal to ...[truncated 638 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the broad `pgrep -f "code tunnel"` fallback. If the PID file is unavailable or invalid, report that the managed process cannot be identified safely. 2. Validate that the PID file contains only a positive integer before using it. 3. Before signaling the process, confirm that `/proc/$pid/exe` resolves to the expected canonical path `$CLI_DIR/code`. 4. Check process ownership and reject a PID that is not owned by the expected user. 5. Record and validate process start time in addition to the PID to prevent PID-reuse errors. 6. Use a dedicated process supervisor, service manager, or process-specific control interface where available. 7. Store the PID file in a private directory owned by the invoking user and enforce restrictive permissions. 8. Revalidate process identity immediately before calling `kill` to reduce time-of-check/time-of-use risk. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill invokes shell commands that start a remote access tunnel, but it declares no explicit tool scope or permission boundaries. This is dangerous because an agent may execute privileged shell actions without clear user consent constraints, and the tunnel exposes remote terminal access that can materially expand access to the container.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad enough that routine requests like 'connect vscode' or 'vscode remote' could activate a skill that launches remote connectivity. In this context, accidental activation is more dangerous than usual because the action creates a background remote tunnel and may expose terminal access beyond the local session.

External Transmission

Medium
Category
Data Exfiltration
Content
check_dependencies() {
    local missing=()
    
    for cmd in curl tar grep; do
        if ! command -v "$cmd" &> /dev/null; then
            missing+=("$cmd")
        fi
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Session Persistence

Medium
Category
Rogue Agent
Content
log_info "Launching tunnel..."
    cd "$CLI_DIR"
    
    nohup ./code tunnel \
        --accept-server-license-terms \
        --name "$tunnel_name" \
        > "$LOG_FILE" 2>&1 &
Confidence
90% confidence
Finding
Running `code tunnel` under `nohup` in the background creates persistent remote access from the container to the VS Code tunnel service. In this skill context, that is the core functionality, but it is still security-sensitive because it establishes long-lived remote terminal access and can survive the invoking shell session, increasing exposure if started unintentionally or by an untrusted user.

Static analysis

No suspicious patterns detected.