What Changed in v2.1.7
This is a security-focused release resolving six advisories. Most close the same class of gap: the per-folder .goshs ACL was enforced on HTTP/WebDAV but not on every other protocol serving the webroot. It also adds folder uploads to the web UI, fixes an FTP crash and an SFTP path bug on Windows, and brings the usual dependency and CI maintenance.
🔒 Security
Per-folder .goshs ACL now enforced on every protocol: SFTP, FTP, TFTP and SMB share a new fail-closed enforcer, httpserver.ProtocolACL. These protocols cannot present a folder's basic-auth credential, so a folder protected by a .goshs auth entry is denied outright. Block-listed names and the .goshs file itself (which holds the bcrypt hashes) are always denied, and directory listings hide .goshs, blocked entries and auth-protected subdirectories.
- SFTP ignores the
.goshsACL (GHSA-2m7f-jq4x-rcj7, High): SFTP handlers only checked the webroot boundary, so the single SFTP credential could read, write, list, rename or delete files inside folders that.goshsprotects or blocks over HTTP.ProtocolACLis now wired into every SFTP read, write, list and command path, including the rename destination. - TFTP, FTP and SMB ignore the
.goshsACL (GHSA-q8gg-q2wc-w52g, Medium): the same gap in the other transfer protocols. Protected subtrees could be downloaded anonymously over TFTP, including the.goshsfile with its bcrypt hash. The fixes:- TFTP checks the ACL on read and write requests.
- FTP wraps its filesystem in an ACL layer that also filters listings.
- SMB checks at handle creation and on the rename destination, and filters directory queries.
- A directory named
.goshswipes inherited auth (GHSA-mhxc-hfx2-7w79, Medium): a.goshsdirectory (creatable via?mkdir) made the ACL resolver return an empty ACL, silently removing inherited per-directory auth and block lists for the whole subtree. The resolver now fails closed: an unreadable or unparsable.goshs(including a dangling symlink) denies everything, and non-regular.goshsentries are ignored.?mkdirand uploads refuse any.goshspath component. - Block list bypass on case-insensitive filesystems (GHSA-3x28-6v7h-gg87, Medium): incomplete fix of CVE-2026-66064. Block-list and never-serve checks compared names case-sensitively, so
SECRET.txtslipped past a block onsecret.txton Windows/macOS. All enforcement points across HTTP, WebDAV, SFTP and listing filters now compare case-insensitively. - Concurrent requests bypass the brute-force lockout (GHSA-8f9w-966j-qhq9, Medium):
verifyCredentialschecked and updated the per-IP failure counter in two separate locked sections around the bcrypt compare. A burst of concurrent wrong-password requests all passed the check, and the counter ended at 1, so the 5-failure lockout never triggered. Each attempt is now counted in the same locked section as the check, before the password is verified, so each IP gets at most 5 guesses per lockout window no matter how many requests it sends at once.
✨ New Features
- Folder upload in the web UI (#227): whole folders, including subdirectories, can now be dropped or selected for upload, and their structure is preserved on the server. Relative paths are sanitized:
..cannot escape the target directory, and.goshscomponents are refused.
🐛 Bug Fixes
- FTP crashed on
AUTH TLSwithout TLS (nil-pointer panic): when a client requested explicit TLS, the FTP driver handed back an empty TLS configuration and the server crashed. FTP now serves FTPS with the configured certificate (-swith-ssor-sk/-sc) and cleanly refusesAUTH TLSwhen TLS is not enabled. - SFTP paths doubled on Windows (#292): SFTP on Windows hosts prefixed the webroot twice, breaking directory navigation and transfers.
🛠️ Build, CI & Packaging
- Docker builder image moved to Go 1.27 (
golang:1.27-alpine); runtimealpinebase image refreshed. - All
github/codeql-actionsteps are pinned to the same release, and Dependabot now groups its bumps into a single PR, so split updates no longer break the CodeQL workflow. - README: security contributor acknowledgements updated.
⬆️ Dependencies
- Go modules:
golang.org/x/crypto0.54.0 → 0.57.0,golang.org/x/net0.57.0 → 0.59.0,golang.org/x/term0.45.0 → 0.46.0,golang.org/x/text0.41.0 → 0.42.0,github.com/fclairamb/ftpserverlib0.32.3 → 0.32.4,github.com/miekg/dns1.1.72 → 1.1.73,github.com/sirupsen/logrus1.9.4 → 1.10.2,github.com/stretchr/testify1.11.1 → 1.12.1,github.com/moby/moby/api1.55.0 → 1.56.0. - GitHub Actions:
github/codeql-action(init/autobuild/analyze/upload-sarif) 4.37.7 → 4.38.2,codecov/codecov-action7.0.0 → 7.1.1,docker/setup-qemu-action4.2.0 → 4.4.0,docker/setup-buildx-action4.3.0 → 4.4.1,docker/build-push-action7.3.0 → 7.4.0. - Docker:
golang1.26-alpine → 1.27-alpine,alpinebase digest refresh.