OST请求中将原始HTML从View传递到Controller时

OST请求中将原始HTML从View传递到Controller时

本文介绍了在POST请求中将原始HTML从View传递到Controller时数据丢失-XSS-safety&信息丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My use-case includes a front-end WYSIWYG editor. Taking user input in HTML5/CSS format from the CSHTML Front-End View. Receiving the input in the Backend Controller's action via POST request. And finally doing fancy Database stuff with it.

听起来很容易.使用编辑器的野兽,它非常简单且可自定义.

Sounds pretty easy. Using this beast of an editor, it's very straightforward and customizable.

所见即所得编辑器textarea嵌套在form中,以使用POST

WYSIWYG editor textarea nested within a form to send editor's raw HTML data using POST

    <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参数.

Controller

Controller's action receiving POST parameter.

    [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 的参数数据不正确.


The problem

HTML5/CSS tags are lost along the way when passing the POST data. Upon inspection, they are sent successfully from the View. The Action's parameter though has incorrect data.

这里似乎正在进行消毒,剥离了我们要保留的HTML标签的POST参数.

Looks like sanitization is in motion here, stripping POST parameters of the HTML tags we want to deliberately keep.

似乎有可能的解决方法.

It looks like there are possible solutions for this.

  • [Request.Unvalidated]批注. 已弃用.
  • [AllowHtml]批注.不推荐使用.请参见此处此处.
  • @Html.Raw(theString) 此处,但这是用于将不安全的数据从 Controller 传递到查看.我们的用例是相反的.
  • 问题包含了前面的要点.都行不通.
  • [Request.Unvalidated] annotation. Deprecated.
  • [AllowHtml] annotation. Deprecated. See here and here.
  • @Html.Raw(theString) here but it's for passing unsafe data from Controller to View. Our use-case is the opposite.
  • This question has a compilation of the previous points. All doesn't work.

如何将原始HTML/CSS数据从视图"传递到动作"?满足以下条件:

How do I pass my raw HTML/CSS data from View to Action? satisfying the following conditions:

  1. 不会丢失标记的数据.

  1. No data-loss of markup.

防止构成XSS风险的不安全数据.根据指南.

Prevent unsafe data that poses XSS risk. As per the guidelines.

推荐答案

解决方案

我最终使用了自定义模型绑定,它绕过了这种过分急切的清理/数据丢失的工作.结果保留了我想要的HTML标签.

The solution

I ended up using Custom Model Binding which bypassed this overly-eager sanitization/data loss. As a result preserved the HTML tags I want.

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

However this introduces XSS risk. To counter-react passing unsafe data, I used HtmlSanitizer to omit unsafe HTML/CSS tags.

在参数中添加了[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标记.即使每个人都声称不支持此功能,并且这种责任是特定于应用程序的.


[HELP] Missing piece -- understanding the root cause

With my working solution above, I still have no clue why HTML markup are sanitized and removed by default. Even though everyone is claiming this is not supported and such responsibility is app-specific.

此处此处:

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

Don't need [AllowHtml] or RequestValidationEnabled because we don't have request validation in this system

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

Any help in demystifying the root cause would be HUGELY appreciated.

我的解决方案基于:

  1. 答案.尽管不再支持request.Unvalidated.
  2. 自定义模型绑定.
  3. HtmlSanitizer .
  4. 答案有助于为我指明正确的方向.
  1. This answer. Though request.Unvalidated is no longer supported.
  2. Custom Model Binding.
  3. HtmlSanitizer.
  4. This answer was helpful in pointing me in the right direction.

这篇关于在POST请求中将原始HTML从View传递到Controller时数据丢失-XSS-safety&amp;信息丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 10:00