@@ -13,6 +13,7 @@ import (
1313 "os"
1414 "os/signal"
1515 "path/filepath"
16+ "strings"
1617 "syscall"
1718 "time"
1819
@@ -111,6 +112,7 @@ func addServerFlags(flags *pflag.FlagSet) {
111112 flags .Bool ("disableExec" , true , "disables Command Runner feature" )
112113 flags .Bool ("disableTypeDetectionByHeader" , false , "disables type detection by reading file headers" )
113114 flags .Bool ("disableImageResolutionCalc" , false , "disables image resolution calculation by reading image files" )
115+ flags .Bool ("followExternalSymlinks" , false , "follow symlinks whose target is outside the user scope (unsafe)" )
114116}
115117
116118var rootCmd = & cobra.Command {
@@ -362,6 +364,10 @@ func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, e
362364 server .EnableExec = ! v .GetBool ("disableExec" )
363365 }
364366
367+ if v .IsSet ("followExternalSymlinks" ) {
368+ server .FollowExternalSymlinks = v .GetBool ("followExternalSymlinks" )
369+ }
370+
365371 if isAddrSet && isSocketSet {
366372 return nil , errors .New ("--socket flag cannot be used with --address, --port, --key nor --cert" )
367373 }
@@ -378,6 +384,25 @@ func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, e
378384 log .Println ("WARNING: read https://github.com/thevickypedia/filebrowser/issues/5199" )
379385 }
380386
387+ if server .FollowExternalSymlinks {
388+ log .Println ("WARNING: Following external symlinks enabled!" )
389+ log .Println ("WARNING: Symlinks pointing outside a user's scope will be followed," )
390+ log .Println ("WARNING: which can expose files outside that scope. Only enable this if" )
391+ log .Println ("WARNING: you fully understand and trust the contents of every user scope." )
392+ }
393+
394+ if set , err := st .Settings .Get (); err == nil && set .Signup {
395+ scope := strings .TrimSpace (set .Defaults .Scope )
396+ scopeIsRoot := scope == "" || scope == "." || scope == "/"
397+
398+ if ! set .CreateUserDir && scopeIsRoot {
399+ log .Println ("WARNING: Signup is enabled without createUserDir and the default scope is" )
400+ log .Println ("WARNING: the server root, so every self-registered user can read, modify and" )
401+ log .Println ("WARNING: delete all files File Browser serves, including other users' files." )
402+ log .Println ("WARNING: Enable createUserDir, or set a default scope other than the root." )
403+ }
404+ }
405+
381406 return server , nil
382407}
383408
@@ -455,19 +480,20 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
455480 }
456481
457482 ser := & settings.Server {
458- BaseURL : v .GetString ("baseURL" ),
459- Port : v .GetString ("port" ),
460- Log : v .GetString ("log" ),
461- TLSKey : v .GetString ("key" ),
462- TLSCert : v .GetString ("cert" ),
463- Address : v .GetString ("address" ),
464- Root : v .GetString ("root" ),
465- TokenExpirationTime : v .GetString ("tokenExpirationTime" ),
466- EnableThumbnails : ! v .GetBool ("disableThumbnails" ),
467- ResizePreview : ! v .GetBool ("disablePreviewResize" ),
468- EnableExec : ! v .GetBool ("disableExec" ),
469- TypeDetectionByHeader : ! v .GetBool ("disableTypeDetectionByHeader" ),
470- ImageResolutionCal : ! v .GetBool ("disableImageResolutionCalc" ),
483+ BaseURL : v .GetString ("baseURL" ),
484+ Port : v .GetString ("port" ),
485+ Log : v .GetString ("log" ),
486+ TLSKey : v .GetString ("key" ),
487+ TLSCert : v .GetString ("cert" ),
488+ Address : v .GetString ("address" ),
489+ Root : v .GetString ("root" ),
490+ TokenExpirationTime : v .GetString ("tokenExpirationTime" ),
491+ EnableThumbnails : ! v .GetBool ("disableThumbnails" ),
492+ ResizePreview : ! v .GetBool ("disablePreviewResize" ),
493+ EnableExec : ! v .GetBool ("disableExec" ),
494+ TypeDetectionByHeader : ! v .GetBool ("disableTypeDetectionByHeader" ),
495+ ImageResolutionCal : ! v .GetBool ("disableImageResolutionCalc" ),
496+ FollowExternalSymlinks : v .GetBool ("followExternalSymlinks" ),
471497 }
472498
473499 err = s .Settings .SaveServer (ser )
0 commit comments