【问题标题】:Data loss when passing raw HTML from View to Controller in POST request -- XSS-safety & information loss在 POST 请求中将原始 HTML 从视图传递到控制器时的数据丢失——XSS 安全和信息丢失
【发布时间】:2020-04-16 09:25:56
【问题描述】:

序言

我的用例包括一个前端所见即所得的编辑器。从 CSHTML 前端视图中获取 HTML5/CSS 格式的用户输入。通过 POST 请求接收后端控制器操作中的输入。最后用它做一些花哨的数据库。

听起来很简单。使用 editor 这个野兽,它非常简单且可自定义。

查看

WYSIWYG 编辑器 textarea 嵌套在 form 中,使用 POST 发送编辑器的原始 HTML 数据

    <form class="form" asp-controller="CreationController" asp-action="CreateSnowflakeBlogpost" method="post">
        <button type="submit" class="btn btn-link">Submit Snowflake Blogpost</button>
        <textarea name="snowflakeHtmlContent" id="joditEditor"> </textarea>
    </form>

控制器

控制器的动作接收POST参数。

    [HttpPost]
    public async Task<IActionResult> CreateSnowflakeBlogpost(string snowflakeHtmlContent)
    {
        // store HTML content in DB and do fancy operations

        // redirect to something else
        return RedirectToAction("PreviewSnowflakeBlogpost");
    }

问题

HTML5/CSS 标签在传递 POST 数据时会丢失。经检查,它们从视图成功发送。 Action 的参数虽然数据不正确。

看起来这里正在进行清理,去除我们想要故意保留的 HTML 标记的 POST 参数。

看起来有可能的解决方案。

  • [Request.Unvalidated] 注释。 Deprecated.
  • [AllowHtml] 注释。已弃用。请参阅herehere
  • @Html.Raw(theString) here 但它用于将不安全的数据从 Controller 传递到 View。我们的用例正好相反。
  • This question 有前面几点的汇编。一切都不起作用。

问题

如何将原始 HTML/CSS 数据从 View 传递到 Action?满足以下条件:

  1. 标记没有数据丢失。

  2. 防止存在 XSS 风险的不安全数据。根据guidelines

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc wysiwyg model-binding html-sanitizing


    【解决方案1】:

    解决办法

    我最终使用了Custom Model Binding,它绕过了这种过于急切的清理/数据丢失。结果保留了我想要的 HTML 标签。

    但是这会带来 XSS 风险。为了应对传递的不安全数据,我使用HtmlSanitizer 省略了不安全的 HTML/CSS 标记。

    动作

    为参数添加[ModelBinder(typeof(AllowSanitizedHtmlBinder))]注解

        [HttpPost]
        public async Task<IActionResult> CreateSnowflakeBlogpost([ModelBinder(typeof(AllowSanitizedHtmlBinder))] string snowflakeHtmlContent)
        {
            // store HTML content in DB and do fancy operations
    
            // redirect to something else
            return RedirectToAction("PreviewSnowflakeBlogpost");
        }
    

    自定义模型绑定器

    这个自定义模型绑定器就像一个中继器,可以防止我们的 POST 参数中的任何数据丢失。此处使用HtmlSanitizer,之前绑定值防止XSS。

        // Custom Model Binding
        using Microsoft.AspNetCore.Mvc.ModelBinding;
    
        // HTML Sanitizer
        using Ganss.XSS;
    
        public class AllowSanitizedHtmlBinder: IModelBinder
        {
            public Task BindModelAsync(ModelBindingContext bindingContext)
            {
                if (bindingContext == null)
                {
                    throw new ArgumentNullException(nameof(bindingContext));
                }
    
                var modelName = bindingContext.ModelName;
    
                // Try to fetch the value of the argument by name
                var valueProviderResult =
                    bindingContext.ValueProvider.GetValue(modelName);
    
                if (valueProviderResult == ValueProviderResult.None)
                {
                    return Task.CompletedTask;
                }
    
                bindingContext.ModelState.SetModelValue(modelName,
                    valueProviderResult);
    
                var value = valueProviderResult.FirstValue;
    
                // Check if the argument value is null or empty
                if (string.IsNullOrEmpty(value))
                {
                    return Task.CompletedTask;
                }
    
                // Sanitize HTML from harmful XSS markup
                var sanitizer = new HtmlSanitizer();
                var sanitizedValue = sanitizer.Sanitize(value);
    
                bindingContext.Result = ModelBindingResult.Success(sanitizedValue);
    
                return Task.CompletedTask;
            }
        }
    

    [帮助] 缺失的部分——了解根本原因

    使用上面的工作解决方案,我仍然不知道为什么 HTML 标记在默认情况下会被清理和删除。尽管每个人都声称这不受支持,并且这种责任是特定于应用程序的。

    herehere 所见:

    您不再需要 [AllowHtml],因为在 ASP.NET Core 2.0 中没有人否认 HTML

    不需要 [AllowHtml] 或 RequestValidationEnabled,因为我们在这个系统中没有请求验证

    任何有助于揭开根本原因的神秘面纱将不胜感激。

    来源

    我的解决方案基于:

    1. This 回答。虽然 request.Unvalidated 不再受支持。
    2. Custom Model Binding
    3. HtmlSanitizer
    4. This 的回答有助于为我指明正确的方向。

    【讨论】:

      猜你喜欢
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 2012-08-15
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多