From df61a586c9df496c2ab71790534b0cab5d9e47ba Mon Sep 17 00:00:00 2001 From: M4rtin Hsu Date: Sun, 16 Apr 2023 20:14:36 +0800 Subject: [PATCH] Fix: potential vulnerability in http provider (#2680) --- adapter/provider/parser.go | 8 +++++++- constant/path.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/adapter/provider/parser.go b/adapter/provider/parser.go index 887ac5cdc7..e248d2c3bc 100644 --- a/adapter/provider/parser.go +++ b/adapter/provider/parser.go @@ -10,7 +10,10 @@ import ( types "github.com/Dreamacro/clash/constant/provider" ) -var errVehicleType = errors.New("unsupport vehicle type") +var ( + errVehicleType = errors.New("unsupport vehicle type") + errSubPath = errors.New("path is not subpath of home directory") +) type healthCheckSchema struct { Enable bool `provider:"enable"` @@ -53,6 +56,9 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide case "file": vehicle = NewFileVehicle(path) case "http": + if !C.Path.IsSubPath(path) { + return nil, fmt.Errorf("%w: %s", errSubPath, path) + } vehicle = NewHTTPVehicle(schema.URL, path) default: return nil, fmt.Errorf("%w: %s", errVehicleType, schema.Type) diff --git a/constant/path.go b/constant/path.go index 781cc5f7cf..add782074a 100644 --- a/constant/path.go +++ b/constant/path.go @@ -4,6 +4,7 @@ import ( "os" P "path" "path/filepath" + "strings" ) const Name = "clash" @@ -51,6 +52,18 @@ func (p *path) Resolve(path string) string { return path } +// IsSubPath return true if path is a subpath of homedir +func (p *path) IsSubPath(path string) bool { + homedir := p.HomeDir() + path = p.Resolve(path) + rel, err := filepath.Rel(homedir, path) + if err != nil { + return false + } + + return !strings.Contains(rel, "..") +} + func (p *path) MMDB() string { return P.Join(p.homeDir, "Country.mmdb") }