在POST请求中将原始HTML从View传递到Controller时数据丢失-XSS安全和信息丢失

问题描述 投票:0回答:1

序言

我的用例包括一个前端WYSIWYG编辑器。从CSHTML前端视图以HTML5 / CSS格式获取用户输入。通过POST请求在后端控制器的操作中接收输入。最后用它来制作精美的数据库资料。

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

查看

所见即所得编辑器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数据时会丢失。经检查,它们已从View成功发送。 Action的参数虽然有错误的数据。

好像在这里进行消毒,剥离了我们要保留的HTML标签的POST参数。

看来这可能有解决方案。

  • [Request.Unvalidated]注释。 Deprecated
  • [AllowHtml]注释。不推荐使用。参见herehere
  • @Html.Raw(theString) here,但用于将不安全的数据从Controller传递到View。我们的用例则相反。
  • This问题具有前面各点的汇总。都行不通。

问题

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

  1. 无标记数据丢失。

  2. 防止构成XSS风险的不安全数据。按照guidelines

asp.net-core asp.net-core-mvc wysiwyg model-binding html-sanitizing
1个回答
0
投票

解决方案

我最终使用了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参数中的任何数据丢失。在绑定该值以防止XSS之前,这里使用了HtmlSanitizer

// 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;
    }
}

[[HELP]丢失的片段-了解根本原因

使用上述工作解决方案,我仍然不知道为什么默认情况下会清理并删除HTML标记。即使每个人都声称不支持此功能,并且此类责任特定于应用程序。

herehere所示:

您不再需要[AllowHtml],因为没有人拒绝ASP.NET Core 2.0中的HTML

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

对揭开根本原因的任何神秘帮助,将不胜感激。

来源

我的解决方案基于:

  1. This答案。尽管不再支持request.Unvalidated
  2. Custom Model Binding
  3. HtmlSanitizer
  4. [This答案有助于指出正确的方向。
© www.soinside.com 2019 - 2024. All rights reserved.