在C#开发中,当应用需要接收用户提交的富文本内容时,直接存储或渲染这些未处理的内容很容易引发XSS跨站脚本攻击,攻击者可能通过注入恶意HTML标签和脚本窃取用户信息或破坏页面逻辑。手动编写正则匹配HTML标签的方式不仅维护成本高,还容易出现过滤遗漏的问题,使用成熟的HtmlSanitizer工具是更可靠的选择。

什么是HtmlSanitizer
HtmlSanitizer是一款开源的C# HTML清洗库,它的核心作用是过滤HTML内容中的危险元素、属性和URL,只保留开发者允许的安全内容,从根源上避免XSS攻击。它内置了完善的默认安全规则,同时也支持开发者根据业务需求自定义过滤策略,适配不同的富文本处理场景。
安装HtmlSanitizer
可以通过NuGet包管理器安装HtmlSanitizer,在Visual Studio的包管理器控制台执行以下命令即可完成安装:
// 安装HtmlSanitizer的NuGet命令 Install-Package HtmlSanitizer
基础使用:清洗HTML标签防御XSS
HtmlSanitizer的默认配置已经能够过滤掉大部分危险的标签和属性,比如<script>、<iframe>、onclick等事件属性,直接使用默认实例即可完成基础的HTML清洗工作。
using Ganss.Xss;
using System;
class Program
{
static void Main()
{
// 模拟用户提交的包含恶意脚本的HTML内容
string userInput = "<div>正常内容</div><script>alert('xss攻击')</script><img src='x' onerror='alert(1)'>";
// 创建HtmlSanitizer实例
var sanitizer = new HtmlSanitizer();
// 执行清洗操作
string safeHtml = sanitizer.Sanitize(userInput);
Console.WriteLine("清洗后的安全内容:");
Console.WriteLine(safeHtml);
}
}
上述代码执行后,输出的安全内容只会保留<div>正常内容</div>,<script>标签和img的onerror事件属性都会被自动过滤掉,有效避免了XSS攻击。
自定义过滤规则
如果默认规则不符合业务需求,比如需要允许特定的标签或属性,或者禁止某些默认允许的内容,可以通过配置HtmlSanitizer的相关属性来自定义规则。
允许或禁止特定标签
通过AllowedTags属性可以设置允许保留的HTML标签,不在列表中的标签会被过滤:
using Ganss.Xss;
class CustomSanitizerDemo
{
static void Demo()
{
var sanitizer = new HtmlSanitizer();
// 只允许保留div、p、span、a这四个标签
sanitizer.AllowedTags.Clear();
sanitizer.AllowedTags.Add("div");
sanitizer.AllowedTags.Add("p");
sanitizer.AllowedTags.Add("span");
sanitizer.AllowedTags.Add("a");
string input = "<div>内容</div><h1>标题</h1><p>段落</p>";
string result = sanitizer.Sanitize(input);
// 输出结果:<div>内容</div><p>段落</p>,h1标签被过滤
}
}
过滤特定属性
通过AllowedAttributes可以配置允许保留的属性,也可以直接移除特定属性:
using Ganss.Xss;
class AttributeFilterDemo
{
static void Demo()
{
var sanitizer = new HtmlSanitizer();
// 禁止a标签的href属性跳转到外部危险地址,只允许相对路径和指定域名
sanitizer.AllowedSchemes.Clear();
sanitizer.AllowedSchemes.Add("http");
sanitizer.AllowedSchemes.Add("https");
sanitizer.AllowedSchemes.Add("");
// 禁止style属性,避免CSS注入攻击
sanitizer.AllowedAttributes.Remove("style");
string input = "<a href='javascript:alert(1)'>恶意链接</a><a href='https://ipipp.com' style='color:red'>正常链接</a>";
string result = sanitizer.Sanitize(input);
// 恶意链接的href会被清空,style属性被移除
}
}
注意事项
- 不要对已经清洗过的内容重复执行Sanitize方法,避免不必要的性能消耗
- 如果业务需要保留部分富文本格式,建议明确配置允许的标签和属性,不要过度放开权限
- 清洗操作应该在数据入库前或者渲染到页面前执行,优先选择入库前处理,避免后续多次渲染重复清洗
- 定期关注HtmlSanitizer的版本更新,及时升级到最新版本修复已知的安全漏洞
常见场景示例
在ASP.NET Core的Web应用中,可以在接收用户提交的内容时直接调用清洗方法:
using Ganss.Xss;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/article")]
public class ArticleController : ControllerBase
{
private readonly HtmlSanitizer _sanitizer;
public ArticleController()
{
_sanitizer = new HtmlSanitizer();
// 全局配置允许的标签,根据实际业务调整
_sanitizer.AllowedTags.Add("img");
_sanitizer.AllowedAttributes.Add("src");
}
[HttpPost]
public IActionResult CreateArticle([FromBody] ArticleCreateDto dto)
{
// 清洗用户提交的富文本内容
string safeContent = _sanitizer.Sanitize(dto.Content);
// 后续将safeContent存入数据库
return Ok(new { message = "文章创建成功", content = safeContent });
}
}
public class ArticleCreateDto
{
public string Title { get; set; }
public string Content { get; set; }
}
C#HtmlSanitizerXSS防御HTML标签清洗修改时间:2026-07-21 10:18:29