summaryrefslogtreecommitdiff
path: root/src/Agent.Windows/Security/PathPolicy.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Agent.Windows/Security/PathPolicy.cs')
-rw-r--r--src/Agent.Windows/Security/PathPolicy.cs9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/Agent.Windows/Security/PathPolicy.cs b/src/Agent.Windows/Security/PathPolicy.cs
index 32a949c..4f6eec4 100644
--- a/src/Agent.Windows/Security/PathPolicy.cs
+++ b/src/Agent.Windows/Security/PathPolicy.cs
@@ -17,7 +17,8 @@ public sealed class PathPolicy(IEnumerable<FilePolicyEntry> entries)
public void Demand(string path, FileCapability required)
{
- if (!IsAllowed(path, required)) throw new SandboxPolicyException("policy.deny", $"'{path}' is not approved for {required}.");
+ if (!IsAllowed(path, required))
+ throw new SandboxPolicyException("policy.deny", $"'{path}' is not approved for {required}. Add the canonical path to sandbox.filesystem.{required.ToString().ToLowerInvariant()} and restart the server.");
}
private static bool IsAtOrBelow(string candidate, string root) =>
@@ -39,7 +40,11 @@ public static class CanonicalPath
current = Path.Combine(current, segment);
if (!File.Exists(current) && !Directory.Exists(current)) continue;
if ((File.GetAttributes(current) & FileAttributes.ReparsePoint) != 0)
- throw new SandboxPolicyException("path.reparse", $"Reparse points are not allowed: '{current}'.");
+ {
+ FileSystemInfo info = Directory.Exists(current) ? new DirectoryInfo(current) : new FileInfo(current);
+ string? target = info.ResolveLinkTarget(returnFinalTarget: true)?.FullName ?? info.LinkTarget;
+ throw new SandboxPolicyException("path.reparse", $"Reparse points are not allowed: component='{current}'. Approve the resolved canonical target{(string.IsNullOrWhiteSpace(target) ? string.Empty : $" '{Path.GetFullPath(target)}'")} instead.");
+ }
}
if (requireExisting && !File.Exists(fullPath) && !Directory.Exists(fullPath)) throw new FileNotFoundException("Approved path does not exist.", fullPath);
return Path.TrimEndingDirectorySeparator(fullPath);