41 lines
1.9 KiB
TypeScript
41 lines
1.9 KiB
TypeScript
/**
|
|
* Canonical directory-boundary checks for the Windows ACL workspace and
|
|
* private-temp capabilities.
|
|
* @module @deepseek-ai/dsh-sandbox-windows-acl/path-boundary
|
|
*/
|
|
|
|
import { realpathSync } from 'node:fs'
|
|
import { isAbsolute, relative, sep } from 'node:path'
|
|
|
|
/** Whether `root` is the same canonical directory as `candidate` or contains it. */
|
|
function containsDirectory(root: string, candidate: string): boolean {
|
|
const relation = relative(realpathSync.native(root), realpathSync.native(candidate))
|
|
return relation === '' || (!isAbsolute(relation) && relation !== '..' && !relation.startsWith(`..${sep}`))
|
|
}
|
|
|
|
/**
|
|
* Reject a temp parent that is inside the workspace: every child created
|
|
* below it would inherit the standing workspace capability.
|
|
* @param workspaceRoot - the canonical workspace root that receives the standing ACE.
|
|
* @param tempRoot - the existing parent beneath which a private temp child would be created.
|
|
*/
|
|
export function assertTempRootOutsideWorkspace(workspaceRoot: string, tempRoot: string): void {
|
|
if (containsDirectory(workspaceRoot, tempRoot)) {
|
|
throw new Error(`Windows ACL temp root must be outside the workspace: workspace=${workspaceRoot}; temp=${tempRoot}`)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reject overlap between an actual private temp directory and any writable
|
|
* directory: either inheritance direction would merge the two capabilities.
|
|
* @param writableDirs - directories carrying the standing workspace capability.
|
|
* @param tempDir - the existing directory carrying the revocable temp capability.
|
|
*/
|
|
export function assertPrivateTempDisjoint(writableDirs: readonly string[], tempDir: string): void {
|
|
for (const writableDir of writableDirs) {
|
|
if (containsDirectory(writableDir, tempDir) || containsDirectory(tempDir, writableDir)) {
|
|
throw new Error(`AclSandbox private temp directory must be disjoint from writable directories: writable=${writableDir}; temp=${tempDir}`)
|
|
}
|
|
}
|
|
}
|