summaryrefslogtreecommitdiff
path: root/src/Agent.Windows/Security/PathPolicy.cs
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-11 21:44:53 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-11 21:44:53 +0900
commit6c3458a5ec37a5b69957ad17c84de58984698f25 (patch)
treebe5c5716e7488fcf1bc1a58de0ded0b9238f34cb /src/Agent.Windows/Security/PathPolicy.cs
parentb5ccecca01007f2a2459265df6d749fbfd31aa84 (diff)
Audit and align v1 runtime design
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);