xxs过滤

本文介绍了一种XSS过滤器的实现方式,该过滤器通过预定义的关键字和正则表达式来检测并清除潜在的XSS攻击代码。支持多种类型的HTML标签过滤,包括但不限于script、iframe等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    /// <summary>
    /// Xss过滤器
    /// </summary>
    public class XssCleaner
    {
        private static List<KeyValuePair<string, Regex>> injectWords = new List<KeyValuePair<string, Regex>>();

        /// <summary>
        /// 静态构造函数
        /// </summary>
        static XssCleaner()
        {
            #region 关键字(可任意变更,不区分大小写)
            injectWords.Add(new KeyValuePair<string, Regex>(@"alert", new Regex(@"alert\(.*\)", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"javascript", new Regex(@"javascript", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"document.", new Regex(@"document\.", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"script", new Regex(@"<\s*script.*>.*<\/\s*script\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"script", new Regex(@"<\s*script.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"applet", new Regex(@"<\s*applet.*>.*<\/\s*applet\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"applet", new Regex(@"<\s*applet.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"frameset", new Regex(@"<\s*frameset.*>.*<\/\s*frameset\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"frameset", new Regex(@"<\s*frameset.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"iframe", new Regex(@"<\s*iframe.*>.*<\/\s*iframe\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"iframe", new Regex(@"<\s*iframe.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"frame", new Regex(@"<\s*frame.*>.*<\/\s*frame\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"frame", new Regex(@"<\s*frame.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"img", new Regex(@"<\s*img.*>.*<\/\s*img\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"img", new Regex(@"<\s*img.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"link", new Regex(@"<\s*link.*>.*<\/\s*link\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"link", new Regex(@"<\s*link.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"object", new Regex(@"<\s*object.*>.*<\/\s*object\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"object", new Regex(@"<\s*object.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"style", new Regex(@"<\s*style.*>.*<\/\s*style\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            injectWords.Add(new KeyValuePair<string, Regex>(@"style", new Regex(@"<\s*style.*/\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            #endregion

            #region 符号(可任意变更,不区分大小写)

            #endregion
        }

        /// <summary>
        /// 过滤
        /// </summary>
        /// <param name="input">输入</param>
        /// <returns>输出</returns>
        public static string Clean(string input)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                return input;
            }
            injectWords.ForEach(injectWord =>
            {
                var startIndex = input.IndexOf(injectWord.Key, StringComparison.CurrentCultureIgnoreCase);

                if (startIndex >= 0)
                {
                    input = injectWord.Value.Replace(input, string.Empty);
                }
            });
            return input;
        }
    }
<think>嗯,用户之前询问过jsoup和HTML编码器,现在转向.NETCore的XSS防御中间件问题,说明他可能正在构建一个需要多层次安全防护的Web应用。用户的技术水平应该不错,因为连续问的都是比较具体的防御实现方案。关于.NETCore的XSS中间件,确实需要分几个层面来思考。首先框架本身内置了编码器,这在处理普通字符串输出时很有效,比如直接使用IHtmlEncoder接口或者Razor的@语法自动编码。但对于富文本场景,用户可能需要类似jsoup的HTML净化能力,这时候就得推荐第三方库了。突然想到用户之前特别关注过jsoup的净化机制,现在问.NET的方案,可能是项目技术栈切换了。在.NET生态里,AngleSharp虽然解析能力强,但净化功能不如专业的HtmlSanitizer库全面——后者支持白名单机制和CSS过滤,这点和jsoup很像。啊,差点忘记用户问的是“中间件”这个特定形式。严格来说.NET没有官方中间件,但可以建议用户用自定义中间件包装HtmlSanitizer的处理逻辑。代码示例要着重展示三个关键点:注册服务的生命周期、中间件的管道拦截点、以及如何区分普通文本和HTML的不同处理策略。用户可能会忽略编码器和净化器的适用场景差异,需要再强调下:普通表单用框架自带的编码器足够,但评论区富文本必须用HtmlSanitizer。另外那个禁用特殊字符的中间件例子可能有点极端,不过对于高安全场景确实有效。最后想到个隐患:用户若直接复用代码示例,可能会漏掉JSON请求的场景。应该在建议里补充说明Content-Type检测的问题,避免XSS通过API注入。</think> 在.NET Core中,**没有官方内置的中间件(Middleware)专门用于XSS过滤**,但框架提供了多重安全机制协同防御XSS攻击,以下是关键实现方案: --- ### 🔒 一、核心防御机制 #### 1. **自动HTML编码(第一道防线)** - **Razor视图引擎**自动转义动态输出 例:`@Model.UserInput` 中的`<script>`会被转义为`<script>` - **手动编码支持**: ```csharp @Html.Encode(Model.UserInput) // MVC视图 _encoder.Encode("unsafe string") // 注入IHtmlEncoder服务 ``` 输出安全原理: `$输入$:<div onclick="alert(1)">` `$输出$:<div onclick="alert(1)">`[^1] #### 2. **请求验证中间件(默认启用)** - **功能**:拦截包含危险标记的请求(如`<script>`) - **触发场景**: ```http POST /submit-form HTTP/1.1 Content-Type: application/x-www-form-urlencoded content=<script>alert(1)</script> // 返回400错误 ``` - **关闭方法(不推荐)**: ```csharp services.Configure<RequestValidationOptions>(options => options.DisableHtmlAttributeValidation = true); ``` --- ### 🔧 二、高级场景解决方案 #### 1. **富文本净化(需第三方库)** - **推荐库**:`HtmlSanitizer`(类似Jsoup的.NET实现) ```csharp var sanitizer = new HtmlSanitizer(); sanitizer.AllowedTags.Add("div"); // 白名单控制 string safeHtml = sanitizer.Sanitize(rawHtml); ``` `$输入$:<div><script>test</script><b>安全文本</b></div>` `$输出$:<div><b>安全文本</b></div>`[^2] #### 2. **自定义中间件示例** 实现基础XSS过滤中间件: ```csharp public class XssFilterMiddleware { private readonly RequestDelegate _next; public XssFilterMiddleware(RequestDelegate next) => _next = next; public async Task Invoke(HttpContext context) { context.Request.EnableBuffering(); // 允许重复读取Body using var reader = new StreamReader(context.Request.Body); var rawContent = await reader.ReadToEndAsync(); // 简易危险字符过滤 (实际项目需用正则/解析器) var sanitized = rawContent.Replace("<", "<").Replace(">", ">"); var ms = new MemoryStream(Encoding.UTF8.GetBytes(sanitized)); context.Request.Body = ms; await _next(context); } } ``` 注册中间件: ```csharp app.UseMiddleware<XssFilterMiddleware>(); ``` --- ### ⚠️ 三、关键注意事项 1. **编码器局限性**: 无法处理属性内的恶意代码(如`<a href="javascript:alert(1)">`),需配合**URL验证** 2. **内容类型区分**: - 纯文本输出:使用`HtmlEncoder` - JSON API:用`System.Text.Json`的自动转义(`JsonSerializer`) 3. **富文本存储**: **先净化再存储**,而非仅依赖输出编码 --- ### 🔍 四、官方推荐实践 | 防御层 | 实现方式 | |----------------|----------------------------------| | 输入验证 | 模型验证 + 正则表达式 | | 存储净化 | HtmlSanitizer + 白名单策略 | | 输出编码 | Razor自动编码 / IHtmlEncoder | | Cookie安全 | `[ValidateNever]`忽略敏感属性 | > 📌 **最佳实践**: > ```mermaid > graph LR > A[用户输入] --> B[模型验证] > B --> C{是否为HTML?} > C -- 是 --> D[HtmlSanitizer净化] > C -- 否 --> E[输入格式化] > D --> F[数据库存储] > E --> F > F --> G[Razor自动编码输出] > ``` --- ### ❓ 相关问题 1. 如何在Web API中防御JSON注入导致的XSS? 2. 使用`HtmlSanitizer`时如何配置允许的CSS样式? 3. Blazor框架的XSS防御机制与MVC有何不同? 4. 如何验证URL属性(如`href/src`)以防止JavaScript协议攻击? [^1]: 基于ASP.NET Core安全文档的输入输出编码规范 [^2]: HtmlSanitizer白名单策略参考Github文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值