在 POST 请求中将原始 HTML 从 View 传递到 Controller 时数据丢失——XSS-safety &信息丢失 [英] Data loss when passing raw HTML from View to Controller in POST request -- XSS-safety & information loss

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

问题描述

我的用例包括一个前端所见即所得的编辑器.从 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.

WYSIWYG 编辑器 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) here 但它用于从 控制器视图.我们的用例正好相反.
  • 这个问题汇总了前面几点.一切都不起作用.
  • [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 数据从 View 传递到 Action?满足以下条件:

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

Custom Model Binder

This custom model binder is like a relay and prevents any data loss in our POST parameter. HtmlSanitizer was used here before binding the value to prevent 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 标记.尽管每个人都声称这不受支持,并且这种责任是特定于应用程序的.


[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],因为在 ASP.NET Core 2.0 中没有人否认 HTML

You don't need [AllowHtml] anymore, because nobody denies HTML in ASP.NET Core 2.0

不需要 [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;信息丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆