```
feat(vscode): add Daemon debug configuration Add a new debug configuration for Daemon mode in VS Code launch settings to facilitate debugging with specific environment variables and flags. fix(config): use filepath.Dir for config path resolution Change from assigning raw config path to using filepath.Dir to get the directory of the config file, ensuring proper directory handling. refactor(filehandler): improve file access security and directory handling Improve security checks by using Lstat instead of Mode check for symlinks, enhance directory handling when URL ends with "/" to prevent path traversal errors, and refine path resolution logic to properly handle root directory cases. fix(config): disable SSL and update example root path Disable SSL for teststatic server configuration and update root path from relative "./example" to "../example" for proper example directory access. ``` Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
f4a2967f59
commit
6fd9f32f9c
|
|
@ -21,6 +21,24 @@
|
||||||
"showLog": true,
|
"showLog": true,
|
||||||
"trace": "log",
|
"trace": "log",
|
||||||
"dlvFlags": ["--check-go-version=false"]
|
"dlvFlags": ["--check-go-version=false"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Daemon",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "debug",
|
||||||
|
"program": "${workspaceFolder}",
|
||||||
|
"env": {
|
||||||
|
"GODEBUG": "cgocheck=0",
|
||||||
|
"_go_daemon": "g_daemon"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"${file}"
|
||||||
|
],
|
||||||
|
"showLog": true,
|
||||||
|
"trace": "log",
|
||||||
|
"dlvFlags": ["--check-go-version=false"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ func LoadConfig() {
|
||||||
server := model.HttpServerConfig{}
|
server := model.HttpServerConfig{}
|
||||||
err = decoder.Decode(&server)
|
err = decoder.Decode(&server)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
server.ConfPath = config
|
server.ConfPath = filepath.Dir(config)
|
||||||
normalizeServer(&server)
|
normalizeServer(&server)
|
||||||
model.Config.Servers = append(model.Config.Servers, &server)
|
model.Config.Servers = append(model.Config.Servers, &server)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -25,27 +25,34 @@ func (f FileHandler) String() string {
|
||||||
}
|
}
|
||||||
func (f FileHandler) Open(name string) (http.File, error) {
|
func (f FileHandler) Open(name string) (http.File, error) {
|
||||||
l := gologger.GetLogger("filehandler")
|
l := gologger.GetLogger("filehandler")
|
||||||
l.Debug("access:", name)
|
l.Debug("Open called: name=", name)
|
||||||
if strings.HasPrefix(name, "../") {
|
if strings.HasPrefix(name, "../") {
|
||||||
return nil, errors.New("not permitted")
|
return nil, errors.New("not permitted")
|
||||||
}
|
}
|
||||||
relatedPath := strings.TrimPrefix(name, f.WPath)
|
relatedPath := strings.TrimPrefix(name, f.WPath)
|
||||||
|
|
||||||
rPath := filepath.Join(f.Root, strings.TrimPrefix(relatedPath, "/"))
|
// When URL ends with "/" (like "/") and WPath matches, we should return
|
||||||
l.Debug("access:", rPath)
|
// the directory and let http.FileServer handle the redirect to default file.
|
||||||
|
// This prevents "http: attempting to traverse a non-directory" error.
|
||||||
|
if relatedPath == "" && f.Default != "" {
|
||||||
|
relatedPath = "."
|
||||||
|
}
|
||||||
|
|
||||||
|
// If relatedPath becomes ".", use Root directly to represent the directory itself
|
||||||
|
var rPath string
|
||||||
|
if relatedPath == "." {
|
||||||
|
rPath = f.Root
|
||||||
|
} else {
|
||||||
|
rPath = filepath.Join(f.Root, strings.TrimPrefix(relatedPath, "/"))
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve symlinks and clean path to prevent path traversal
|
// Resolve symlinks and clean path to prevent path traversal
|
||||||
realRoot, _ := filepath.EvalSymlinks(f.Root)
|
realRoot, _ := filepath.EvalSymlinks(f.Root)
|
||||||
realPath, _ := filepath.EvalSymlinks(filepath.Dir(rPath))
|
realRPath, _ := filepath.EvalSymlinks(rPath)
|
||||||
if realPath != realRoot && !strings.HasPrefix(realPath, realRoot+string(filepath.Separator)) {
|
|
||||||
return nil, errors.New("not permitted")
|
|
||||||
}
|
|
||||||
|
|
||||||
if rPath == f.Root {
|
// Check if the resolved path is within root
|
||||||
if f.Default == "" {
|
if realRPath != realRoot && !strings.HasPrefix(realRPath, realRoot+string(filepath.Separator)) {
|
||||||
return nil, errors.New("not permit list dir")
|
return nil, errors.New("not permitted")
|
||||||
}
|
|
||||||
rPath = filepath.Join(rPath, f.Default)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fInfo, exists, err := FileExists(rPath)
|
fInfo, exists, err := FileExists(rPath)
|
||||||
|
|
@ -57,11 +64,13 @@ func (f FileHandler) Open(name string) (http.File, error) {
|
||||||
return nil, os.ErrNotExist
|
return nil, os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
if fInfo.IsDir() && rPath != strings.TrimSuffix(f.Root, "/") {
|
// If it's a directory and not the root, don't allow listing
|
||||||
|
if fInfo.IsDir() && rPath != f.Root {
|
||||||
return nil, errors.New("not permit list dir")
|
return nil, errors.New("not permit list dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
if fInfo.Mode() == fs.ModeSymlink {
|
// Use Lstat to check if the path itself is a symlink (doesn't follow symlinks)
|
||||||
|
if lstatInfo, err := os.Lstat(rPath); err == nil && lstatInfo.Mode()&fs.ModeSymlink != 0 {
|
||||||
return nil, errors.New("not permit follow symbol link")
|
return nil, errors.New("not permit follow symbol link")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
"name": "teststatic",
|
"name": "teststatic",
|
||||||
"server": ["www.teststatic.com"],
|
"server": ["www.teststatic.com"],
|
||||||
"port": 8088,
|
"port": 8088,
|
||||||
"enable_ssl":true,
|
"enable_ssl":false,
|
||||||
"paths": [
|
"paths": [
|
||||||
{
|
{
|
||||||
"path": "/",
|
"path": "/",
|
||||||
"root": "./example",
|
"root": "../example",
|
||||||
"default": "index.html"
|
"default": "index.html"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue