11package config
22
33import (
4+ "fmt"
45 "os"
6+ "path/filepath"
57 "strings"
68
79 "gopkg.in/yaml.v2"
@@ -46,6 +48,11 @@ func Load() (*Config, error) {
4648 configPath = "config.yaml"
4749 }
4850
51+ // Validate config path to prevent path traversal attacks
52+ if err := validateConfigPath (configPath ); err != nil {
53+ return nil , fmt .Errorf ("invalid config path: %w" , err )
54+ }
55+
4956 // Set defaults
5057 config := & Config {
5158 Server : ServerConfig {
@@ -72,6 +79,7 @@ func Load() (*Config, error) {
7279
7380 // Load from file if it exists
7481 if _ , err := os .Stat (configPath ); err == nil {
82+ // #nosec G304 - configPath is validated above to prevent path traversal
7583 data , err := os .ReadFile (configPath )
7684 if err != nil {
7785 return nil , err
@@ -126,3 +134,39 @@ func (c *Config) IsEmailAllowed(email string) bool {
126134
127135 return false
128136}
137+
138+ // validateConfigPath ensures the config path is safe and doesn't allow path traversal
139+ func validateConfigPath (path string ) error {
140+ // Clean the path and check for path traversal attempts
141+ cleanPath := filepath .Clean (path )
142+
143+ // Don't allow paths that try to go up directories
144+ if strings .Contains (cleanPath , ".." ) {
145+ return fmt .Errorf ("path traversal not allowed" )
146+ }
147+
148+ // Only allow certain file extensions
149+ ext := filepath .Ext (cleanPath )
150+ if ext != ".yaml" && ext != ".yml" {
151+ return fmt .Errorf ("only .yaml and .yml files are allowed" )
152+ }
153+
154+ // Convert to absolute path to check if it's within allowed directories
155+ absPath , err := filepath .Abs (cleanPath )
156+ if err != nil {
157+ return fmt .Errorf ("failed to get absolute path: %w" , err )
158+ }
159+
160+ // Get current working directory
161+ wd , err := os .Getwd ()
162+ if err != nil {
163+ return fmt .Errorf ("failed to get working directory: %w" , err )
164+ }
165+
166+ // Only allow config files in current directory or its subdirectories
167+ if ! strings .HasPrefix (absPath , wd ) {
168+ return fmt .Errorf ("config file must be in current directory or subdirectories" )
169+ }
170+
171+ return nil
172+ }
0 commit comments