**问题:**
在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()必须满足三重校验:- 来源可信性验证:仅允许来自白名单配置项或内部CMS管理后台的HTML模板
- 内容沙箱化处理:使用
HtmlSanitizer库剥离危险标签/属性 - 上下文语义确认:确保输出位置在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保护的响应
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 富文本编辑器直出:TinyMCE/CKEditor提交的HTML未经服务端Sanitize即存库并