I have an application that has to deal with getting "special" characters in its URL (like &, +, %, etc). When I'm sending a request to the application using these characters (of course I'm sending them escaped) I'm getting "Bad Request" response code with the message "ASP.NET detected invalid characters in the URL". Tracing the request shown me that the error was thrown from the "Authentication Module".
I've searched a bit and found that every page has a ValidateRequest and changing its value to false solves the problem. Unfortunately I'm using Httphandler. Does anyone know how to stop the request validation using http handler?
I ran into the same problem (creating an IHttpHandler that needed to receive requests with special characters in the URL). I had to do two things to fix it:
Create the following DWORD registration entry with a value of 1: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\VerificationCompatibility
In the web.config, set the allowDoubleEscaping attribute of the requestFiltering element to true.
I had the same problem and got it working by setting validateRequest="false" as well as requestValidationMode="2.0", like below. No registry edits.
<system.web>
<httpRuntime requestValidationMode="2.0" />
...
<pages ... validateRequest="false" />
</system.web>
Wholesale changes at the application or machine level were not acceptable to me. I only had one parameter that a client was sending incorrectly that I needed to scrub.
I found that when a request is made with html or other potentially dangerous items in the query string, you can scrub the string by using the context.Request.RawUrl and, once the query string is scrubbed, use context.RewritePath(scrubbedUrl).
First thing in the handler, get the context.Request.RawUrl
Scrub the bad request RawUrl for bad input
context.RewritePath(srubbedUrl)
Profit
It seems like request validation only cares about accessing context.Request.Params[], so if you scrub and rewrite path (to the same path) before the Params collection is accessed, you're golden.
Below solution worked for me-
Create the following DWORD registration entry with a value of 1: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\VerificationCompatibility
In the web.config, set the allowDoubleEscaping attribute of the requestFiltering element to true.
You can remove all the modules with
<httpModules>
<clear />
</httpModule>
to make the request get to your handler. Or maybe you can remove the specific modules that are stopping your request.
This is the list of modules loaded by default in ASP.NET 2.0 from here
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" />
<add name="Profile" type="System.Web.Profile.ProfileModule" />
</httpModules>
How about this?
<system.web>
<pages validateRequest="false">
</pages>
</system.web>
Since .NET Framework 4.5, you can use the Unvalidated property on HttpRequest or HttpRequestBase to access form, query string and URL data in a way that will not trigger request validation. If you avoid accessing these values in any other way (including in helper methods or other HTTP modules running in the same request), you will not require anything else to avoid request validation.
You can set validateRequest to false in the pages section of the web.config. Maybe that works for HttpHandlers as well?
Related
In my MVC5 application, I have a data-grid which has it's filter/sort criteria specified inside the URL. When a user selects a Record to Edit/Create/Delete, I needed to save the URL value so that when the Controller POST action completed, they would be returned to the exact same layout they were on before the GET action was triggered (same data-grid with sort/filter criteria applied).
In my pursuit of this funcitonality, I began using a session variable in my Controller. On GET:
Session["returnURL"] = Request.UrlReferrer.AbsoluteUri;
I set a session variable of returnURL to the current full path URL of my Browser. The on the post, after my changes to the record/database are saved, I have check the returnURL variable for null and perform a Redirect():
var returnURL = (Session["returnURL"] != null) ? Session["returnURL"].ToString() : Url.Action("Index", "Home");
return Redirect(returnURL);
This all works perfectly fine on my localhost, but when I publish it to my Server each time I attempt to navigate to Edit/Create/Delete actions for my record, the Session Variable on the GET actions causes:
Server Error in '/' Application.
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error: [No relevant source lines]
After a lot of trial and error I diagnosed that it is my Session Variable that is causing this NullReferenceException as when I remove that specific code line from my GET action method, everything else functions fine and the appropriate View loads.
Can anyone helps with this? I'm at a loss for why my Session Variable is working on my Localhost but not on my Server. I took a look at the following MSDN article https://msdn.microsoft.com/en-us/library/h6bb9cz9(v=vs.71).aspx, but I'm still getting the same result even with <configuration><system.web> <sessionState mode="InProc"></sessionState>... specified in my Web.Config.
EDIT:
At ps2goat's suggestion, I modified my Web.Config to include:
<system.web>
<sessionState mode="InProc"></sessionState>
// ....
<pages enableSessionState="true">
<namespaces>
<add namespace="GridMvc" />
<add namespace="MvcSiteMapProvider.Web.Html" />
<add namespace="MvcSiteMapProvider.Web.Html.Models" />
</namespaces>
</pages>
// ....
</system.web>
Still receiving the same NullReferenceException error...? I have now specified the sessionState = InProc and set <pages enableSessionState="true">.
I found the answer in this post (The Session object is null in ASP.NET MVC 4 webapplication once deployed to IIS 7 (W 2008 R2)), wherein I modified my <modules> section to do an add/remove of the below specified values:
<configuration>
...
<system.webServer>
...
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
...
</modules>
</system.webServer>
</configuration>
I'm still not entirely sure WHY this is the answer, but it worked for my issue in this case.
After multiple hours of reading, I came up that the IIS doesn't support more than one
"Access-Control-Allow-Origin" header.
Also setting the value with "*" isn't allowed with error:
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin'
header when the credentials flag is true. Origin 'null' is therefore
not allowed access.
Other SO questions came up with solutions like this one or this one but I don't know where I do have to change the header.
My application is written in .NET and I'm using IIS 8.5. My target is to do a CORS request for multiple origin domains. Do I have to write a IHttpModule to handle the origin header?
I came up with my own solution which also works like Google+ or Facebook auth. Here is another SO question based on iFrame auth
You can use an iFrame as middleware. Within the iFrame I make a request to my application on same origin/domain.
For example:
My application comes from www.domainA.com another from www.domainB.com and both of them do contain an iFrame from www.hostingdomain.com.
From www.hostingdomain.com I do make a call to my webservice and set a cookie based on .NET FormsAuthentication. For IE you do have to use the P3P to set a 3rd party cookie.
You can use IIS CORS Module: https://www.iis.net/downloads/microsoft/iis-cors-module
Your web.config should be something like this replacing [origin_#] for your domains:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="[origin_1]">
<allowMethods>
<add method="GET" />
<add method="HEAD" />
<add method="POST" />
<add method="PUT" />
<add method="DELETE" />
</allowMethods>
</add>
<add origin="[origin_2]">
<allowMethods>
<add method="GET" />
<add method="HEAD" />
<add method="POST" />
<add method="PUT" />
<add method="DELETE" />
</allowMethods>
</add>
</cors>
</system.webServer>
</configuration>
You can find the configuration reference in here: https://learn.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference
I have a form at which I use ckeditor. This form worked fine at Asp.Net 2.0 and 3.5 but now it doesn't work in Asp.Net 4+. I have ValidateRequest="false" directive. Any suggestions?
Found solution on the error page itself. Just needed to add requestValidationMode="2.0" in web.config
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime requestValidationMode="2.0" />
</system.web>
MSDN information: HttpRuntimeSection.RequestValidationMode Property
There is a way to turn the validation back to 2.0 for one page. Just add the below code to your web.config:
<configuration>
<location path="XX/YY">
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
</location>
...
the rest of your configuration
...
</configuration>
I know this is an old question, but if you encounter this problem in MVC 3 then you can decorate your ActionMethod with [ValidateInput(false)] and just switch off request validation for a single ActionMethod, which is handy. And you don't need to make any changes to the web.config file, so you can still use the .NET 4 request validation everywhere else.
e.g.
[ValidateInput(false)]
public ActionMethod Edit(int id, string value)
{
// Do your own checking of value since it could contain XSS stuff!
return View();
}
This works without changing the validation mode.
You have to use a System.Web.Helpers.Validation.Unvalidated helper from System.Web.WebPages.dll. It is going to return a UnvalidatedRequestValues object which allows to access the form and QueryString without validation.
For example,
var queryValue = Server.UrlDecode(Request.Unvalidated("MyQueryKey"));
Works for me for MVC3 and .NET 4.
Note that another approach is to keep with the 4.0 validation behaviour, but to define your own class that derives from RequestValidator and set:
<httpRuntime requestValidationType="YourNamespace.YourValidator" />
(where YourNamespace.YourValidator is well, you should be able to guess...)
This way you keep the advantages of 4.0s behaviour (specifically, that the validation happens earlier in the processing), while also allowing the requests you need to let through, through.
In an ASP.NET MVC4 application I have a custom output cache provider defined.
My configuration is like this:
<system.web>
<caching>
<outputCache defaultProvider="DiskOutputCache" enableOutputCache="true" >
<providers>
<add name="DiskOutputCache" type="ProExam.DMC.MvcUtil.DiskOutputCache, ProExam.DMC.MvcUtil, Version=1.0.0.0, Culture=neutral"/>
</providers>
</outputCache>
<outputCacheSettings>
<outputCacheProfiles>
<add name="forever" duration="2147483647" varyByParam="id" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
I have an action like this:
[OutputCache(CacheProfile = "forever")]
public ActionResult View(UrlParamString id)
{
...
}
When I run in debug, only the get method of my custom output cache provider is called. Never the set or the add. Any help would be appreciated...
Try reducing the duration. You defined an almost infinite cache duration this means while the app is running, it will not try to store your cache item again.
Duration is set in seconds... Try duration="10" or something and see what happens.
Apart from that you can also try to define enabled="true" location="Server" in your cache profile.
Try adding location attribute to web.config entry.
<add name="LongLivedProfile" duration="86400" location="Any" varyByParam="*" />
Check that you do not write any cookies during the request. Outputcache does not call add/set if you write a cookie.
Check This: Custom OutputCache provider is not working (get is called but not set or add)
It doesn't work if you are using cookies.
Also Check Note Section for CacheProfile: https://msdn.microsoft.com/en-us/library/vstudio/hdxfb6cy(v=vs.100).aspx
This attribute is not supported for # OutputCache directives included in user controls (.ascx files). When specified on a page, the value must match the names of one of the available entries in the outputCacheProfiles element under the outputCacheSettings section. If the name does not match a profile entry, an exception is thrown.
I am trying to implement Swagger with Service Stack. I've installed service stack with swagger using nuget. Current DLL versions are reported as 3.9.56.0 mostly.
I am trying to follow the example provided at...
https://github.com/ServiceStack/ServiceStack.UseCases/tree/master/SwaggerHelloWorld
and the instrucstion appear fairly fool-proof...
Plugins.Add(new ServiceStack.Api.Swagger.SwaggerFeature());
goes into the 'Configure' method after I've installed via nuget (as the documentation instructs), then I've added [ApiMember] and [Api] tags, along with changes to the [Route] tags to add Summary and Notes
but when I visit ~/swagger-ui/index.html i get the error
Please specify the protocol for ../api
My api sits at ~/api, and I have a single method at the moment (Hello World) sitting at ~api/Hello/{name} which returns JSON and works ok.
if I visit ~apii get the message Handler for Request not found: with a stack trace type output.
What am I doing wrong? The instructions to enable swagger appear really straight forward, and detailed instructions appear to be lacking, probably because it should 'just work', please help!
Update to address Esker...
Stack trace # myhost:54011/api
Handler for Request not found:
Request.ApplicationPath: /
Request.CurrentExecutionFilePath: /api
Request.FilePath: /api
Request.HttpMethod: GET
Request.MapPath('~'): D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\
Request.Path: /api
Request.PathInfo:
Request.ResolvedPathInfo: /api
Request.PhysicalPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\api
Request.PhysicalApplicationPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\
Request.QueryString:
Request.RawUrl: /api
Request.Url.AbsoluteUri: http://localhost:54011/api
Request.Url.AbsolutePath: /api
Request.Url.Fragment:
Request.Url.Host: localhost
Request.Url.LocalPath: /api
Request.Url.Port: 54011
Request.Url.Query:
Request.Url.Scheme: http
Request.Url.Segments: System.String[]
App.IsIntegratedPipeline: True
App.WebHostPhysicalPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger
App.WebHostRootFileNames: [global.asax,global.asax.cs,helloservice.cs,jquery-1.10.2.js,packages.config,servicestackswagger.csproj,servicestackswagger.csproj.user,web.config,web.debug.config,web.release.config,app_data,app_start,bin,controllers,dto,models,obj,properties,swagger-ui,views]
App.DefaultHandler: metadata
App.DebugLastHandlerArgs: GET|/api|D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\api
Also, "Please specify protocol' is a swagger error, displayed onscreen in html underneath the aforementioned 'textbox to change discovery url'
and the DLL versions are 'mostly' the same because ServiceStack.Redis is version 3.9.57.0, but I'm not using that, so 'mostly'
Update... My Solution
I needed this in my web.config file inside of the <configuration> tag, I had previously not included the <location path="api"> bit.
<!-- ServiceStack: CustomPath /api -->
<location path="api">
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
</location>
also... I had set up my 'routes' as such...
//INCORRECT
[Route("/api/Hello/{name}", Summary = #"N031'5 ServiceStackSwagger thingy", Notes = "Some more info in here cause these are notes")]
public class Hello : IReturn<HelloResponse>
but that messed with swagger's functionality, it needed to be...
//CORRECT
[Route("/Hello/{name}"...
with the 'api' bit REMOVED, and now everything is working.
You need to tell Swagger about the specific URL of the ServiceStack Swagger endpoint, rather than the base URL of your services. This endpoint is located at /resources under your base URL. So, instead of ../api for the discoveryUrl, use ../api/resources, like so, in your index.html file:
window.swaggerUi = new SwaggerUi({
discoveryUrl: '../api/resources',
...