Skip to content

Commit 791ea5e

Browse files
committed
chore: allow setting addition safePaths by environment variable SAFE_PATHS
package managers can allow for pre-defined safe paths without disabling the entire security check feature for #2004
1 parent 7e7016b commit 791ea5e

File tree

2 files changed

+61
-7
lines changed

2 files changed

+61
-7
lines changed

constant/path.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,23 @@ var Path = func() *path {
3737
}
3838
}
3939

40-
return &path{homeDir: homeDir, configFile: "config.yaml", allowUnsafePath: allowUnsafePath}
40+
var safePaths []string
41+
for _, safePath := range strings.Split(os.Getenv("SAFE_PATHS"), ":") {
42+
safePath = strings.TrimSpace(safePath)
43+
if len(safePath) == 0 {
44+
continue
45+
}
46+
safePaths = append(safePaths, safePath)
47+
}
48+
49+
return &path{homeDir: homeDir, configFile: "config.yaml", allowUnsafePath: allowUnsafePath, safePaths: safePaths}
4150
}()
4251

4352
type path struct {
4453
homeDir string
4554
configFile string
4655
allowUnsafePath bool
56+
safePaths []string
4757
}
4858

4959
// SetHomeDir is used to set the configuration path
@@ -72,19 +82,22 @@ func (p *path) Resolve(path string) string {
7282
return path
7383
}
7484

75-
// IsSafePath return true if path is a subpath of homedir
85+
// IsSafePath return true if path is a subpath of homedir (or in the SAFE_PATHS environment variable)
7686
func (p *path) IsSafePath(path string) bool {
7787
if p.allowUnsafePath || features.CMFA {
7888
return true
7989
}
8090
homedir := p.HomeDir()
8191
path = p.Resolve(path)
82-
rel, err := filepath.Rel(homedir, path)
83-
if err != nil {
84-
return false
92+
safePaths := append([]string{homedir}, p.safePaths...) // add homedir to safePaths
93+
for _, safePath := range safePaths {
94+
if rel, err := filepath.Rel(safePath, path); err == nil {
95+
if filepath.IsLocal(rel) {
96+
return true
97+
}
98+
}
8599
}
86-
87-
return filepath.IsLocal(rel)
100+
return false
88101
}
89102

90103
func (p *path) GetPathByHash(prefix, name string) string {

constant/path_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package constant
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestPath(t *testing.T) {
9+
assert.False(t, (&path{}).IsSafePath("/usr/share/metacubexd/"))
10+
assert.True(t, (&path{
11+
safePaths: []string{"/usr/share/metacubexd"},
12+
}).IsSafePath("/usr/share/metacubexd/"))
13+
14+
assert.False(t, (&path{}).IsSafePath("../metacubexd/"))
15+
assert.True(t, (&path{
16+
homeDir: "/usr/share/mihomo",
17+
safePaths: []string{"/usr/share/metacubexd"},
18+
}).IsSafePath("../metacubexd/"))
19+
assert.False(t, (&path{
20+
homeDir: "/usr/share/mihomo",
21+
safePaths: []string{"/usr/share/ycad"},
22+
}).IsSafePath("../metacubexd/"))
23+
24+
assert.False(t, (&path{}).IsSafePath("/opt/mykeys/key1.key"))
25+
assert.True(t, (&path{
26+
safePaths: []string{"/opt/mykeys"},
27+
}).IsSafePath("/opt/mykeys/key1.key"))
28+
assert.True(t, (&path{
29+
safePaths: []string{"/opt/mykeys/"},
30+
}).IsSafePath("/opt/mykeys/key1.key"))
31+
assert.True(t, (&path{
32+
safePaths: []string{"/opt/mykeys/key1.key"},
33+
}).IsSafePath("/opt/mykeys/key1.key"))
34+
35+
assert.True(t, (&path{}).IsSafePath("key1.key"))
36+
assert.True(t, (&path{}).IsSafePath("./key1.key"))
37+
assert.True(t, (&path{}).IsSafePath("./mykey/key1.key"))
38+
assert.True(t, (&path{}).IsSafePath("./mykey/../key1.key"))
39+
assert.False(t, (&path{}).IsSafePath("./mykey/../../key1.key"))
40+
41+
}

0 commit comments

Comments
 (0)