@marcel91200 / caddy Mirror · read-only / commits / a97bc460
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 10, 22:30 UTC

fileserver: hide the config directory when it is relative (#8398)

FileServer.Provision hides the data directory when it is relative (#8327), because a relative data directory sits under the working directory and holds private keys. The config directory falls back to the same relative "./caddy" when no config home can be resolved, and it holds autosave.json, which is the loaded configuration. The two directories are resolved independently, so an absolute data directory did not cover a relative config directory: with XDG_DATA_HOME set and no HOME or XDG_CONFIG_HOME, the data directory is absolute while the config directory is "./caddy" under the served root. Both directories are now hidden through the existing fallback, each entry added only once. Refs #8381

PerryLink committed Nov 10, 2026 at 22:56 UTC a97bc460cfe5b111fad3d8aa7fc905868e84ae36
2 files changed +41 -3
modules/caddyhttp/fileserver/staticfiles.go
+11 -3
@@ -213,9 +213,17 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
213 fsrv.IndexNames = defaultIndexNames
214 }
215
216 - // a relative data directory sits under the working directory and holds private keys
217 - if dataDir := caddy.AppDataDir(); !filepath.IsAbs(dataDir) {
218 - if abs, err := caddy.FastAbs(dataDir); err == nil {
216 + // a relative data or config directory sits under the working directory and
217 + // holds private keys or the last saved configuration, so hide it
218 + for _, dir := range []string{caddy.AppDataDir(), caddy.AppConfigDir()} {
219 + if filepath.IsAbs(dir) {
220 + continue
221 + }
222 + abs, err := caddy.FastAbs(dir)
223 + if err != nil {
224 + continue
225 + }
226 + if !slices.Contains(fsrv.Hide, abs) {
227 fsrv.Hide = append(fsrv.Hide, abs)
228 }
229 }
modules/caddyhttp/fileserver/staticfiles_hide_test.go
+30
@@ -182,3 +182,33 @@ func TestHideOtherLetterCases(t *testing.T) {
182 })
183 }
184 }
185 +
186 +func TestHideRelativeConfigDir(t *testing.T) {
187 + for _, env := range []string{"XDG_CONFIG_HOME", "HOME", "AppData", "HOMEDRIVE", "HOMEPATH", "USERPROFILE", "home"} {
188 + t.Setenv(env, "")
189 + }
190 + // an absolute data directory must not mask a relative config directory:
191 + // autosave.json holds the running configuration
192 + t.Setenv("XDG_DATA_HOME", t.TempDir())
193 +
194 + if dir := caddy.AppConfigDir(); filepath.IsAbs(dir) {
195 + t.Fatalf("test setup: config directory is absolute: %s", dir)
196 + }
197 + if dir := caddy.AppDataDir(); !filepath.IsAbs(dir) {
198 + t.Fatalf("test setup: data directory is relative: %s", dir)
199 + }
200 +
201 + fsrv := FileServer{Root: "."}
202 + ctx, _ := caddy.NewContext(caddy.Context{Context: context.Background()})
203 + if err := fsrv.Provision(ctx); err != nil {
204 + t.Fatal(err)
205 + }
206 +
207 + autosave := filepath.Join("caddy", "autosave.json")
208 + if !fileHidden(autosave, fsrv.Hide) {
209 + t.Errorf("%s is not hidden; hide list: %v", autosave, fsrv.Hide)
210 + }
211 + if fileHidden("caddyfile.go", fsrv.Hide) {
212 + t.Errorf("caddyfile.go is hidden; hide list: %v", fsrv.Hide)
213 + }
214 +}