Why does Glimpse disable request validation? - asp.net

I'm found that request validation was not working on my PC, which meant it's behaving differently to our live web servers. After some experimentation it seems Glimpse is the cause (the version with Glimpse has not yet gone live, which is why the live servers were working normally).
e.g. this malicious URL:
http://website/?foo=<script>
...should cause the following error:
A potentially dangerous Request.QueryString value was detected from the client (foo="<script>").
However once Glimpse is registered in web.config "modules" section, the request validation doesn't happen (even when Glimpse is turned off), leaving the website open to cross site scripting attacks (XSS).
If I remove the line which registers Glimpse, then request validation immediately works normally: In in IIS 7.5 this is as follows:
<system.webServer>
<modules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
</modules>
Is there a way I can fix this, or is this a bug in Glimpse?
Update 1:
I've now verified the problem happens if I do a fresh install of Glimpse into an unrelated project (running ASP.NET 4.5.1), so it is not an incompatibility with the original project. I did not change any settings, I simply installed it from NuGet and the problem was immediately apparent.
I've also noticed I turn glimpse off by setting <glimpse defaultRuntimePolicy="Off" /> in Web.config, then the request validation also then kicks in as normal.

The way that request validation works in ASP.NET is that the input is validated and an exception thrown only for the first call to Request.RawUrl, Request.QueryString, and so on. Glimpse looks up the query string early on in the request (from RequestMetadata.get_RequestIsAjax) and swallows the exception, so future calls to Request.QueryString in the same request context will not be validated.
FWIW, the ASP.NET team has disowned request validation. See https://learn.microsoft.com/en-us/aspnet/aspnet/overview/web-development-best-practices/what-not-to-do-in-aspnet-and-what-to-do-instead#validation for more information.

Related

HTTP Error 403.14 - Forbidden on ASP.NET MVC API local website

Recently I had to reset windows on my work laptop due to a faulty driver that caused endless bluescreens after a few minutes of booting up. I use windows 10, and had windows on its own partition so all my work was unaffected by the reset.
This is relevant because before the reset, my ASP.NET sites would run perfectly fine locally with IIS 10, I could run my API site and use Postman to do HTTP requests as expected, login to a localized version of the site, etc. All without issues. After the reset, and the subsequent reinstalling of all the programs that were present before the reset, the API site no longer works as expected. Now I get a consistent 403.14 Forbidden error on the main page, and various other errors depending on whats being done.
I need to clarify that this site is not a directory site so enabling directory browsing as most answers to this questions tell to do is not the solution I need.
I've tried dozens of solutions both on SO and elsewhere, including:
-Making sure the IIS app pool is set to v4.0 and not v2.0
-Typing this: 'C:\windows\Microsoft.NET\Framework64\v4.0.30319> aspnet_regiis.exe -i'
in CMD.
-Making sure all the required features in 'turn windows features on/off' are on.
-Putting this:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
in the config.
-Trying this alternative to the above:
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
-Resetting all the repositories for the sites with a hard reset in git, then cleaning and rebuilding everything
-Checking with my coworker that both of our setups are the same, including all the important files and program settings (they are, his local sites work as expected)
-Reinstalling windows again and installing all the programs with great attention to what does what and what order they're installed in.
-Testing that it all works on my personal PC (it does)
The expected result is that the home page is a blank white page, and each of the controllers accessed from there (i.e. http://localhost/api.mysite/account/login/, .../account/getinfo/,.../account/changeinfo/) all work as expected accepting and returning json. The only error messages are as follows:
403.14 when attempting to access the site through a browser to the default page (http://localhost/api.mysite/)
405 error when POST-ing to the default page with Postman, as expected(?).
404 error when trying to POST or GET to any of the controllers methods in the API site with Postman. (http://localhost/api.mysite/account/login etc.)
Any help is greatly appreciated, this is incredibly frustrating! Thank you.

ASP.NET MVC handles 404 errors differently on local IIS and when deployed to Azure

I have a controller where an action returns a 404 error on ASP.NET MVC. Working locally, I get the page with 404 error correctly. When I deploy it to azure, instead of the page, I only get a text-only page:
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I've tried all three values on on customErrors mode in web.config (mode = Off, On, RemoteOnly) and it doesn't seem to change anything at all.
Why is Azure behaving differently on 404 errors and how can I make it behave the same as local IIS?
Okay I've found out the problem. Apparently, it wasn't even hitting the ASP.NET's custom errors handler, and was being caught at server level.
I've played with web.config and added this:
<httpErrors errorMode="Detailed">
<remove statusCode="500"/>
</httpErrors>
It now passes my error to the ASP.NET's custom error handler correctly.

Validation of viewstate MAC failed, but occurs on only 1 out of 2 webfarm servers (machine key is correct)

So I have something weird going on and i can not pin down exactly what is causing it. My asp.net project is live with session state on two production servers that are synced using the following command:
msdeploy -verb:sync -source:webserver,computername=%MACHINE%,username=Administrator,password=%PASSWORD% -dest:webserver 2<&1
The application is an asp.net 4.0 website that is run on two Server 2008 R2 web servers behind a load balanced configuration where the users are set to stick to one server once they connect. We have <MachineKey> set hardcoded with validation and decryption keys in the root site of the application and it is the same between both servers. My application is set up to forward exception events to our email system.
What is happening is that i am receiving the dreaded 'Validation of viewstate MAC failed' from the servers but even though the server load is 50/50 split the errors are coming in on a 99/1 split. So one web server is generating these errors considerably more often than the other one. This is strange considering the servers are synced and all configurations are identical.
I've done extensive searching on this problem and it seems quite difficult to find any solution that doesn't mention or do the following.
<MachineKey> is not identical between servers. (I know for a fact this is not my problem)
Setting enableViewStateMac=false or some other setting that jeopardizes the site security.
Make sure that all action tags on form inputs reference the same page they are placed on
Make sure the instance ID of the servers are the same (they are)
If the user clicks through the page before the entire page (viewstate) has been downloaded (my viewstate is set to render at the top of the page).
Issues with response.redirect and server.transfer
Now i have eliminated all except the last two as possible causes. My application has been running fine for over a year with no issues and right before these errors appeared i enabled SQL session state, migrated the project from .NET 3.5 to .NET 4.0, and set the set the server mode deployment mode to retail. I have tried recycling the application pools and performing an 'iis reset' to no avail.
Does anyone else have any suggestions as to what i can look at? Bottom line i do NOT want to fix this by opening up security holes in my site.
It appears this is happening to users right after they authenticate using forms authentication the first time they try to log in but i can not confirm this. I also have a theory that this might have to do with caching but i can't be sure on this either.
Here is the juicy bit from my web.config (i have removed some sensitive information)
<system.web>
<httpRuntime requestValidationMode="2.0"/>
<globalization culture="en-US" uiCulture="en-US" resourceProviderFactoryType="WebResourceFactory"/>
<compilation debug="true" defaultLanguage="c#" explicit="true" strict="true" targetFramework="4.0">
<assemblies>
</assemblies>
</compilation>
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" slidingExpiration="true"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<sessionState mode="SQLServer" sqlConnectionString="connection" compressionEnabled="true" />
<pages theme="Blue" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
<machineKey validationKey="key" decryptionKey="key" decryption="3DES" validation="SHA1" />
</system.web>
EDIT:Emphasized that i'm using SQL session state with a load balancer set to prefer to route users to the server they started on.
There is an additional possibility that you have not added to your list - ViewStateUserKey.
I have seen issues with applications where the ViewStateUserKey was set to the Session ID on logon and (crucially) before any data is saved to the Session. Since ASP.NET does not persist Session IDs until one or more objects are saved to session this meant that the ID was constantly changing and the Viewstate was failing validation. Even if you have saved something to Session then the Session will be different on each server if you are using the default in-process model and not a state server or SQL session store (as you are doing). Any server specific value or value that is not readily predictable across servers used with ViewStateUserKey will of course also cause this problem.
Otherwise the most common causes of this issue I have seen is where an "Action" attribute is set on a form that is not the URL of the same page as the form (this catches out developers used to PHP or platforms that do not attempt to abstract away from HTTP), or missing Machine Key attributes in the Web.config in multi-server environments (which you seem to have covered).
Ok i appear to have fixed it, though i can not discern what exactly caused it so i will just list all the steps i performed in case someone else has this problem later on.
1 :
Installed these windows updates:
2:
My forms authentication cookie was set to persistent but my session cookie was set to the browser session. I set my forms authentication cookie to be browser session based.
3:
I copied my from the site config to the root of IIS. From all the documentation i could find it should not be necessary for me to do this because IIS should support multiple machine keys for different sites / applications.
4:
Rebooted the server.
That's it! I have not received the errors since then.

To Increase Request Timeout only on particular Web Page

Is it possible to increase the request timeout for just the one particular web page? I am working on ASP.Net 4.0 and I need one particular page to have a longer request timeout, since it is responsible for initiating a long running process. Thanks.
Use Web.config:
<location path="Page.aspx">
<system.web>
<httpRuntime executionTimeout="180"/>
</system.web>
</location>
This is an old thread, but it should be emphasized that updating the executionTimeout of a page or the entire machine must also be accompanied by the compilation debug flag being set to "false", otherwise the timeout element is ignored.
Also, depending on whether or not you are using AJAX update panels, you may also have to look at the AsycPostBackTimeout flag on the ScriptManager itself - depends on how your timeout is manifesting itself. Ajax post back timeouts will be seen as error messages logged to the Javascript Console and tend to manifest themselves as ajax operations "dying on the vine" depending on how you are handling things.
The debug="false" bit is probably what is afflicting the gentleman above who was having issues on his Amazon Server, but not locally.
Some googling will also reveal that some folks have noticed that localhost handles things differently as well, so you may need to experiment around that.

Something faster than HttpHandlers?

What is the fastest way to execute a method on an ASP.NET website?
The scenario is pretty simple: I have a method which should be executed when a web page is hit. Nothing else is happening on the page, the only rendered output is a "done" message. I want the processing to be as fast as possible.
Every single hit is unique, so caching is not an option.
My plan is to use an HttpHandler and configure it in web.config (mypage.ashx) rather than a regular .aspx page. This should reduce the overhead significantly.
So my question is really: Is there a faster way to accomplish this than using HttpHandlers?
Depending on what you're doing, I wouldn't expect to see a lot of improvement over just using an HttpHandler. I'd start by just writing the HttpHandler and seeing how it performs. If you need it to be faster, try looking more closely at the things you're actually doing while processing the request and seeing what can be optimized. For example, if you're doing any logging to a database, try writing to a local database instead of across a network. If it's still not fast enough, then maybe look into writing something lower level. Until that point though, I'd stick with whatever's easiest for you to write.
For reference, I've written an ad server in ASP.NET (using HttpHandlers) that can serve an ad (including targeting and logging the impression to a local database) in 0-15ms under load. I thought I was doing quite a bit of processing - but that's a pretty good response time IMHO.
Update after several months:
If you clear all the HttpModules that are included by default, this will remove a fair amount of overhead. By default, the following HttpModules are included in every site via the machine-level web.config file:
OutputCache
Session (for session state)
WindowsAuthentication
FormsAuthentication
PassportAuthentication
RoleManager
UrlAuthorization
FileAuthorization
AnonymousIdentification
Profile
ErrorHandler
ServiceModel
Like I said above, my ad server doesn't use any of these, so I've just done this in that app's web.config:
<httpModules>
<clear />
</httpModules>
If you need some of those, but not all, you can remove the ones you don't need:
<httpModules>
<remove name="PassportAuthentication" />
<remove name="Session" />
</httpModules>
ASP.NET MVC Note: ASP.NET MVC requires the session state module unless you do something specific to workaround it. See this question for more information: How can I disable session state in ASP.NET MVC?
Update for IIS7: Unfortunately, things aren't quite as simple in IIS7. Here is how to clear HTTP Modules in IIS7
I'm not sure what your exact scenario is, but if all your page is doing is processing some data, you don't really need an aspx page or an http handler at all. You could write an ASMX web service or WCF service to do what you need and this would most likely be less overhead. The WCF service doesn't even have to be hosted in ASP.NET. You can host it from a Windows service or console app, and call it in-proc using named pipes. This would probably reduce the overhead for calling the data processing code significantly.
If you really have to use asp.net, you can also just hook into AuthorizeRequest step and intercept the request from there, do your processing and write your Done response directly.

Resources