feat(coredeno): permission engine for I/O fortress
CheckPath (prefix-based), CheckNet (exact match), CheckRun (exact match). Empty allowed list = deny all. Secure by default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
026dd00ed4
commit
3399994977
2 changed files with 82 additions and 0 deletions
42
pkg/coredeno/permissions.go
Normal file
42
pkg/coredeno/permissions.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package coredeno
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CheckPath returns true if the given path is under any of the allowed prefixes.
|
||||||
|
// Empty allowed list means deny all (secure by default).
|
||||||
|
func CheckPath(path string, allowed []string) bool {
|
||||||
|
if len(allowed) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
clean := filepath.Clean(path)
|
||||||
|
for _, prefix := range allowed {
|
||||||
|
cleanPrefix := filepath.Clean(prefix)
|
||||||
|
if strings.HasPrefix(clean, cleanPrefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckNet returns true if the given host:port is in the allowed list.
|
||||||
|
func CheckNet(addr string, allowed []string) bool {
|
||||||
|
for _, a := range allowed {
|
||||||
|
if a == addr {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRun returns true if the given command is in the allowed list.
|
||||||
|
func CheckRun(cmd string, allowed []string) bool {
|
||||||
|
for _, a := range allowed {
|
||||||
|
if a == cmd {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
40
pkg/coredeno/permissions_test.go
Normal file
40
pkg/coredeno/permissions_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
package coredeno
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckPath_Good_Allowed(t *testing.T) {
|
||||||
|
allowed := []string{"./data/", "./config/"}
|
||||||
|
assert.True(t, CheckPath("./data/file.txt", allowed))
|
||||||
|
assert.True(t, CheckPath("./config/app.json", allowed))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckPath_Bad_Denied(t *testing.T) {
|
||||||
|
allowed := []string{"./data/"}
|
||||||
|
assert.False(t, CheckPath("./secrets/key.pem", allowed))
|
||||||
|
assert.False(t, CheckPath("../escape/file", allowed))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckPath_Good_EmptyDenyAll(t *testing.T) {
|
||||||
|
assert.False(t, CheckPath("./anything", nil))
|
||||||
|
assert.False(t, CheckPath("./anything", []string{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckNet_Good_Allowed(t *testing.T) {
|
||||||
|
allowed := []string{"pool.lthn.io:3333", "api.lthn.io:443"}
|
||||||
|
assert.True(t, CheckNet("pool.lthn.io:3333", allowed))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckNet_Bad_Denied(t *testing.T) {
|
||||||
|
allowed := []string{"pool.lthn.io:3333"}
|
||||||
|
assert.False(t, CheckNet("evil.com:80", allowed))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckRun_Good(t *testing.T) {
|
||||||
|
allowed := []string{"xmrig", "sha256sum"}
|
||||||
|
assert.True(t, CheckRun("xmrig", allowed))
|
||||||
|
assert.False(t, CheckRun("rm", allowed))
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue