I have built a custom HttpHandler that issues a status page whenever a specific resource is requested by the load balancer.
Some more background: It can't be a controller as I need to be able to share it with other assemblies and the company coding policy is not to allow controllers from other assemblies.
Also, I cannot use a delegating handler as I don't want to affect the pipeline by adding a global message handler.
So I have the following in the web.config:
<system.web>
...
<httpHandlers>
<!-- Status Page-->
<add verb="GET" path="*" type="Web.Api.Framework.StatusPageHandler, Web.Api.Framework" />
</httpHandlers>
...
</system.web>
<system.webServer>
...
<handlers>
<clear/>
<add name="StatusPageHandler" path="*" verb="GET" type="Web.Api.Framework.StatusPageHandler, Web.Api.Framework" />
</handlers>
...
</system.webServer>
When I try to access the handler (http://foo.bar/status) it fails with a 404. If I remove the resource mapping for the default controller (from global.asax) then it works. i.e. without the following statement in global.asax it works:
routes.MapRoute("Default", "{controller}", null, null);
I stumbled upon a url for which it does work: http://foo.bar/status/XXX, but that is hardly ideal - we don't want to have to extend the url in that "ugly" way.
How do I get it to work?
One way to get it to work. Change Web.Config like so.
<add name="StatusPageHandler" path="status" verb="GET"
type="Web.Api.Framework.StatusPageHandler, Web.Api.Framework" />
Add the line in Global.asax (RouteConfig.cs?) to ignore this route. Make sure you add this line before routes.MapRoute.
routes.IgnoreRoute("status");
Related
I'm creating a web application using the latest version of ASP.NET MVC 5.2.3. I just concern in XSS attack. I figure out in ASP.NET Core is perfectly working protecting from this attack the XSS and this framework totally amazing but it lacked third party I need to my project. Here's my concern. I already enabled the custom error too but I disabled it currently for testing.
But I want to make sure this will catch also.
Input Validation is passed. To avoid this exception or error.
A potentially dangerous Request.Form value was detected from the client (Name="").
using, the [AllowHtml] attribute this is fine or using the AntiXss library.
But, from the URL. Example URLs,
http://localhost:54642/Employees/
http://localhost:54642/Employees/?a=<script>
link or url
this error should like,
A potentially dangerous Request.Path value was detected from the client (<).
So my solution is enabling this from Web.config then it works!
But Troy Hunt said from his tutorial this is not a good or better practice for this error. So I decided to look the best solution from this XSS attack.
In my form I normally add this anti-forgery token
#Html.AntiForgeryToken()
then on my controller I made sure validate the token
[ValidateAntiForgeryToken]
also when passing the variable or data, I always declare correct variable. Anyways if its member area page you can always restrict access to correct member roles example like
[Authorize] // for registered user
or more filtered
[Authorize(Roles = "SUBSCRIBER.VIEW")]
Below is only applicable for .net 4.5 and above
// web.config
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
// enabling anti-xss
<httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
Request validation Lazy validation was introduced in ASP.NET 4.5, I
just did some testing on it and it seems that lazy validation is the
enabled regardless of how you set the "requestValidationMode", after
you've installed the 4.5 framework.
Check out OWASP site. Here is the common ones I add in system.web in web.config file of a webapi app.
<httpProtocol>
<customHeaders>
<remove name="Server" />
<remove name="X-Powered-By" />
<remove name="X-Frame-Options" />
<remove name="X-XSS-Protection" />
<remove name="X-Content-Type-Options" />
<remove name="Cache-Control" />
<remove name="Pragma" />
<remove name="Expires" />
<remove name="Content-Security-Policy"/>
<clear />
<add name="X-Frame-Options" value="DENY" />
<add name="X-XSS-Protection" value="1; mode=block"/>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="Cache-Control" value="no-cache, no-store" />
<add name="Pragma" value="no-cache" />
<add name="Expires" value="Sun, 1 Jan 2017 00:00:00 UTC" />
<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' data; img-src https://*;"/>
</customHeaders>
</httpProtocol>
The URL I'm trying to let work is one in the style of: http://somedomain.com/api/people/staff.33311 (just like sites as LAST.FM allow all sort of signs in their RESTFul & WebPage urls, for example "http://www.last.fm/artist/psy'aviah" is a valid url for LAST.FM).
What works are following scenarios:
- http://somedomain.com/api/people/ - which returns all people
- http://somedomain.com/api/people/staff33311 - would work as well, but it's not what I'm after
I'd want the url to accept a "dot", like the example below
- http://somedomain.com/api/people/staff.33311 - but this gives me a
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I've set up following things:
The controller "PeopleController"
public IEnumerable<Person> GetAllPeople()
{
return _people;
}
public IHttpActionResult GetPerson(string id)
{
var person = _people.FirstOrDefault(p => p.Id.ToLower().Equals(id.ToLower()));
if (person == null)
return NotFound();
return Ok(person);
}
The WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
I already tried following all the tips of this blogpost http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx but it still won't work.. I also think it's quite tedious and I wonder if there isn't another, better and more secure way.
We have our Id's internally like this, so we're going to have to find a solution to fit the dot in one way or another, preferably in the style of "." but I'm open to alternative suggestions for urls if need be...
Suffix the URL with a slash e.g. http://somedomain.com/api/people/staff.33311/ instead of http://somedomain.com/api/people/staff.33311.
Following setting in your web.config file should fix your issue:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
I've found that adding the following before the standard ExtensionlessUrlHandler solves the issue for me:
<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
path="api/*"
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
I don't think the name actually matters all that much except it probably helps if your IDE (Visual Studio in my case) is managing your site configuration.
H/T to https://stackoverflow.com/a/15802305/264628
I don't know what I am doing really, but after playing with the previous answer a bit I came up with another, perhaps more appropriate, solution:
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>
I found that I needed to do more than just set the runAllManagedModulesForAllRequests attribute to true. I also had to ensure that the extensionless URL handler was configured to look at all paths. In addition, there is one more bonus configuration setting you can add which will help in some cases. Here is my working Web.config:
<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="WebDAV" />
<remove name="OPTIONSVerbHandler" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Note, specifically, that the ExtensionlessUrlHandler-Integrated-4.0 has its path attribute set to * as opposed to *. (for instance).
I'd use this in Web.config file:
<add name="ManagedSpecialNames" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
before standard "ExtensionlessUrlHandler".
For instance in my case I put it here:
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ManagedFiles" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
So you force URLs of such pattern to be managed by you, instead of standard management as files in application directory tree.
I got stuck in this situation but appending /
at the end of URL wasn't look clean for me.
so just add below in web.config handlers tag
and you will be good to go.
<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
I found that both way works for me: either setting runAllManagedModulesForAllRequests to true or add ExtentionlessUrlHandler as following. Finally i choose to add extensionUrLHandler since runAllManagedModulesForAllRequests do have performance impact to the site.
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
I also faced this issue. I was under a circumstance where I was not supposed to play with IIS and website config related settings. So I had to make it working by making changes at the code level only.
The point is that the most common case where you would end up having dot character in the URL is when you get some input from the user and pass it as a query string or url fragment to pass some argument to the parameters in the action method of your controller.
public class GetuserdetailsbyuseridController : ApiController
{
string getuserdetailsbyuserid(string userId)
{
//some code to get user details
}
}
Have a look at below URL where user enters his user id to get his personal details:
http://mywebsite:8080/getuserdetailsbyuserid/foo.bar
Since you have to fetch some data from the server we use http GET verb. While using GET calls any input parameters can be passed only in the URL fragments.
So to solve my problem I changed the http verb of my action to POST. Http POST verb has the facility of passing any user or non-user input in body also. So I created a JSON data and passed it into the body of the http POST request:
{
"userid" : "foo.bar"
}
Change your method definition as below:
public class GetuserdetailsbyuseridController : ApiController
{
[Post]
string getuserdetailsbyuserid([FromBody] string userId)
{
//some code to get user details
}
}
Note: More on when to use GET verb and when to use POST verb here.
I've started learning (and using) Monorail a little while ago, and recently, I've dabbled into routing. Unfortunately, the documentation around it is kinda sparse, but I've managed to get some info from various blog posts, most of them 2 years + old. I managed to setup the routing pretty quickly, BUT I realized that Monorail's routing engine confuses .jpeg files as controller/action requests WHEN they are not found.
The webconfig file is pretty standard:
<monorail useWindsorIntegration="false" defaultUrlExtension=".rails">
<url useExtensions="true"/>
<controllers>
<assembly>NetTwitter.Web</assembly>
</controllers>
<viewcomponents>
<assembly>NetTwitter.Web</assembly>
</viewcomponents>
<viewEngine viewPathRoot="Views" customEngine="Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine, Castle.MonoRail.Framework.Views.NVelocity"/>
</monorail>
<system.web>
<httpHandlers>
<!-- block direct user access to template files -->
<add verb="*" path="*.vm" type="System.Web.HttpForbiddenHandler"/>
<add verb="*" path="*.boo" type="System.Web.HttpForbiddenHandler"/>
<add verb="*" path="*.st" type="System.Web.HttpForbiddenHandler"/>
<add verb="GET" path="*.css" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.js" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.jpg" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.gif" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.png" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.jpeg" type="System.Web.StaticFileHandler" />
<add verb="*" path="*.rails" type="Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, Castle.MonoRail.Framework"/>
</httpHandlers>
<httpModules>
<add name="routing" type="Castle.MonoRail.Framework.Routing.RoutingModuleEx, Castle.MonoRail.Framework" />
</httpModules>
As is the initialization of the routing engine inside the Global.asax:
public void Application_OnStart()
{
log4net.Config.XmlConfigurator.Configure();
RoutingModuleEx.Engine.Add(
new PatternRoute("<controller>/[action]"));
}
The error itself says it pretty clearly:
{"Controller not found. Area: '' Controller Name: 'content'"}
So, what can I do? Thanks in advance.
This is because you are using the RoutingModuleEx. That will rewrite the URL before the actual httpHandlers are matched against.
And your route is to general for this, probably.
We solve it by having a /static/ folder which has it's own web.config, therefore overriding the original web.config.
This one contians only:
<system.webServer>
<handlers>
<clear/>
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
You might want to remove the rounting module from here as well, since it might be inherited. We have however not noticed any issue with it, but haven't really put my head in it either. It might be that we don't match any routes when we are one level down, or subfolders doesn't inherit httpModules.
Why cant i register a HttpModule under a directory?
<system.web>
<httpHandlers>
<add verb="*" path="/home/facebookredirect.axd" type="Facebook.Web.FacebookAppRedirectHttpHandler, Facebook.Web" />
</httpHandlers>
</system.web>
<handlers>
<add name="facebookredirect.axd" verb="*" path="/home/facebookredirect.axd" type="Facebook.Web.FacebookAppRedirectHttpHandler, Facebook.Web" />
</handlers>
when the request comes to /home/facebookredirect.axd i m getting a 404. why this is not working?
I want the facebookredirect.axd to work under /home/
Below is frm, global.asx
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Essentially. home doesnt exist, there is a home controller. But i want to use this path.
path="/home/facebookredirect.axd"
should be:
path="home/facebookredirect.axd"
Also you need to exclude this url from your routes:
routes.IgnoreRoute("home/{resource}.axd");
It's probably because there is a generic .axd handler (i.e. *.axd) added before yours.
If you remove this before adding your handlers, then add it back in after your handler is added, it could resolve the problem (disclaimer: haven't tried it, just going on the evidence).
Try to add resourceType="Unspecified"
so it becames
<add name="facebookredirect.axd" verb="*" path="/home/facebookredirect.axd"
type="Facebook.Web.FacebookAppRedirectHttpHandler, Facebook.Web"
resourceType="Unspecified" />
At least, i have handlers working with folders with the same declaration.
Also folder "Home" should exists on server
I know that if I want to have requests for MyPage.aspx go to the class called MyHandler in the assembly called MyAssembly, I can add this to my web.config file:
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="MyPage.aspx" type="MyHandler, MyAssembly"/>
</system.web>
</configuration>
This works for any MyPage.aspx at the (made up) URL: www.mycoolsite.com/MyProject/[SomePathHere]/MyPage.aspx
What if I want to do it for every MyPage.aspx except www.mycoolsite.com/MyProject/NoHandler/MyPage.aspx
Is there a way to exclude that path from the handler?
You can put a web.config in the NoHandler folder that defines a different handler (NotFound if you want to server a 404 style, etc). Same format as your current web.config, just put only the elements you want to override like the handler.
Here's an example if you want to override with a 404 in that directory:
<configuration>
<system.web>
<httpHandlers>
<remove verb="*" path="MyPage.aspx" type="MyHandler, MyAssembly"/>
<add verb="*" path="MyPage.aspx" type="MySpecialHandler, MyAssembly"/>
</httpHandlers>
</system.web>
</configuration>