Private/Security/Paths.ps1

function Test-VSOWithin {
    param([string]$Path, [string]$Root, [switch]$AllowEqual)
    $base=[IO.Path]::GetFullPath($Root).TrimEnd('\','/')
    $full=[IO.Path]::GetFullPath($Path).TrimEnd('\','/')
    if ($AllowEqual -and $full.Equals($base,[StringComparison]::OrdinalIgnoreCase)) { return $true }
    return $full.StartsWith($base+'\',[StringComparison]::OrdinalIgnoreCase)
}

function Assert-VSONoReparse {
    param([string]$Path, $Context)
    $cursor=[IO.Path]::GetFullPath($Path)
    while ($cursor) {
        # Get-Item, rather than Test-Path alone, also inspects dangling links.
        $item=Get-Item -LiteralPath $cursor -Force -ErrorAction SilentlyContinue
        if ($null -ne $item -and ($item.Attributes -band [IO.FileAttributes]::ReparsePoint)) { Throw-VSOError $Context Reparse @($cursor) }
        $parent=[IO.Path]::GetDirectoryName($cursor)
        if ($parent -eq $cursor) { break }; $cursor=$parent
    }
}

function Resolve-VSOPath {
    param([string]$Path, $Context, [switch]$Installation)
    if ([string]::IsNullOrWhiteSpace($Path) -or $Path -notmatch '^[A-Za-z]:[\\/]' -or $Path.Substring(2) -match '[:*?"<>|\x00-\x1f]' -or $Path -match '[%!&^()]') { Throw-VSOError $Context Path @($Path) }
    foreach ($component in ($Path.Substring(3) -split '[\\/]')) {
        if ($component -in @('.','..') -or $component -match '[. ]$|^(?i:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)') { Throw-VSOError $Context Path @($Path) }
    }
    $full=[IO.Path]::GetFullPath($Path).TrimEnd('\','/')
    # Reserve room for sibling staging/journal names under Windows PowerShell's
    # legacy filesystem APIs. The payload child is not a second installation root.
    $maximum=if ($Installation) {160}else{240}
    if ($full.Length -le 3 -or $full.Length -gt $maximum) { Throw-VSOError $Context Path @($Path) }
    Assert-VSONoReparse $full $Context
    if ($Installation) {
        $windows=[Environment]::GetFolderPath([Environment+SpecialFolder]::Windows)
        $protected=@($windows,$env:SystemRoot,$env:ProgramFiles,${env:ProgramFiles(x86)},$env:ProgramData,$env:USERPROFILE,$env:LOCALAPPDATA,$env:APPDATA,$script:ModuleRoot)
        foreach ($root in $protected) {
            if ($root -and ((Test-VSOWithin $root $full -AllowEqual) -or ($root -in @($windows,$env:SystemRoot) -and (Test-VSOWithin $full $root -AllowEqual)))) { Throw-VSOError $Context Path @($full) }
        }
        foreach ($root in @([IO.Path]::GetTempPath(),(Join-Path $env:SystemRoot 'Temp'))) {
            if (Test-VSOWithin $full $root -AllowEqual) { Throw-VSOError $Context Temporary }
        }
    }
    return $full
}

function Join-VSOChild {
    param([string]$Root, [string]$Relative, $Context)
    if ([string]::IsNullOrWhiteSpace($Relative) -or [IO.Path]::IsPathRooted($Relative) -or $Relative -match '[:*?"<>|\x00-\x1f]' -or $Relative -match '[\\/]$') { Throw-VSOError $Context Path @($Relative) }
    foreach ($piece in ($Relative -split '[\\/]')) {
        if (-not $piece -or $piece -in @('.','..') -or $piece -match '[. ]$|^(?i:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)') { Throw-VSOError $Context Path @($Relative) }
    }
    $path=[IO.Path]::GetFullPath((Join-Path $Root $Relative))
    if (-not (Test-VSOWithin $path $Root)) { Throw-VSOError $Context Path @($Relative) }
    Assert-VSONoReparse $path $Context
    return $path
}

function Get-VSODefaultPath {
    param([string]$Scope, $Context)
    $base=if ($Scope -eq 'AllUsers') { $env:ProgramFiles } else { $env:LOCALAPPDATA }
    if (-not $base) { Throw-VSOError $Context Path @($Scope) }
    if ($Scope -eq 'CurrentUser') { return (Join-Path $base 'Programs\VSO') }
    return (Join-Path $base 'VSO')
}

function Assert-VSOProtectedDirectory {
    param([string]$Path, $Context, [switch]$UserAllowed)
    Assert-VSONoReparse $Path $Context
    $acl=Get-Acl -LiteralPath $Path -ErrorAction Stop
    $allowed=@('S-1-5-18','S-1-5-32-544','S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464')
    if ($UserAllowed) { $allowed += [Security.Principal.WindowsIdentity]::GetCurrent().User.Value }
    $writeMask=[Security.AccessControl.FileSystemRights]::Write -bor [Security.AccessControl.FileSystemRights]::Delete -bor [Security.AccessControl.FileSystemRights]::DeleteSubdirectoriesAndFiles -bor [Security.AccessControl.FileSystemRights]::ChangePermissions -bor [Security.AccessControl.FileSystemRights]::TakeOwnership
    foreach ($rule in $acl.GetAccessRules($true,$true,[Security.Principal.SecurityIdentifier])) {
        if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Allow -and ($rule.FileSystemRights -band $writeMask) -and $rule.IdentityReference.Value -notin $allowed -and -not ($rule.PropagationFlags -band [Security.AccessControl.PropagationFlags]::InheritOnly)) { Throw-VSOError $Context ProtectedParent }
    }
    $owner=$acl.GetOwner([Security.Principal.SecurityIdentifier]).Value
    if ($owner -notin $allowed) { Throw-VSOError $Context ProtectedParent }
}

function New-VSOSecureDirectory {
    param([string]$Path, [string]$Scope, $Context)
    Assert-VSONoReparse $Path $Context
    if ([IO.Directory]::Exists($Path)) { Assert-VSOProtectedDirectory $Path $Context -UserAllowed:($Scope -eq 'CurrentUser'); return }
    $acl=[Security.AccessControl.DirectorySecurity]::new()
    $acl.SetAccessRuleProtection($true,$false)
    $inherit=[Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit'
    $none=[Security.AccessControl.PropagationFlags]::None
    $allow=[Security.AccessControl.AccessControlType]::Allow
    $identities=@('S-1-5-18','S-1-5-32-544')
    if ($Scope -eq 'CurrentUser') { $identities += [Security.Principal.WindowsIdentity]::GetCurrent().User.Value }
    foreach ($sid in $identities) { $acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new([Security.Principal.SecurityIdentifier]::new($sid),[Security.AccessControl.FileSystemRights]::FullControl,$inherit,$none,$allow)) }
    if ($Scope -eq 'AllUsers') { $acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new([Security.Principal.SecurityIdentifier]::new('S-1-5-32-545'),[Security.AccessControl.FileSystemRights]::ReadAndExecute,$inherit,$none,$allow)) }
    $owner=if ($Scope -eq 'AllUsers') { 'S-1-5-32-544' } else { [Security.Principal.WindowsIdentity]::GetCurrent().User.Value }
    $acl.SetOwner([Security.Principal.SecurityIdentifier]::new($owner))
    # Framework's overload creates with ACLs; Core uses the FileSystemAclExtensions API.
    if ($PSVersionTable.PSEdition -eq 'Desktop') { [void][IO.Directory]::CreateDirectory($Path,$acl) }
    else { [IO.FileSystemAclExtensions]::Create([IO.DirectoryInfo]::new($Path),$acl) }
    Assert-VSOProtectedDirectory $Path $Context -UserAllowed:($Scope -eq 'CurrentUser')
}

function Get-VSOTreeFiles {
    param([string]$Root, $Context, [int]$Limit = 20000)
    $pending=[Collections.Generic.Stack[string]]::new(); $pending.Push($Root); $count=0
    while ($pending.Count) {
        $dir=$pending.Pop(); Assert-VSONoReparse $dir $Context
        foreach ($item in @(Get-ChildItem -LiteralPath $dir -Force -ErrorAction Stop)) {
            if ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) { Throw-VSOError $Context Reparse @($item.FullName) }
            if ($item.PSIsContainer) { $pending.Push($item.FullName) }
            else { $count++; if ($count -gt $Limit) { Throw-VSOError $Context Archive @('file count') }; $item }
        }
    }
}

function Remove-VSOPrivateTree {
    param([string]$Path, [string]$Parent, $Context)
    if (-not (Test-VSOWithin $Path $Parent) -or [IO.Path]::GetFileName($Path) -notmatch '^\.vso-(work|txn)-[a-f0-9]{32}$') { Throw-VSOError $Context Path @($Path) }
    if ([IO.Directory]::Exists($Path)) {
        $null=@(Get-VSOTreeFiles $Path $Context)
        Assert-VSONoReparse $Path $Context
        Remove-Item -LiteralPath $Path -Recurse -Force -ErrorAction Stop
    }
}