Potentially dangerous Request.Form in WSFederation

2019-02-09 07:17发布

问题:

In my MVC3 site I've avoided setting requestValidationMode="2.0" with the new ValidateInput attribute, but now I'm trying to switch to WIF for authentication, and when the STS redirects back to my site, I'm getting the exception because WSFederationAuthenticationModule.IsSignInResponse is calling Request.Form instead of Request.Unvalidated().Form ... is there any way to deal with this without going to requestValidationMode="2.0" (which I really don't want to do).

Here's the stack trace, so you can see what I mean. My Controller's method never really gets called.

[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (wresult="<trust:RequestSecuri...").]
   System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8755668
   System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +122
   System.Web.HttpRequest.get_Form() +114
   Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.IsSignInResponse(HttpRequest request) +21
   Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.CanReadSignInResponse(HttpRequest request, Boolean onPage) +121
   Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +78
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

回答1:

The correct way of dealing with this is to add specific validator to the HttpRuntime, that knows how to detect valid security tokens.

Look at any of the examples here: http://claimsid.codeplex.com/releases/view/62929

Here's an excerpt from one of those (sample #5 t be specific which is also an MVC app):

namespace FShipping
{
    using System;
    using System.Web;
    using System.Web.Util;
    using Microsoft.IdentityModel.Protocols.WSFederation;

    public class WsFederationRequestValidator : RequestValidator
    {
        protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
        {
            validationFailureIndex = 0;
            if (requestValidationSource == RequestValidationSource.Form &&
                collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal))
            {
                if (WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage != null)
                {
                    return true;
                }
            }

            return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
        }
    }
}

Here's the config:

<system.web> 
...   
   <httpRuntime requestValidationType="FShipping.WsFederationRequestValidator" />
</system.web>


回答2:

I think we also observed this same error at some point, but if I remember correctly that was in some experimental or test scaffolding code, so we didn't have a strict security requirement there.

The official information I could find is that this is a known issue in WIF: see the "ASP.NET Detects Passive Federation Tokens as Potential Security Attack" section at the beginning of the WIF Known Issues page. They say there to set validateRequest="false" in web.config, or the equivalent ASP.NET Page directive for doing this at page level.

So you could try setting this only in a Page directive on the 'home page' of your application, I'm not sure but that might work.

Note that they don't talk about requestValidationMode="2.0" on the WIF Known Issues page, but judging from this TechNet wiki page this additional setting is necessary for ASP.NET 4.