I'm trying to solve a "A potentially dangerous Request.Form value was detected from the client" problem, and SO answers and Scott Hanselman recommend setting
<httpRuntime requestValidationMode="2.0" />
in Web.config (along with adding an attribute to problematic Methods).
I realize this changes the validation mode to ASP.NET 2.0's, but what does that mean?
And also, does this change has any side effects I should be aware of?
Thanks.
Check out the description at MSDN's HttpRuntimeSection.RequestValidationMode Property.
2.0. Request validation is enabled only for pages, not for all HTTP requests. In addition, the request validation settings of the pages
element (if any) in the configuration file or of the # Page directive
in an individual page are used to determine which page requests to
validate.
Take a look at ASP.NET Request Validation>
The request validation feature in ASP.NET provides a certain level of
default protection against cross-site scripting (XSS) attacks. In
previous versions of ASP.NET, request validation was enabled by
default. However, it applied only to ASP.NET pages (.aspx files and
their class files) and only when those pages were executing.
In ASP.NET 4, by default, request validation is enabled for all
requests, because it is enabled before the BeginRequest phase of an
HTTP request. As a result, request validation applies to requests for
all ASP.NET resources, not just .aspx page requests. This includes
requests such as Web service calls and custom HTTP handlers. Request
validation is also active when custom HTTP modules are reading the
contents of an HTTP request.
As a result, request validation errors might now occur for requests
that previously did not trigger errors. To revert to the behavior of
the ASP.NET 2.0 request validation feature, add the following setting
in the Web.config file:
<httpRuntime requestValidationMode="2.0" />
However, we recommend that you analyze any request validation errors
to determine whether existing handlers, modules, or other custom code
accesses potentially unsafe HTTP inputs that could be XSS attack
vectors.
Related
I have a single, embedded orbeon instance, behind a spring gateway with JWT security. This works well, for the orbeon builder, I need to forward the Authorization header to make the things working properly.
But for the form-runner, now I have a requirement: for some forms the authentication is required, for some others it is not.
It is possible to configure the Orbeon in the following way: if the Authorization header is present, forward it, if not, do nothing (just load the form and let it fill)?
This is the settings for header forwarding in my properties-local-prod.xml
<property
as="xs:string"
name="oxf.http.forward-headers"
value="Authorization"/>
<property
as="xs:string"
name="oxf.xforms.forward-submission-headers"
value="Authorization token allowDraft"/>
<property
as="xs:string"
name="oxf.fr.authentication.method"
value="header"/>
At now I got the default Orbeon unauthorized page.
I got 401 when I am trying to open the embedded from-runner without authentication (obviously there is nothing to send towards to orbeon). I found this in orbeon log:
HTTP status code 401 {controller: "oxf:/apps/fr/page-flow.xml", method: "GET", path:
"/fr/app/form/edit/myforminstanceid", status-code: "401"}
A possible solution would be if it would be possible to define some kind of run context that can be applied per form definition basis, like prod-auth, prod-public (unfortunately these should be active parallelly as we have a single Orbeon instance). (Further thinking the already available run modes, e.g. for the same set of forms I should be able to define that the save-draft is visible for autenticated users, but not for the anonymous users... although I have already solved this with some not-that-nice javascript magic.)
Orbeon itself does not do anything when one put a similar config to the properties-prod.xml, just forwards the given headers.
Albeit the default Orbeon Forms logging could be better (about the further HTTP calls to be aware what is happening in the background), there was that single line in the log what it did when the request arrived. As it turned out, my custom backend (persistence layer) expected the Authorization header.
I had to put to my spring security config a (/contextRoot/orbeon).permitAll() and it started to work.
I've got a public MVC 5 web-site, using the anti-forgery token. Every day a large number of errors are logged in the form of "The anti-forgery cookie token and form field token do not match.", and a lesser number in the form of "The required anti-forgery cookie "__RequestVerificationToken" is not present.".
The problem is not reproducible, it occurs for different people on different pages at different times. Closing the browser resolves the problem - sometimes just using the Back button and re-trying resolves the problem.
As the website works for the vast majority of users, I can rule out missing ValidateAntiForgeryToken attributes in controllers, likewise, I can rule out missing or duplicate #Html.AntiForgeryToken() code in the views.
The website runs on a single server, so I can rule out different machinekeys in the web.config (I've tried running the website with and without this setting anyway).
The application pool is set to restart each night, and there's plenty of spare resource on the
server, so I can rule out the application pool restarting and invalidating sessions (especially as this isn't logged in the event log or anywhere else).
I've hit the problem very rarely - I definitely have cookies enabled, so I can rule out cookies being disabled. I can also rule out javascript being disabled, as user's can only progress so far into the site without JS - and errors occur on pages beyond this point.
I've disabled all caching, setting nocache, nostore etc. This seemed to reduce the occurrence of the issue, but it still persisted (I had to re-enable caching for a variety other reasons).
What other options are there to consider?
I am so frustrated by this I am considering turning off anti-forgery protection and contributing to the global weakening of security.
Make sure you have AntiForgery attributes both in controller and forms.
If you are doing ajax post maybe you can send RequestValidationToken as a parameter.
$('input[name=__RequestVerificationToken]').val()
Also maybe somebody attacking your site or using some bots to get content or post forms.
so it is possible that form just shows validation error (like HTML is not allowed) instead of throwing an exception
A potentially dangerous Request.Form value was detected from the client
when I include HTML in input. I dont want to accept HTML, but I also dont like to get exception.
In ASP .NET 4.0, request validation is enabled for all requests by default.
http://www.asp.net/whitepapers/aspnet4/breaking-changes
You can still force your app to ignore this check.
See link for details:-
ValidateRequest="false" doesn't work in Asp.Net 4
However, I wouldn't advocate this strategy. It's much better to try to validate the text with Javascript before sending to the server to ensure it doesn't contain any characters that trip the ValidateRequest behaviour.
This question covers all of those characters:-
What characters or character combinations are invalid when ValidateRequest is set to true?
If your user does not have Javascript enabled, you'll still hit the error. In that (rare) case, you can fall back on customErrors so that you at least show something that is prettier than the yellow error page.
You can handle application behavior on errors in your web.config file:
</system.web>
…
<customErrors defaultRedirect="/ErrorPage" mode="RemoteOnly"></customErrors>
…
</system.web>
Moreover, beside specifying whether to show detailed errors or not you can also redirect user to a specific page to show him custom errors pages which you have designed.
For more information about this check msdn explanation for customErrors element
I have an ASP MVC 3 website that has a Feedback form and should require SSL.
Now, I have an action called Feedback inside a controller called 'ContactUs' that is responsible for viewing and processing the feedback.
When I used the [RequireHttps] attribute on that action, it works nice and it changes the URL to "https". However, I noticed that all the links inside my page are now pointing to "https"! As if this attribute had forced the routing engine to apply the same to all links!!!
Of course, the SSL is only required for this single action and all the rest need to have normal http.
Could anyone tell me how to solve this?
In your case [RequireHttp] attribute might be OK if you clear out the login cookie - or you'll be sending it in clear-text across the wire. It might be more work than it's worth to avoid the slight cost of further HTTPS calls. SO is all about recycling questions and other users reading your question might think it's OK to drop down to HTTP after login, when it's usually the wrong thing to do.
The [RequireHttps] attribute can be used on a controller type or action method to say "this can be accessed only via SSL." Non-SSL requests to the controller or action will be redirected to the SSL version (if an HTTP GET) or rejected (if an HTTP POST). You can override the RequireHttpsAttribute and change this behavior if you wish. There's no [RequireHttp] attribute built-in that does the opposite, but you could easily make your own if you desired.
There are also overloads of Html.ActionLink() which take a protocol parameter; you can explicitly specify "http" or "https" as the protocol. Here's the MSDN documentation on one such overload. If you don't specify a protocol or if you call an overload which doesn't have a protocol parameter, it's assumed you wanted the link to have the same protocol as the current request.
The reason we don't have a [RequireHttp] attribute in MVC is that there’s not really much benefit to it. It’s not as interesting as [RequireHttps], and it encourages users to do the wrong thing. For example, many web sites log in via SSL and redirect back to HTTP after you’re logged in, which is absolutely the wrong thing to do. Your login cookie is just as secret as your username + password, and now you’re sending it in clear-text across the wire. Besides, you’ve already taken the time to perform the handshake and secure the channel (which is the bulk of what makes HTTPS slower than HTTP) before the MVC pipeline is run, so [RequireHttp] won’t make the current request or future requests much faster.
You can create another custom filter attribute to move back to http. Try solution from this question...
Why once SSL is enabled with [RequireHttps] at action level, it remains enabled forever?
Is ASP.NET MVC 2 vulnerable to the oracle padding attack? If so, what workaround should be implemented? The instructions on Scott Gu's blog appear to only be for Webforms.
I tried this:
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="/Home/ErrorPage" />
however, http://www.example.com/PageThatDoesNotExist still returns a standard 404 error page.
EDIT: I see that Scott Gu posted in the comments under his blog post that MVC is vulnerable, but it's still not clear to me exactly how to implement the workaround.
Yes - linkage to the comment by Scott Guthrie.
Saturday, September 18, 2010 9:00 PM by ScottGu
#Vijay,
Will the ASP.NET MVC too get affected?
Yes - all versions of ASP.NET are affected, including ASP.NET MVC.
Thanks,
Scott
I see that you've seen the comment, but if you run the vbs script on your server, it should tell you if it's still a problem.
Edit: Also, Scott has discussed FAQs in a new post here.
Under your default route you could/should add this for starters
routes.MapRoute("Catch All", "{*path}", new { controller = "Home", action = "ErrorPage" });
Edit 2
the problem lies in the part redirectMode="ResponseRewrite" without this, it works.
using the route though will fix 1 part of the problem, where the path cant be found (404)
the next part, like existing paths with bad ID's or other data, could be fixed with
<customErrors mode="On" defaultRedirect="/Home/ErrorPage" />
what exactly does redirectMode="ResponseRewrite" do?
Edit: what it does.
redirectMode
ResponseRedirect: Specifies that the
URL to direct the browser to must be
different from the original Web
request URL.
ResponseRewrite:
Specifies that the URL to direct the
browser to must be the original Web
request URL.
It only matters for .NET 3.5 SP1 and .NET 4.0.
Edit 101:
For redirectMode="ResponseRewrite" the ASP.NET calls Server.Execute(...) internally, which does not work with MVC routes, so for MVC this only works with a static HTML file.
<customErrors mode="On" defaultRedirect="~/Views/Shared/error.htm" redirectMode="ResponseRewrite" />
works.
This question is included in Scott Gu's Frequently Asked Questions about the ASP.NET Security Vulnerability:
Does this affect both ASP.NET Web Forms and ASP.NET MVC?
Yes – the publicly disclosed exploit can be used against all types of ASP.NET Applications (including both Web Forms and MVC).
I posted my full take on this (after extra research) on my blog.
Update note: moved the link to a post specific to asp.net MVC
I strongly believe the issue with the 404s is related to WebResources and ScriptResources (which can disable for asp.net MVC btw), as those probably give 404s when the corresponding resource isn't found (which would be the normal response to an valid padding that gives an invalid resource path/name).
Other error codes & messages could be an issue for other asp.net features, but ending with a 404 only because you hit an url non related to any special handler shouldn't be causing the issue.
Also note what I mentioned in this answer:
How serious is this new ASP.NET security vulnerability and how can I workaround it?
if the app is asp.net MVC we don't really need webresources.axd and/or scriptresources.axd, so those can be turned off. We also don't use viewstate.
asp.net membership provider 'caches' roles in cookies, turn that off.
The auth cookie is signed, and from the info in the paper they shouldn't be able to generate a signed cookie if they don't get to the actual keys (as they did in the video before forging the auth cookie).
As Aristos mentioned, for the session id in the cookie, that's random for the user session, so it'd have to be sniffed from an user with the target security level and cracked while that session is active. Even then if you are relying in authentication to assign/authorize the user operations, then the impact would be minimal / it'd depend a lot in what Session is used for in that app.
A patch for this bug has been released on Windows Update.
http://weblogs.asp.net/scottgu/archive/2010/09/30/asp-net-security-fix-now-on-windows-update.aspx
Do you have a route/controller action setup to return an error page for the /Home/ErrorPage route?