Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7c4ac4e
check for invalid characters in allowedDirectories when loading config
sean-breen Jun 19, 2025
d64f804
add sanitising of allowed directories when loading configuration
sean-breen Jun 24, 2025
88d04e2
remove log
sean-breen Jun 24, 2025
5c41b2a
fix lint issues
sean-breen Jun 25, 2025
dd1f2f2
fix test
sean-breen Jun 25, 2025
8c99d03
add check for symlinks, disallow all symlinks
sean-breen Jun 25, 2025
cb04ec0
fix lint
sean-breen Jun 25, 2025
faf003a
fix lint
sean-breen Jun 25, 2025
be3e230
fix lint
sean-breen Jun 25, 2025
195808f
fix default paths
sean-breen Jun 26, 2025
a13d9fe
update comment
sean-breen Jul 2, 2025
83f1c56
Merge branch 'main' into allowedDirsFix
sean-breen Jul 4, 2025
38fdf24
fix default collector config test
sean-breen Jul 4, 2025
9183a07
return bool + error from isAllowedDirs
sean-breen Jul 9, 2025
b8b714b
fix lint
sean-breen Jul 9, 2025
d5c4bfa
rename tests
sean-breen Jul 9, 2025
a017437
remove needless logs
sean-breen Jul 14, 2025
a9d2744
Merge branch 'main' into allowedDirsFix
sean-breen Jul 14, 2025
dfbdecd
fix lint warning
sean-breen Jul 14, 2025
4e9451f
refactor to remove unessessary logs
sean-breen Jul 15, 2025
6b4d18f
fix lint
sean-breen Jul 15, 2025
99a0a79
fix test names
sean-breen Jul 15, 2025
5ede483
fix test
sean-breen Jul 15, 2025
b8f30db
add unit test for isSymlink
sean-breen Jul 15, 2025
73939b3
use require in place of assert
sean-breen Jul 15, 2025
7fcbfe1
update regex
sean-breen Jul 15, 2025
279dcdd
update comment
sean-breen Jul 15, 2025
0e767b2
Merge branch 'main' into allowedDirsFix
sean-breen Jul 17, 2025
c4c1787
Merge branch 'main' into allowedDirsFix
sean-breen Jul 21, 2025
c00d955
fix unit test
sean-breen Jul 21, 2025
2d3e6e8
Remove symlink check
sean-breen Jul 22, 2025
9b586fe
Merge branch 'main' into allowedDirsFix
sean-breen Jul 23, 2025
c362abf
fix unit test after merging main
sean-breen Jul 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 40 additions & 21 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"log/slog"
"os"
"path/filepath"
"regexp"
"slices"
"strconv"
"strings"
Expand All @@ -36,7 +37,11 @@ const (
EnvPrefix = "NGINX_AGENT"
KeyDelimiter = "_"
KeyValueNumber = 2
AgentDirName = "/etc/nginx-agent/"
AgentDirName = "/etc/nginx-agent"

// Regular expression to match invalid characters in paths.
// It matches whitespace, control characters, non-printable characters, and specific Unicode characters.
regexInvalidPath = "\\s|[[:cntrl:]]|[[:space:]]|[[^:print:]]|ㅤ|\\.\\.|\\*"
)

var viperInstance = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter))
Expand Down Expand Up @@ -79,27 +84,13 @@ func RegisterConfigFile() error {
}

func ResolveConfig() (*Config, error) {
// Collect allowed directories, so that paths in the config can be validated.
directories := viperInstance.GetStringSlice(AllowedDirectoriesKey)
allowedDirs := []string{AgentDirName}

log := resolveLog()
slogger := logger.New(log.Path, log.Level)
slog.SetDefault(slogger)

// Check directories in allowed_directories are valid
for _, dir := range directories {
if dir == "" || !filepath.IsAbs(dir) {
slog.Warn("Invalid directory: ", "dir", dir)
continue
}

if !strings.HasSuffix(dir, "/") {
dir += "/"
}
allowedDirs = append(allowedDirs, dir)
}

// Collect allowed directories, so that paths in the config can be validated.
directories := viperInstance.GetStringSlice(AllowedDirectoriesKey)
allowedDirs := resolveAllowedDirectories(directories)
slog.Info("Configured allowed directories", "allowed_directories", allowedDirs)

// Collect all parsing errors before returning the error, so the user sees all issues with config
Expand Down Expand Up @@ -129,13 +120,40 @@ func ResolveConfig() (*Config, error) {

checkCollectorConfiguration(collector, config)

slog.Info(
"Excluded files from being watched for file changes",
"exclude_files",
config.Watchers.FileWatcher.ExcludeFiles,
)

slog.Debug("Agent config", "config", config)
slog.Info("Excluded files from being watched for file changes", "exclude_files",
config.Watchers.FileWatcher.ExcludeFiles)

return config, nil
}

// resolveAllowedDirectories checks if the provided directories are valid and returns a slice of cleaned absolute paths.
// It ignores empty paths, paths that are not absolute, and paths containing invalid characters.
// Invalid paths are logged as warnings.
func resolveAllowedDirectories(dirs []string) []string {
allowed := []string{AgentDirName}
for _, dir := range dirs {
re := regexp.MustCompile(regexInvalidPath)
invalidChars := re.MatchString(dir)
if dir == "" || dir == "/" || !filepath.IsAbs(dir) || invalidChars {
slog.Warn("Ignoring invalid directory", "dir", dir)
continue
}
dir = filepath.Clean(dir)
if dir == AgentDirName {
// If the directory is the default agent directory, we skip adding it again.
continue
}
allowed = append(allowed, dir)
}

return allowed
}

func checkCollectorConfiguration(collector *Collector, config *Config) {
if isOTelExporterConfigured(collector) && config.IsGrpcClientConfigured() && config.IsAuthConfigured() &&
config.IsTLSConfigured() {
Expand Down Expand Up @@ -744,13 +762,14 @@ func resolveClient() *Client {
}

func resolveCollector(allowedDirs []string) (*Collector, error) {
// Collect receiver configurations
var receivers Receivers

err := resolveMapStructure(CollectorReceiversKey, &receivers)
if err != nil {
return nil, fmt.Errorf("unmarshal collector receivers config: %w", err)
}

// Collect exporter configurations
exporters, err := resolveExporters()
if err != nil {
return nil, fmt.Errorf("unmarshal collector exporters config: %w", err)
Expand Down
Loading