Is it possible to remove some post data with an Ht

2019-02-05 07:45发布

问题:

I'm converting an old classic asp website to asp.net.

The application is basically an extension of a tool set for a given set of users but it is hosted at an external vendor.

To perform a seamless transfer to this application it POSTS some xml data which is firing off the "potentially dangerous Request.Form value". I know I could turn off the validateRequest flag but I would rather not do this.

I have written an httpmodule which takes this data and uses it to authenticate the user, is it possible to use the same module, or a different module for that matter, to remove these "bad" values in the post data before that data is "validated"?

Otherwise if none of these ideas work, I am open to other suggestions.

回答1:

Yes. The following class implements the IHttpModule Interface and registers and event that will fire before the HttpRequestValidationException check occurs. It checks that the request is a POST and that "testinput" is not null and then HTML Encodes it. The Class needs to be registered in your Web.config as an httpModule.

class...

using System;
using System.Collections.Specialized;
using System.Reflection;
using System.Web;

public class PrevalidationSanitizer : System.Web.IHttpModule
{
    private HttpApplication httpApp;

    public void Init(HttpApplication httpApp)
    {
        this.httpApp = httpApp;
        httpApp.PreRequestHandlerExecute += new System.EventHandler(PreRequestHandlerExecute_Event);
    }

    public void Dispose() { }

    public void PreRequestHandlerExecute_Event(object sender, System.EventArgs args)
    {
        NameValueCollection form = httpApp.Request.Form;

        Type type = form.GetType();

        PropertyInfo prop = type.GetProperty("IsReadOnly", BindingFlags.Instance 
            | BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

        prop.SetValue(form, false, null);

        if (httpApp.Request.RequestType == "POST" != null 
            && httpApp.Request.Form["testinput"])
                httpApp.Request.Form.Set("testinput"
                    , httpApp.Server.HtmlEncode(httpApp.Request.Form["testinput"]));
    }
}

web.config entry...

<system.web>
  <httpModules>
    <add type="PrevalidationSanitizer" name="PrevalidationSanitizer" />
...


回答2:

I'd be tempted to factor out the poor pattern of placing XML data in a field post via HTML Form. I understand you want to port "seamlessly" which I take it means you want to be able to maintain both ASP and ASPX pages for a time. However in this case you should consider changing both the form and the action target of the form at the same time.

I guess the this is similar to advice I gave here. Only in this case the situation is worse in that the pattern of code in the original ASP falls short of the desirable, even within the limitations of classic ASP.

If you don't want to completely port the ASP form and its action page at the same time then consider modifying the ASP page to use XHR to post the XML to an ashx that places the XML somewhere safe and returns a GUID. Place the returned GUID in a hidden field instead of the field that held the XML originally. In the receiving ASPX page use the GUID to retrieve the previously posted XML.



回答3:

Sounds like a lot of hassle. What's so bad about about using the validateRequest flag a page level?

Just make sure you sanitise the input correctly and encode it if you need to store it anywhere and/or make sure you don't spit back the field to the browser without encoding it.