@@ -10,8 +10,9 @@ import (
1010 "errors"
1111 "fmt"
1212 "log/slog"
13+ "os"
1314 "path/filepath"
14- "regexp "
15+ "slices "
1516 "strings"
1617 "time"
1718
@@ -396,8 +397,9 @@ func (nr *NginxReceiver) Validate(allowedDirectories []string) error {
396397 return err
397398}
398399
399- func (c * Config ) IsDirectoryAllowed (directory string ) bool {
400- allow , err := isAllowedDir (directory , c .AllowedDirectories )
400+ // IsAllowedDirectory checks if the given path is in the list of allowed directories.
401+ func (c * Config ) IsDirectoryAllowed (path string ) bool {
402+ allow , err := isAllowedDir (path , c .AllowedDirectories )
401403 if err != nil {
402404 slog .Warn ("Unable to determine if directory is allowed" , "error" , err )
403405 return false
@@ -480,29 +482,40 @@ func (c *Config) IsCommandServerProxyConfigured() bool {
480482}
481483
482484// isAllowedDir checks if the given path is in the list of allowed directories.
483- // It returns true if the path is allowed, false otherwise.
484- // If the path is allowed but does not exist, it also logs a warning.
485- // It also checks if the path is a file, in which case it checks the parent directory of the file.
485+ // It works on files and directories.
486+ // If the path is a file, it checks the directory of the file.
487+ // If the path is a directory, it checks the directory itself.
488+ // It also allows subdirectories within the allowed directories.
486489func isAllowedDir (path string , allowedDirs []string ) (bool , error ) {
487490 if len (allowedDirs ) == 0 {
488491 return false , errors .New ("no allowed directories configured" )
489492 }
490493
491- directoryPath := path
492- // Check if the path is a file, regex matches when end of string is /<filename>.<extension>
493- isFilePath , err := regexp .MatchString (`/(\w+)\.(\w+)$` , directoryPath )
494- if err != nil {
495- return false , errors .New ("error matching path" + directoryPath )
494+ // Check if the path is absolute
495+ if ! filepath .IsAbs (path ) {
496+ return false , fmt .Errorf ("PathError: %s is not absolute" , path )
496497 }
497498
498- if isFilePath {
499- directoryPath = filepath .Dir (directoryPath )
499+ // Does the path exist?
500+ info , err := os .Stat (path )
501+ if err == nil && ! info .IsDir () {
502+ // Path exists and is not a directory
503+ // It's a file so get the parent directory
504+ path = filepath .Dir (path )
505+ }
506+ if err != nil {
507+ if os .IsNotExist (err ) {
508+ // Path does not exist, we can still check if it's an allowed directory
509+ } else {
510+ // Some other error occurred
511+ return false , fmt .Errorf ("PathError %s %w" , path , err )
512+ }
500513 }
501514
502- for _ , allowedDirectory := range allowedDirs {
503- // Check if the directoryPath starts with the allowedDirectory
504- // This allows for subdirectories within the allowed directories.
505- if strings . HasPrefix ( directoryPath , allowedDirectory ) {
515+ for _ , dir := range allowedDirs {
516+ // Check if the path is a subdirectory of the allowed directory
517+ if slices . Contains ( allowedDirs , path ) || strings . HasPrefix ( path , dir + "/" ) {
518+ slog . Info ( fmt . Sprintf ( "Allowed directory %s is allowed" , path ))
506519 return true , nil
507520 }
508521 }
0 commit comments