You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用Response.AddHeader下载Excel时如何防范Content-Disposition相关XSS漏洞

C# Excel下载场景防范Content-Disposition关联XSS攻击的方案

漏洞触发原因

现有代码直接将myfile.Name字符串拼接进Content-Disposition响应头,如果文件名属于用户可控参数(比如用户自定义导出文件名、用户上传后再下载的文件名称),攻击者可以构造包含换行符、双引号、恶意脚本片段的特殊文件名,篡改响应头结构,触发响应头注入,最终导致存储型XSS漏洞。

修复方案

1. 使用官方内置类/方法处理文件名编码,禁止手动拼接未转义的文件名

根据你使用的.NET版本选择对应实现:

  • .NET Core / .NET 5+ 版本:使用ContentDispositionHeaderValue类自动处理编码转义,无需手动拼接
var contentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
    FileName = myfile.Name,
    // 适配多浏览器的非ASCII字符显示
    FileNameStar = myfile.Name
};
Response.Headers[System.Net.HttpKnownHeaderNames.ContentDisposition] = contentDisposition.ToString();

// 后续代码保持不变
Response.AddHeader("Content-Length", myfile.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.TransmitFile(myfile.FullName);
  • .NET Framework 版本:使用HttpUtility.UrlEncode对文件名做UTF8编码后再拼接
string encodedFileName = HttpUtility.UrlEncode(myfile.Name, System.Text.Encoding.UTF8);
// 替换+号编码为%20,避免部分浏览器显示文件名时把空格识别为+号
encodedFileName = encodedFileName.Replace("+", "%20");
Response.AddHeader("Content-Disposition", $"attachment; filename=\"{encodedFileName}\"");

// 后续代码保持不变
Response.AddHeader("Content-Length", myfile.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.TransmitFile(myfile.FullName);

2. 额外加固措施

  • 对用户可控的文件名做格式白名单校验,仅允许包含中英文、数字、下划线、减号、点号,过滤所有控制字符、换行符以及\ / : * ? " < > |等非法文件名字符
  • 若业务允许,优先使用服务端生成的随机安全文件名,仅在需要保留用户原始文件名的场景才做上述编码处理
  • 保持ASP.NET默认的响应头安全校验配置,不要手动关闭响应头拆分拦截功能

内容的提问来源于stack exchange,提问作者newbies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:06:07