1. ホーム
  2. asp.net-mvc

[解決済み] ASP.NET MVC カスタムモデルバインダーの使用時に、クライアントから危険なRequest.Formの値が検出されました。

2022-12-11 16:39:16

質問

ここでエラーが発生します。

ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");

値の選択のみを許可するにはどうすればよいですか? 例えば、以下のようになります。

[ValidateInput(false)]
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");
    ValueProviderResult value2 = bindingContext.ValueProvider.GetValue("ConfirmationMessage2");
}

どのように解決するのですか?

いくつかのオプションがあります。

モデル上で、HTMLを許可する必要がある各プロパティにこの属性を追加する - 。 ベストチョイス

using System.Web.Mvc;

[AllowHtml]
public string SomeProperty { get; set; }

コントローラアクションで、すべてのHTMLを許可するためにこの属性を追加します。

[ValidateInput(false)]
public ActionResult SomeAction(MyViewModel myViewModel)

web.configでブルートフォース-。 絶対にお勧めしません。

web.config ファイルのタグ内に、httpRuntime 要素に requestValidationMode="2.0" という属性を挿入してください。また、pages 要素に validateRequest="false" 属性を追加します。

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>

詳細はこちら http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx

上記は、デフォルトのモデルバインダーの使用に対して動作します。

カスタムモデルバインダー

上記のコードにおける bindingContext.ValueProvider.GetValue() の呼び出しは、どんな属性であっても常にデータを検証するようです。ASP.NET MVC のソースを調べてみると、DefaultModelBinder はまずリクエストの検証が必要かどうかをチェックし、検証が必要かどうかを示すパラメーターで bindingContext.UnvalidatedValueProvider.GetValue() メソッドを呼び出していることがわかります。

残念ながら、フレームワークのコードを使用することはできません。なぜなら、無知な開発者が危険なことをしないように、封印、プライベート、または何かで保護されているからです。しかし、AllowHtml と ValidateInput 属性を尊重するカスタム モデル バインダーを作成することはそれほど難しくはありません。

public class MyModelBinder: IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // First check if request validation is required
        var shouldPerformRequestValidation = controllerContext.Controller.ValidateRequest && bindingContext.ModelMetadata.RequestValidationEnabled;

        // Get value
        var valueProviderResult = bindingContext.GetValueFromValueProvider(shouldPerformRequestValidation);
        if (valueProviderResult != null)
        {
            var theValue = valueProviderResult.AttemptedValue;

            // etc...
        }
    }
}

もう一つの必要な要素は、検証されていない値を取得する方法です。この例では、ModelBindingContext クラスの拡張メソッドを使用しています。

public static class ExtensionHelpers
{
    public static ValueProviderResult GetValueFromValueProvider(this ModelBindingContext bindingContext, bool performRequestValidation)
    {
        var unvalidatedValueProvider = bindingContext.ValueProvider as IUnvalidatedValueProvider;
        return (unvalidatedValueProvider != null)
          ? unvalidatedValueProvider.GetValue(bindingContext.ModelName, !performRequestValidation)
          : bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    }
}

これに関する詳細は http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/