mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
feat: Add support for policy inheritence (#113)
* feat: Add support for policy inheritence * fix: Linter fixes * Update docs/sandbox.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * fix: Handle boolean inheritence * ci: Add linter * Update sandbox/policy_test.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * fix: Linter fixes * fix: Linter fixes * fix: Sandbox rule regex format --------- Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/safedep/dry/utils"
|
||||
"github.com/safedep/pmg/sandbox"
|
||||
"github.com/safedep/pmg/sandbox/util"
|
||||
)
|
||||
@@ -138,7 +139,7 @@ func generateMoveBlockingRules(pathPatterns []string, logTag string) []string {
|
||||
if util.ContainsGlob(pathPattern) {
|
||||
// For glob patterns, use regex matching for precise pattern enforcement
|
||||
regexPattern := util.GlobToRegex(pathPattern)
|
||||
rules = append(rules, fmt.Sprintf("(deny file-write-unlink (regex \"%s\") (with message \"%s\"))", regexPattern, logTag))
|
||||
rules = append(rules, fmt.Sprintf("(deny file-write-unlink (regex #\"%s\") (with message \"%s\"))", regexPattern, logTag))
|
||||
|
||||
// Also block moving the base directory to prevent bypass
|
||||
baseDir := extractBaseDir(pathPattern)
|
||||
@@ -358,7 +359,7 @@ func (t *seatbeltPolicyTranslator) translate(policy *sandbox.SandboxPolicy) (str
|
||||
}
|
||||
|
||||
// PTY support (optional)
|
||||
if policy.AllowPTY {
|
||||
if utils.SafelyGetValue(policy.AllowPTY) {
|
||||
sb.WriteString(";; Pseudo-terminal (PTY) support\n")
|
||||
sb.WriteString("(allow pseudo-tty)\n")
|
||||
sb.WriteString("(allow file-ioctl\n")
|
||||
@@ -390,7 +391,7 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
globDoubleStarAutoAllowParentDirIfNeeded(sb, pattern, expanded, "file-read*")
|
||||
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(allow file-read* (regex \"%s\"))\n", regexPattern))
|
||||
sb.WriteString(fmt.Sprintf("(allow file-read* (regex #\"%s\"))\n", regexPattern))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(allow file-read* (subpath \"%s\"))\n", expanded))
|
||||
}
|
||||
@@ -424,7 +425,7 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
globDoubleStarAutoAllowParentDirIfNeeded(sb, pattern, expanded, "file-write*")
|
||||
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(allow file-write* (regex \"%s\"))\n", regexPattern))
|
||||
sb.WriteString(fmt.Sprintf("(allow file-write* (regex #\"%s\"))\n", regexPattern))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(allow file-write* (subpath \"%s\"))\n", expanded))
|
||||
}
|
||||
@@ -444,7 +445,7 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
// Use regex matching for glob patterns, subpath for literals
|
||||
if util.ContainsGlob(expanded) {
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (regex \"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (regex #\"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (subpath \"%s\") (with message \"%s\"))\n", expanded, t.logTag))
|
||||
}
|
||||
@@ -471,7 +472,7 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
// Use regex matching for glob patterns, subpath for literals
|
||||
if util.ContainsGlob(expanded) {
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (regex \"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (regex #\"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (subpath \"%s\") (with message \"%s\"))\n", expanded, t.logTag))
|
||||
}
|
||||
@@ -483,7 +484,7 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
if t.enableDangerousFileBlocking {
|
||||
// Add mandatory deny patterns for security (credentials, git hooks, etc.)
|
||||
sb.WriteString(";; Mandatory security denies (credentials, git hooks, etc.)\n")
|
||||
mandatoryDenies := util.GetMandatoryDenyPatterns(policy.AllowGitConfig)
|
||||
mandatoryDenies := util.GetMandatoryDenyPatterns(utils.SafelyGetValue(policy.AllowGitConfig))
|
||||
for _, pattern := range mandatoryDenies {
|
||||
// Expand variables if needed
|
||||
expanded, err := util.ExpandVariables(pattern)
|
||||
@@ -494,8 +495,8 @@ func (t *seatbeltPolicyTranslator) translateFilesystem(policy *sandbox.SandboxPo
|
||||
// Use regex matching for glob patterns, subpath for literals
|
||||
if util.ContainsGlob(expanded) {
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (regex \"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (regex \"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (regex #\"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (regex #\"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(deny file-write* (subpath \"%s\") (with message \"%s\"))\n", expanded, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny file-read* (subpath \"%s\") (with message \"%s\"))\n", expanded, t.logTag))
|
||||
@@ -571,7 +572,7 @@ func (t *seatbeltPolicyTranslator) translateProcess(policy *sandbox.SandboxPolic
|
||||
if util.ContainsGlob(expanded) {
|
||||
// For glob patterns, use regex matching for precise control
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(allow process-exec* (regex \"%s\"))\n", regexPattern))
|
||||
sb.WriteString(fmt.Sprintf("(allow process-exec* (regex #\"%s\"))\n", regexPattern))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(allow process-exec* (literal \"%s\"))\n", expanded))
|
||||
}
|
||||
@@ -589,7 +590,7 @@ func (t *seatbeltPolicyTranslator) translateProcess(policy *sandbox.SandboxPolic
|
||||
if util.ContainsGlob(expanded) {
|
||||
// For glob patterns, use regex matching for precise control
|
||||
regexPattern := util.GlobToRegex(expanded)
|
||||
sb.WriteString(fmt.Sprintf("(deny process-exec* (regex \"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
sb.WriteString(fmt.Sprintf("(deny process-exec* (regex #\"%s\") (with message \"%s\"))\n", regexPattern, t.logTag))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("(deny process-exec* (literal \"%s\") (with message \"%s\"))\n", expanded, t.logTag))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user