影评周公子 2026-02-07 17:45 采纳率: 98.8%
浏览 0
已采纳

Razor中@Html.Raw()为何导致XSS漏洞?如何安全使用?

**问题:** 在ASP.NET MVC/Razor中,`@Html.Raw()` 直接将字符串作为未编码的HTML输出,绕过Razor默认的HTML编码机制。若其参数源自用户输入(如表单提交、URL参数、数据库未净化内容),攻击者可注入恶意脚本(如 `<script></script>`),导致跨站脚本(XSS)漏洞——轻则窃取Cookie、重定向用户,重则劫持会话甚至发起蠕虫攻击。常见误用场景包括:直接渲染富文本编辑器内容、拼接动态HTML模板、或对“已‘信任’的数据”盲目调用`Raw()`而未做上下文校验。根本原因在于`Html.Raw()`仅取消编码,不提供任何输入验证、内容策略或沙箱保护。因此,它不是“安全输出API”,而是“危险透传API”——安全使用前提必须是:数据**全程可控、严格验证、且明确属于可信HTML上下文**。如何确保?下文将详解防御策略与替代方案。
  • 写回答

1条回答 默认 最新

  • 冯宣 2026-02-07 17:45
    关注
    ```html

    一、认知层:理解 Html.Raw() 的本质与风险根源

    @Html.Raw() 并非“渲染HTML的快捷方式”,而是显式解除Razor默认XSS防护机制的危险开关。它绕过 HtmlEncoder.Default.Encode(),将字符串原样写入响应流——这意味着:任何未净化的<script>onerror=javascript:alert() 都将被浏览器执行。其设计初衷仅服务于绝对可信的静态HTML片段(如硬编码图标SVG),而非动态内容。误将其视为“富文本渲染API”是绝大多数XSS漏洞的起点。

    二、分析层:典型误用场景与上下文失配诊断

    • 富文本编辑器直出:TinyMCE/CKEditor提交的HTML未经服务端Sanitize即存库并@Html.Raw(Model.Content)
    • URL参数拼接@Html.Raw(Request.QueryString["template"]) —— 攻击者构造 ?template=%3Cimg%20src=x%20onerror=fetch('/steal?c='+document.cookie)%3E
    • “已信任”幻觉:数据库字段标记为“HTML安全”,但未审计编辑入口、导入脚本、API批量写入路径

    三、防御层:纵深防御策略体系(含代码与流程图)

    安全使用 @Html.Raw() 必须满足三重校验:

    1. 来源可信性验证:仅允许来自白名单配置项或内部CMS管理后台的HTML模板
    2. 内容沙箱化处理:使用 HtmlSanitizer 库剥离危险标签/属性
    3. 上下文语义确认:确保输出位置在HTML body内(非<script><style>、事件属性等执行上下文)

    示例:基于 HtmlSanitizer 的安全封装

    public static class HtmlHelperExtensions
    {
        private static readonly HtmlSanitizer _sanitizer = new HtmlSanitizer();
        static HtmlHelperExtensions() 
        {
            _sanitizer.AllowedTags.Add("p"); _sanitizer.AllowedTags.Add("strong");
            _sanitizer.AllowedAttributes.Add("class"); _sanitizer.RemovingAttribute += (s, e) => e.Cancel = true;
        }
        public static MvcHtmlString SafeRaw(this HtmlHelper helper, string html) =>
            MvcHtmlString.Create(_sanitizer.Sanitize(html ?? ""));
    }

    安全决策流程图

    flowchart TD A[数据来源] --> B{是否100%可控?} B -->|否| C[拒绝Raw,改用Encode] B -->|是| D[是否经HtmlSanitizer净化?] D -->|否| E[强制净化] D -->|是| F[输出位置是否HTML Body?] F -->|否| G[转义为text/plain或使用data-*属性] F -->|是| H[@Html.Raw\(\) 安全调用]

    四、替代层:更健壮的现代方案矩阵

    场景推荐方案安全优势
    富文本展示<div @ref="contentRef"></div> + Blazor Server端Sanitize服务端净化+客户端无执行上下文
    动态UI组件Razor Components + MarkupString(仅限已净化内容)明确声明意图,编译期检查
    国际化HTML片段Resource files + @Html.Raw(LocalizedResources.GetHtml("welcome"))(资源由开发人员维护)源头可控,无用户输入通道

    五、治理层:建立组织级XSS防控基线

    对5年以上开发者而言,技术方案需嵌入工程实践:

    • 静态扫描规则:SonarQube自定义规则禁止 @Html.Raw\([^)]*Request\.[^)]*\) 模式
    • 数据库约束:对存储HTML的字段添加CHECK约束(如正则限制仅含<p><span><strong>
    • 运行时监控:ASP.NET Core中间件拦截含<script>且未经X-Content-Type-Options: nosniff保护的响应
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月8日
  • 创建了问题 2月7日