mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
* fix: Sandbox profile for Go ecosystem * fix: Sandbox violations for network bind
84 lines
2.7 KiB
Go
84 lines
2.7 KiB
Go
package sandbox
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/safedep/pmg/sandbox/util"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestProfileEnvContract pins the env protection contract as a regression
|
|
// test: npm-restrictive and pypi-restrictive are pure bases that allow
|
|
// nothing, each package manager's leaf profile re-allows only its own auth
|
|
// variables (plus the shared config conventions of its ecosystem), and
|
|
// sibling tokens stay scrubbed alongside other ecosystems' and cloud
|
|
// credentials. Every probe entry is on the built-in deny list, so anything
|
|
// not explicitly expected as kept must be scrubbed. This catches accidental
|
|
// over-broad environment.allow entries.
|
|
func TestProfileEnvContract(t *testing.T) {
|
|
r, err := newDefaultProfileRegistry()
|
|
require.NoError(t, err)
|
|
|
|
env := []string{
|
|
"NPM_TOKEN=x",
|
|
"NODE_AUTH_TOKEN=x",
|
|
"YARN_NPM_AUTH_TOKEN=x",
|
|
"BUN_AUTH_TOKEN=x",
|
|
"TWINE_PASSWORD=x",
|
|
"UV_PUBLISH_TOKEN=x",
|
|
"POETRY_PYPI_TOKEN_PYPI=x",
|
|
"AWS_SECRET_ACCESS_KEY=x",
|
|
"GOOGLE_APPLICATION_CREDENTIALS=x",
|
|
"GITHUB_TOKEN=x",
|
|
"OP_SERVICE_ACCOUNT_TOKEN=x",
|
|
"CLOUDFLARE_API_TOKEN=x",
|
|
}
|
|
|
|
tests := []struct {
|
|
profile string
|
|
wantKept []string
|
|
}{
|
|
{profile: "npm-restrictive", wantKept: []string{}},
|
|
{profile: "pypi-restrictive", wantKept: []string{}},
|
|
{profile: "npm", wantKept: []string{"NPM_TOKEN", "NODE_AUTH_TOKEN"}},
|
|
{profile: "yarn", wantKept: []string{"NPM_TOKEN", "NODE_AUTH_TOKEN", "YARN_NPM_AUTH_TOKEN"}},
|
|
{profile: "bun", wantKept: []string{"NPM_TOKEN", "NODE_AUTH_TOKEN", "BUN_AUTH_TOKEN"}},
|
|
{profile: "pnpm", wantKept: []string{"NPM_TOKEN", "NODE_AUTH_TOKEN"}},
|
|
{profile: "npx", wantKept: []string{"NPM_TOKEN", "NODE_AUTH_TOKEN"}},
|
|
{profile: "pip", wantKept: []string{}},
|
|
{profile: "pipx", wantKept: []string{}},
|
|
{profile: "uv", wantKept: []string{"UV_PUBLISH_TOKEN"}},
|
|
{profile: "uvx", wantKept: []string{"UV_PUBLISH_TOKEN"}},
|
|
{profile: "poetry", wantKept: []string{"POETRY_PYPI_TOKEN_PYPI"}},
|
|
{profile: "go", wantKept: []string{}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.profile, func(t *testing.T) {
|
|
policy, err := r.ResolveProfile(tt.profile, ResolveOptions{})
|
|
require.NoError(t, err)
|
|
|
|
result := util.ScrubEnv(env, util.EnvScrubOptions{
|
|
Allow: policy.Environment.Allow,
|
|
Deny: policy.Environment.Deny,
|
|
})
|
|
|
|
kept := map[string]bool{}
|
|
for _, name := range tt.wantKept {
|
|
kept[name] = true
|
|
}
|
|
|
|
for _, entry := range env {
|
|
name, _, _ := strings.Cut(entry, "=")
|
|
if kept[name] {
|
|
assert.Contains(t, result.Env, entry, "%s should keep %s", tt.profile, name)
|
|
} else {
|
|
assert.Contains(t, result.Removed, name, "%s should scrub %s", tt.profile, name)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|