source dump of claude code
at main 211 lines 7.2 kB view raw
1/** 2 * PowerShell Constrained Language Mode allowed types. 3 * 4 * Microsoft's CLM restricts .NET type usage to this allowlist when PS runs 5 * under AppLocker/WDAC system lockdown. Any type NOT in this set is considered 6 * unsafe for untrusted code execution. 7 * 8 * We invert this: type literals not in this set → ask. One canonical check 9 * replaces enumerating individual dangerous types (named pipes, reflection, 10 * process spawning, P/Invoke marshaling, etc.). Microsoft maintains the list. 11 * 12 * Source: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_language_modes 13 * 14 * Normalization: entries stored lowercase, short AND full names where both 15 * exist (PS resolves type accelerators like [int] → System.Int32 at runtime; 16 * we match against what the AST emits, which is the literal text). 17 */ 18export const CLM_ALLOWED_TYPES: ReadonlySet<string> = new Set( 19 [ 20 // Type accelerators (short names as they appear in AST TypeName.Name) 21 // SECURITY: 'adsi' and 'adsisearcher' REMOVED. Both are Active Directory 22 // Service Interface types that perform NETWORK BINDS when cast: 23 // [adsi]'LDAP://evil.com/...' → connects to LDAP server 24 // [adsisearcher]'(objectClass=user)' → binds to AD and queries 25 // Microsoft's CLM allows these because it's for Windows admins in trusted 26 // domains; we block them since the target isn't validated. 27 'alias', 28 'allowemptycollection', 29 'allowemptystring', 30 'allownull', 31 'argumentcompleter', 32 'argumentcompletions', 33 'array', 34 'bigint', 35 'bool', 36 'byte', 37 'char', 38 'cimclass', 39 'cimconverter', 40 'ciminstance', 41 // 'cimsession' REMOVED — see wmi/adsi comment below 42 'cimtype', 43 'cmdletbinding', 44 'cultureinfo', 45 'datetime', 46 'decimal', 47 'double', 48 'dsclocalconfigurationmanager', 49 'dscproperty', 50 'dscresource', 51 'experimentaction', 52 'experimental', 53 'experimentalfeature', 54 'float', 55 'guid', 56 'hashtable', 57 'int', 58 'int16', 59 'int32', 60 'int64', 61 'ipaddress', 62 'ipendpoint', 63 'long', 64 'mailaddress', 65 'norunspaceaffinity', 66 'nullstring', 67 'objectsecurity', 68 'ordered', 69 'outputtype', 70 'parameter', 71 'physicaladdress', 72 'pscredential', 73 'pscustomobject', 74 'psdefaultvalue', 75 'pslistmodifier', 76 'psobject', 77 'psprimitivedictionary', 78 'pstypenameattribute', 79 'ref', 80 'regex', 81 'sbyte', 82 'securestring', 83 'semver', 84 'short', 85 'single', 86 'string', 87 'supportswildcards', 88 'switch', 89 'timespan', 90 'uint', 91 'uint16', 92 'uint32', 93 'uint64', 94 'ulong', 95 'uri', 96 'ushort', 97 'validatecount', 98 'validatedrive', 99 'validatelength', 100 'validatenotnull', 101 'validatenotnullorempty', 102 'validatenotnullorwhitespace', 103 'validatepattern', 104 'validaterange', 105 'validatescript', 106 'validateset', 107 'validatetrusteddata', 108 'validateuserdrive', 109 'version', 110 'void', 111 'wildcardpattern', 112 // SECURITY: 'wmi', 'wmiclass', 'wmisearcher', 'cimsession' REMOVED. 113 // WMI type casts perform WMI queries which can target remote computers 114 // (network request) and access dangerous classes like Win32_Process. 115 // cimsession creates a CIM session (network connection to remote host). 116 // [wmi]'\\evil-host\root\cimv2:Win32_Process.Handle="1"' → remote WMI 117 // [wmisearcher]'SELECT * FROM Win32_Process' → runs WQL query 118 // Same rationale as adsi/adsisearcher removal above. 119 'x500distinguishedname', 120 'x509certificate', 121 'xml', 122 // Full names for accelerators that resolve to System.* (AST may emit either) 123 'system.array', 124 'system.boolean', 125 'system.byte', 126 'system.char', 127 'system.datetime', 128 'system.decimal', 129 'system.double', 130 'system.guid', 131 'system.int16', 132 'system.int32', 133 'system.int64', 134 'system.numerics.biginteger', 135 'system.sbyte', 136 'system.single', 137 'system.string', 138 'system.timespan', 139 'system.uint16', 140 'system.uint32', 141 'system.uint64', 142 'system.uri', 143 'system.version', 144 'system.void', 145 'system.collections.hashtable', 146 'system.text.regularexpressions.regex', 147 'system.globalization.cultureinfo', 148 'system.net.ipaddress', 149 'system.net.ipendpoint', 150 'system.net.mail.mailaddress', 151 'system.net.networkinformation.physicaladdress', 152 'system.security.securestring', 153 'system.security.cryptography.x509certificates.x509certificate', 154 'system.security.cryptography.x509certificates.x500distinguishedname', 155 'system.xml.xmldocument', 156 // System.Management.Automation.* — FQ equivalents of PS-specific accelerators 157 'system.management.automation.pscredential', 158 'system.management.automation.pscustomobject', 159 'system.management.automation.pslistmodifier', 160 'system.management.automation.psobject', 161 'system.management.automation.psprimitivedictionary', 162 'system.management.automation.psreference', 163 'system.management.automation.semanticversion', 164 'system.management.automation.switchparameter', 165 'system.management.automation.wildcardpattern', 166 'system.management.automation.language.nullstring', 167 // Microsoft.Management.Infrastructure.* — FQ equivalents of CIM accelerators 168 // SECURITY: cimsession FQ REMOVED — same network-bind hazard as short name 169 // (creates a CIM session to a remote host). 170 'microsoft.management.infrastructure.cimclass', 171 'microsoft.management.infrastructure.cimconverter', 172 'microsoft.management.infrastructure.ciminstance', 173 'microsoft.management.infrastructure.cimtype', 174 // FQ equivalents of remaining short-name accelerators 175 // SECURITY: DirectoryEntry/DirectorySearcher/ManagementObject/ 176 // ManagementClass/ManagementObjectSearcher FQ REMOVED — same network-bind 177 // hazard as short names adsi/adsisearcher/wmi/wmiclass/wmisearcher 178 // (LDAP bind, remote WMI). See short-name removal comments above. 179 'system.collections.specialized.ordereddictionary', 180 'system.security.accesscontrol.objectsecurity', 181 // Arrays of allowed types are allowed (e.g. [string[]]) 182 // normalizeTypeName strips [] before lookup, so store the base name 183 'object', 184 'system.object', 185 // ModuleSpecification — full qualified name 186 'microsoft.powershell.commands.modulespecification', 187 ].map(t => t.toLowerCase()), 188) 189 190/** 191 * Normalize a type name from AST TypeName.FullName or TypeName.Name. 192 * Handles array suffix ([]) and generic brackets. 193 */ 194export function normalizeTypeName(name: string): string { 195 // Strip array suffix: "String[]" → "string" (arrays of allowed types are allowed) 196 // Strip generic args: "List[int]" → "list" (conservative — the generic wrapper 197 // might be unsafe even if the type arg is safe, so we check the outer type) 198 return name 199 .toLowerCase() 200 .replace(/\[\]$/, '') 201 .replace(/\[.*\]$/, '') 202 .trim() 203} 204 205/** 206 * True if typeName (from AST) is in Microsoft's CLM allowlist. 207 * Types NOT in this set trigger ask — they access system APIs CLM blocks. 208 */ 209export function isClmAllowedType(typeName: string): boolean { 210 return CLM_ALLOWED_TYPES.has(normalizeTypeName(typeName)) 211}