IIS/Nginx 文件上传安全:阻断 upload-to-RCE
校验上传、存到可执行根之外、在上传路径禁脚本执行,并防路径遍历。
测试环境Standard / Datacenter · 版本号 26100.33650 · x64
E1- 版本号
- 26100.33650
- 版本
- Standard / Datacenter
- 架构
- x64
- 支持
- 文档(E1)
- 证据
- E1官方文档
- 核验日期
- 2026-10-29
- 页面类型
- 任务
上传危险是三件事同时成立:
- 文件落在 IIS/Nginx 服务的路径;
- 服务器执行该扩展名(
.php、.asp、.aspx、.cgi); - 攻击者控制名字/内容。
至少破坏两个。最好存到 Web 根之外,通过受控处理器下载。
- 扩展名和 MIME 白名单;不要只信
Content-Type。 - 代理 + 应用都限制大小。
- 存储名随机;原名只做元数据。
- 能重编码图片就重编码;去 EXIF。
- 业务允许就 AV/EDR 扫描。
- 上传放站点根之外,或放无脚本处理器目录。
- 下载用
Content-Disposition: attachment+ 安全 content type。
拒绝/规范化:
../、..\、编码%2e%2e%2f、双重编码;- 绝对路径(
C:\、\\server\share); - NUL 字节和 ADS(
file.php::$DATA)。
不要只用 Path.Combine 拼用户输入;解析规范路径并确认仍在上传根之下。
上传目录去掉脚本处理器(示例是去掉全部 handler,按需保留静态):
<location path="uploads"> <system.webServer> <handlers> <clear /> </handlers> </system.webServer></location><clear /> 后目录什么都不服务;通常应只移除 *.php/*.asp handler,而不是全部静态。用真实文件测。
再用请求过滤拒绝上传路径里的可执行扩展。
location ^~ /uploads/ { add_header Content-Disposition "attachment"; try_files $uri =404;}
location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000;}^~ 阻止正则 PHP location 匹配 /uploads/ 下的文件。没有它,shell.php 会被执行。try_files 挡 PATH_INFO 技巧。
- 传
.php/.aspx,请求;应 404/403,不执行。 - 传
..%2fweb.config;应拒绝。 - 传正常图片;应 200 且类型正确。
- 应用池身份不能写站点根,只能写 uploads。
E1。实验室用了 PHP FastCGI 和 IIS,但没有做上传/RCE 测试;控制项是 Server 2025 的生产清单。