Thanks to visit codestin.com
Credit goes to github.com

Skip to content

support disabling reverse port forwarding (ssh -R) in the Coder agent SSH server #22275

Description

@ericpaulsen

Problem

Coder's embedded SSH server (built on gliderlabs/ssh) unconditionally allows reverse port forwarding. In agent/agentssh/agentssh.go, the callback is hardcoded:

ReversePortForwardingCallback: func(ctx ssh.Context, bindHost string, bindPort uint32) bool {
    // Allow reverse port forwarding all!
    s.logger.Debug(ctx, "reverse port forward",
        slog.F("bind_host", bindHost),
        slog.F("bind_port", bindPort))
    return true
},

This presents a sandbox escape vector when workspaces are used for AI agent containment:

  • A user runs ssh -R 2222:<local-machine>:22 <workspace> to open a reverse tunnel into the workspace
  • Inside the workspace, anything (agent or human) can run ssh -p 2222 localhost to reach the user's local machine
  • This breaks out of the workspace sandbox, bypassing any network isolation applied within the workspace

Why existing mitigations don't cover this

  • Agent Boundaries operate at the HTTP/HTTPS layer (domain-based allowlist via a proxy). They do not intercept raw TCP connections like SSH over a reverse-forwarded port.
  • CODER_BROWSER_ONLY=true blocks all SSH connections deployment-wide, which also prevents legitimate CLI/IDE access (Cursor, JetBrains, VS Code Remote, etc.).
  • sshd_config in the workspace image has no effect — Coder uses its own embedded SSH server, not OpenSSH.
  • Kubernetes NetworkPolicy can restrict egress but cannot control localhost traffic within the pod where the reverse-forwarded port is bound.

Proposed Solution

Add a configurable option to disable or restrict reverse port forwarding in the Coder agent SSH server. Ideally this would be controllable at:

  • Template level — template admins can disable ssh -R for specific workspace templates (e.g., AI agent workspaces) while leaving it enabled for human developer templates
  • Deployment level — a deployment-wide flag as a fallback

The implementation would involve making the ReversePortForwardingCallback respect a configuration value instead of unconditionally returning true. A similar option could be offered for local port forwarding (ssh -L) via LocalPortForwardingCallback.

Use Case

Organizations running AI coding agents in Coder workspaces with process/network sandboxing (via Kubernetes, Agent Boundaries, nsjail, etc.) need to prevent agents from escaping the sandbox via SSH tunnels established by human users connecting to the workspace.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions