发布日期:2025 年 2 月 25 日
版本:.NET 8 及更高版本.NET Framework所有版本
摘要
Microsoft已对最新版本的 Windows 进行了安全改进。 这些安全改进会修改临时路径处理,并可能导致某些.NET Framework和 .NET API(如System.IO.Path.GetTempPath())在应用修补程序后返回其他位置。
所需作
任何.NET Framework 或 都不需要执行任何作。基于 NET 的应用程序。 应用程序将自动受益于适用于你的环境的任何安全改进。 大多数应用程序不会观察到任何行为更改。
本文的其余部分详细介绍了如何确定这些安全改进是否可能会影响应用程序的运行时行为。 本文还列出了根据需要自定义运行时行为的步骤
适用的软件
本文适用于以下软件:
-
.NET 8 及更高版本
-
.NET Framework,自 2024 年 7 月安全更新和后续更新起的所有版本
仅当在以下 Windows 更新版本上运行时:
-
安装 KB5052077 时Windows 10版本 22H2
-
Windows Server 2019,安装KB5053594时
-
Windows Server 2016安装KB5053594时
本文不适用于在 Windows 11、Windows Server 2022 或更高版本上运行的 .NET Framework 或 .NET。
在非 Windows 平台上运行时,本文 不适用于 .NET。
详细说明和影响声明
从上述 Windows 更新 KB 开始,Microsoft已将 Win32 GetTempPath2 API 向后移植到较旧的 Windows 市场内版本,以充当较旧的 Win32 GetTempPath API 的更安全的替代品。 在内部,.NET Framework和 .NET 依赖于这些 Win32 API 来提供 System.IO.Path.GetTempPath() 方法的实现:Win32 GetTempPath2 API 是首选的(如果存在);如果不存在 GetTempPath2,则使用 Win32 GetTempPath API 作为回退。
由于这些 KB 使新的 Win32 GetTempPath2 API 在适用的平台上可用,因此安装 KB 后,.NET Framework 和 .NET 将开始使用 GetTempPath2。
主要行为更改是,作为 SYSTEM 标识运行的调用方将默认观察 System.IO.Path.GetTempPath() 方法返回 %WINDIR%\SystemTemp ,而作为 SYSTEM 标识以外的任何对象的调用方将观察 方法继续返回其现有值。
如果应用程序满足以下 所有 条件,则可能会受到此更改的影响:
-
应用程序使用前面“适用软件”标题下列出的运行时和 OS 平台;和
-
应用程序作为 SYSTEM 标识运行;和
-
手动设置 %TMP% 或 %TEMP% 环境变量以重定向标准临时文件位置。 (请参阅 Win32 GetTempPath API 文档的 “备注”部分 。)
如果满足 所有这些 条件,则安装 Windows KB 后,你可能会看到应用程序写入临时目录,而不是预期目录。
此行为更改可以通过任何.NET Framework 或 可见。NET 提供的 API,最终依赖于 GetTempPath2。 最常见的入口点是:
这不是一个详尽的方法列表,其行为可能会在安装 KB 后更改。
确定应用程序是否在 SYSTEM 标识下运行
有几种不同的机制可用于确定.NET Framework或 .NET 应用程序的标识
基于 IIS 的 Web 应用程序
IIS 将 SYSTEM 标识称为“LOCALSYSTEM”。 在 IIS 管理器 (inetmgr.exe) ,转到“应用程序池”选项卡,查看所有应用池及其关联的标识。 还可以从“ 分组 依据”下拉列表中选择“标识”,以便更轻松地查看作为 LOCALSYSTEM 标识运行的应用池。
下面的屏幕截图显示了 (“MyAppPool”) 配置为以 LOCALSYSTEM 运行的应用池示例。 在此应用池中运行的任何应用程序都将作为 SYSTEM 标识运行。
还可以使用以下脚本从提升的 PowerShell 会话以编程方式访问此信息。
Import-Module IISAdministration Get-IISAppPool | where {$_.ProcessModel.IdentityType -eq "LocalSystem"}
在配置了系统级“MyAppPool”应用池的计算机中,如上面的屏幕截图所示,此 PowerShell 脚本输出以下内容,显示“MyAppPool”正在 SYSTEM 标识下运行。
Name Status CLR Ver Pipeline Mode Start Mode ---- ------ ------- ------------- ---------- MyAppPool Started v4.0 Integrated OnDemand
Windows 服务
如果.NET Framework或 。基于 NET 的应用程序注册为 Windows 服务,可以使用服务管理器查看其关联标识。
在提升的命令提示符下,运行 services.msc。 这将显示服务管理器 UI。
如果 “登录 方式”列列出了服务标识的“本地系统”,则服务在 SYSTEM 标识下运行。
还可以使用 Get-Service cmdlet 通过 PowerShell 查询此数据。 例如,若要查询名为 MyService服务的此信息,请使用以下命令。
(Get-Service MyService).UserName -ieq "LocalSystem"
如果服务注册为在 SYSTEM 标识下运行,则会将 True 打印到控制台。
其他机制
任务管理器 (taskmgr.exe) 或 Sysinternals 进程资源管理器 等工具还可以告诉你应用程序是否在 SYSTEM 标识下运行。
在任务管理器中,使用“详细信息”视图列出系统中所有正在运行的进程,然后找到感兴趣的进程并查看 “用户名” 列下的条目。
如果 “用户名 ”值显示为“SYSTEM”,则进程在 SYSTEM 标识下运行。
或者,在 Sysinternals 进程资源管理器中,找到感兴趣的进程并进入 “属性” 视图,然后查看“ 图像 ”选项卡下的“用户”字段。
如果 User 值读取“NT AUTHORITY\SYSTEM”,则进程在 SYSTEM 标识下运行。
更改系统级进程的临时路径
下面的 PowerShell 脚本演示如何创建新目录 C:\NewSystemTemp\ 并将目录访问限制为仅在 SYSTEM 标识下运行的进程。 请勿尝试更改已填充文件的目录的 ACL。
必须从提升的 PowerShell 会话运行此脚本。
mkdir C:\NewSystemTemp\ $acl = New-Object System.Security.AccessControl.DirectorySecurity $acl.SetSecurityDescriptorSddlForm("O:SYG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)") Set-Acl C:\NewSystemTemp\ -AclObject $acl
可以通过运行 命令来确认此作是否成功
icacls C:\NewSystemTemp\
这将生成以下输出,显示成功:
C:\NewSystemTemp\ NT AUTHORITY\SYSTEM:(OI)(CI)(F) BUILTIN\Administrators:(OI)(CI)(F) Successfully processed 1 files; Failed processing 0 files
创建目录后,使用系统级范围设置 %SYSTEMTEMP% 环境变量。 可以通过系统控制面板 UI 进行设置,也可以通过 PowerShell 以编程方式进行设置:
[Environment]::SetEnvironmentVariable("SYSTEMTEMP", "C:\NewSystemTemp", [EnvironmentVariableTarget]::Machine)
然后重新启动计算机。
更改 %SYSTEMTEMP% 环境变量不会更改作为 SYSTEM 以外的标识运行的.NET Framework和 .NET 应用程序的 System.IO.Path.GetTempPath() 的返回值。 这些应用程序将继续遵循其始终具有的相同解析逻辑,包括遵循 %TMP% 或 %TEMP% 环境变量(如果存在)。
同样,设置 %TMP% 或 %TEMP% 环境变量不会更改作为 SYSTEM 标识运行的.NET Framework和 .NET 应用程序的 System.IO.Path.GetTempPath() 的返回值。
有关详细信息
有关.NET Framework和 .NET 行为的详细信息,请参阅 Path.GetTempPath 上的 .NET 文档。
有关基础 Windows OS 行为的详细信息,请参阅 Win32 GetTempPath2 API 上的 Windows 文档。