Skip to content

SFTP sftp.root chroot: readdir works but all path resolution (cd/get/open) fails — even files at the chroot root #214

Description

@Yaminyam

Summary

When sftp.root (SFTP chroot) is configured, directory listing works but every path resolution fails — you can ls the root and see entries, but cd <subdir>, get <file>, and even get <file-at-root> all fail. This makes the sftp.root confinement feature unusable.

Reproduces on both macOS (aarch64) and Linux (x86_64-musl) builds of bssh-server v2.2.3.

Reproduction

Config (config.yaml):

server:
  bind_address: 127.0.0.1
  port: 2223
  host_keys: [/tmp/cctest/hostkey]
auth:
  methods: [publickey]
  publickey:
    authorized_keys_pattern: /tmp/cctest/{user}.keys
sftp:
  enabled: true
  root: /tmp/cctest/data        # <-- chroot

Data layout:

/tmp/cctest/data/hello.txt
/tmp/cctest/data/subdir/nested.txt

Run: bssh-server run -c config.yaml -D, then connect with the OpenSSH sftp client:

sftp> pwd
Remote working directory: /
sftp> ls
hello.txt  subdir           # <-- readdir OK
sftp> cd subdir
realpath /subdir: Access denied: path outside root      # <-- BUG
sftp> get subdir/nested.txt
File "/subdir/nested.txt" not found.                    # <-- BUG
sftp> get hello.txt
File "/hello.txt" not found.                            # <-- BUG (file is at chroot root!)

Expected

  • cd subdir → enters /subdir (i.e. <root>/subdir)
  • get hello.txt → downloads <root>/hello.txt
  • get subdir/nested.txt → downloads <root>/subdir/nested.txt

Actual

  • ls (readdir) resolves entries under the chroot root correctly.
  • But realpath/open/stat of any path — including a file directly at the chroot root — is rejected as path outside root or not found.

So there is an inconsistency between the readdir path handling and the open/realpath path handling when sftp.root is set: listing translates the chroot correctly, but per-path resolution does not (it appears to treat the virtual /… as an absolute host path and then reject it against the root boundary).

Workaround

Leave sftp.root unset (root: null) — without chroot, all SFTP operations work correctly (verified: nav, upload, download, rename, chmod, rm/rmdir, spaces/unicode filenames, multi-MB binary transfer with matching checksum).

Environment

  • bssh-server 2.2.3 (bssh-server-macos-aarch64 and bssh-server-linux-x86_64-musl)
  • OpenSSH sftp client

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions