【问题标题】:How to save HTML to database and retrieve it properly如何将 HTML 保存到数据库并正确检索它
【发布时间】:2014-02-09 18:00:06
【问题描述】:

这些天学习安全性:)
我需要允许用户在表单中输入文本并允许他们使用一些 HTML 标签:粗体、斜体、列表等,并防止他们添加一些危险的 JavaScript 代码。
所以我使用this whitelist implementation 来清理HTML。
但是我仍然对如何以正确的方式保存和显示感到困惑。
所以在这里我做了什么:
型号:

public class Post
    {
        [AllowHtml]
        public string Data { get; set; }
    }

控制器:

[HttpPost, ActionName("Create")]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Post model)
        {
            // Decode model.Data as it is Encoded after post
            string decodedString = HttpUtility.HtmlDecode(model.Data);
            // Clean HTML
            string sanitizedHtmlText =  HtmlUtility.SanitizeHtml(decodedString);

            string encoded = HttpUtility.HtmlEncode(sanitizedHtmlText);

查看:

@using (Html.BeginForm("Create", "Home", FormMethod.Post)) {    
    @Html.AntiForgeryToken()
    @Html.TextAreaFor(a=>a.Data)
    <input type="submit" value="submit" />
}

所以当我发布表单时,我会看到:

<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p>&lt;img src="http://metro-portal.hr/img/repository/2010/06/medium/hijena_shutter.jpg" /&gt;</p>

因为&lt;p&gt;&amp;lt;我觉得需要先解码:

<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p><img src="http://metro-portal.hr/img/repository/2010/06/medium/hijena_shutter.jpg" /></p>

然后我根据白名单对其进行清理,并获得清理后的 HTML:

<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p>

1) 我应该像这样将它保存在数据库中吗?
2)或者我需要将此结果编码,然后将其保存到数据库(编码如下)?

&lt;p&gt;Simple &lt;em&gt;&lt;strong&gt;whitelist&lt;/strong&gt; &lt;/em&gt;test:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;t1&lt;/li&gt;
&lt;li&gt;t2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Image:&lt;/p&gt;
&lt;p&gt;

如果我把它放在这样的视图上,我会感到困惑:

@Model.Data

我在视图上看到了这个:

&lt;p&gt;Simple &lt;em&gt;&lt;strong&gt;whitelist&lt;/strong&gt; &lt;/em&gt;test:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;t1&lt;/li&gt; &lt;li&gt;t2&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Image:&lt;/p&gt; &lt;p&gt;

<p>Simple <em><strong>whitelist</strong> </em>test:</p> <ul> <li>t1</li> <li>t2</li> </ul> <p>Image:</p> <p>

那么如何正确显示此 HTML(粗体、列表等)?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 razor xss


    【解决方案1】:

    经验法则如下:

    1. 将 RAW HTML 存储在您的数据库中,无需任何编码或清理。如果你存储一些包含 XSS 代码的字符串,SQL 服务器并不关心。
    2. 在您的页面上显示此输出时,请确保已对其进行清理。

    所以:

    [HttpPost, ActionName("Create")]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Post model)
    {
        // store model.Data directly in your database without any cleaning or sanitizing
    }
    

    然后在显示时:

    @Html.Raw(HtmlUtility.SanitizeHtml(Model.Data))
    

    请注意我在这里如何使用 Html.Raw 帮助程序来确保您不会获得双重 HTML 编码输出。 HtmlUtility.SanitizeHtml 函数应该已经负责清理值并返回一个可以在视图中显示的安全字符串,并且不会进一步编码。另一方面,如果您使用了@HtmlUtility.SanitizeHtml(Model.Data),那么@ razor 函数将对SanitizeHtml 函数的结果进行HTML 编码,这可能不是您想要的。

    【讨论】:

    • Aha...clear :) 所以在发布后基本上我可以将其保存到数据库&lt;p&gt;This is &lt;strong&gt;safe&lt;/strong&gt; text and &lt;em&gt;danger&lt;/em&gt; follows &amp;gt; &amp;lt;script&amp;gt;alert('attack');&amp;lt;/script&amp;gt;&lt;/p&gt; 并在视图上使用 SanitizeHtml。我认为我不能在数据库中保存 html 标签。我得到的这个值被模型从视图传递到 Create 方法(它添加了 &qt、lt 等)。
    • 是的,你的理解是正确的。在数据库中存储原始 HTML 没有任何问题。
    • @DarinDimitrov 我如何获得HtmlUtility.SanitizeHtml() 方法。不知道参考什么。我做了一些谷歌搜索,发现这里@9​​87654321@ HtmlUtility 仅适用于 Windows 和 Windows Phone。如何在我的 MVC Web 项目中引用它?
    • 要清理 HTML(即删除不在白名单中的标签),请参阅 Is there a good solution for a C# html sanitizer?
    【解决方案2】:

    到框架 4.5,使用 MVC 5,使用 @Html.Raw(WebUtility.HtmlDecode(item.ADITIONAL_INFORMATION))

    【讨论】:

      【解决方案3】:

      您可以通过数据类型 VARBINARY(MAX) 为 htmlcolumn 将 HTML 文件保存在数据库中。

      1. 将html文件转换成二进制文件(code project link)

      2. 在这样的示例代码中插入数据:

      Declare @HTML   Varbinary(MAX) = Set HTML Varbinary code here 
      
      Insert into table_name (htmlcoulmn)
      Value @HTML
      
      1. 在数据库中加载数据,当你需要加载文件时,你应该通过这个代码将htmlcolumn转换为Nvarchar(max):
      Select CAST(htmlcolumn as nvarchar(MAX)) As HTMLCODE
      FROM Table_Name
      

      如果此解决方案有问题,感谢您给我写评论。

      希望你一切顺利

      【讨论】:

        猜你喜欢
        • 2018-10-29
        • 1970-01-01
        • 2019-06-06
        • 2017-03-12
        • 2015-11-05
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多