I would like to create a route in my MVC application that will allow using hashtags in urls. If I would go to www.mydomain.com/#tag1 a specific controller for tag1 must take care of that request. If I would go to www.mydomain.com/#tag2, a different controller for tag2 must take care of that request.
Is this possible in MVC4?
use www.mydomain.com/ht#hashtag || then have ht defined as a forwarding or delegating controller that finds the correct controller to invoke
Is this even possible in MVC ?
This is not an issue with MVC. URL fragments (URLs with a hashtag #) are left up to the author of the browser to interpret. Many browsers do not pass this information back to the server, so relying on them for routing is not reliable across browsers.
So, in short yes this is possible with MVC (by customizing routing), but unless you can limit the browsers that your clients use to those that pass the fragment information to the server side it isn't practical.
RFC 2396 section 4.1:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
(emphasis added)
Typically, the usage of URL fragments is limited to the client side because that is the only place that all major browsers support them.
Related
I have an HTTPS post coming in via a secure form. Without going into lengthy explanation: I need to call an action within the same controller that accepts two tokens passed as parameters. When I run Fiddler, I see that that method is being called with the parameters in the URL. My question is: Does this pose a security risk? Is there a more secure way of redirecting within the same controller?
Yes, it poses a security risk, but it is easily mitigated by simply validating that the urls you are redirecting to are within the same domain as your source destination.
In fact, this is on the OWASP top 10.
A10 - Unvalidated Redirects and Forwards
EDIT:
I just realized that I missed the "ToAction" part of the question, so no.. It's not really possible to redirect outside of the site with RedirectToAction, so there isn't a worry for that. However, if you are using direct user input to feed into your RedirectToAction (and that includes accepting post data that you generate in a different page) then it's possible that an attacker could redirect to a method you did not anticipate. However, this is no different from a user simply trying random URL's and hitting one, or knowing a url and going to it manually. You need to have authorization in place to prevent access to URL's that the user does not have authorization to view.
If the original Action is accessed via HTTPS then RedirectToAction will redirect to a relative URL on the same domain using the same protocol.
So if your original page is
https://www.example.com/Foo/Bar
and this redirects to the FooBar action with some route parameters:
https://www.example.com/Foo/FooBar/1/2/3
an attacker cannot read the parameters 1/2/3 nor the rest of the URL.
However, the things you should bear in mind are:
The URL parameters will be logged by default by the browser (history), your server, by corporate proxy servers and possibly by other devices on your network by default.
If the user follows any links from your page to other https URLs, the referer HTTP header will contain your page address including parameters. Modern browsers will not send the referer header with http links though.
If there are any other https resources on your page this will cause the browser to send the referer header with the request.
For these reasons, if your parameters (1/2/3) are private, then you may wish to POST this data to the target page rather than use RedirectToAction (which results in a GET).
Note that you should be validating that the current user has access to the resources that 1/2/3 refers to (e.g. if the parameters were an order ID, you should check that the user identified by their auth cookies allow them to see the order referenced). Keeping 1/2/3 private are only beneficial if the parameters are themselves sensitive (e.g. a social security number).
Note that the OWASP Top 10 vulnerability, "A10 - Unvalidated Redirects and Forwards" does not apply here as RedirectToAction can only redirect to another action. If the other action redirects to a user set URL, then the vulnerability would lie there instead.
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?
Our Payroll application needs to be extended with a function that tracks when enter and leave work during the day. We are deploying a JSP page on several terminals around our country.
The JSP page that provides this capability, is part of a big struts2 application.
What we want, is to check the origin of the request, when the JSP page calls an action form one of out terminals. We need to check the IP, match the relative DNS name, and so on.... but this is not the matter!
The matter is: How should we do this ?
I am thinking about to develop an Interceptors that will be attached to all the actions that requires request origin validation.
Do you think this is a good approach?
Does already exists an interceptor that provide this functionality?
i don't know how to check the dns, but if you want to check the origin of the request, which i presume to be client's ip address, you can get it by httpServletRequest.getRemoteAddr(). don't forget to make your action implements ServletRequestAware
I'm trying to implement a small ASP.NET MVC site which interacts with another site. In short, sessions are managed between the main site and satellite sites through tokens in the URL. I can specify the url format but I can't remove the requirement that a session token is submitted as part of the URL.
I'm trying to work out how to set up the routing and am in a few minds here. I can't decide which would be best, or if there is perhaps a better way to do it. The main ways I'm thinking:
routes.MapRoute("Main", "{controller}/{action}/{id}/{token}");
Gives URLs like http://mysite.com/Products/Detail/5/5f1c8bbf-d4f3-41f5-ac5f-48f5644a6d0f
Pro: mostly keeps with existing MVC convention for site nagivation
Con: Adds complication to routing when supporting defaults for ID and Action.
routes.MapRoute("Main", "{token}/{controller}/{action}/{id}/");
Gives URLs like http://mysite.com/5f1c8bbf-d4f3-41f5-ac5f-48f5644a6d0f/Products/Detail/5
Pro: simplifies routing - can still apply action/id defaults as per standard MVC convention
Con: very "un-web-like" URLs. Requires regex to validate that the first variable is a valid GUID / token before moving on to next route in the table.
The other possibility coming to mind, passing sessions like:
http://mysite.com/Home/Index?session=5f1c8bbf-d4f3-41f5-ac5f-48f5644a6d0f
The related problem with that is I have a base class derived from Controller which all other secure pages are going through. The SecureController class overrides Execute() and checks for the validity of the token taken from the URL. Both approaches (GET and routing) seem like it would be easy enough to get the token within the controller Execute() function, but the GET approach feels kind of tacky whereas the routing approach feels like it's, for lack of better explanation, breaking the elegance of the MVC routing design.
Has anyone else out there taken on a similar problem and had any particular successes or difficulties to share?
It seems no matter you do, your URLs will be pretty messy with that token.
I have had to handle this kind of single sign-on functionality in an ASP.NET MVC app as well, but I went for a slightly different and much simpler approach: I created a GatewayController with a SignOn action that took a session token and a URL as parameters.
Then this SignOn action would just check the validity of the session token and then sign the user on to my site, redirecting to the supplied URL. From then on, the session token is not needed anymore, as authentication from then on would be cookie-based.
It might not be entirely applicable in your case, depending on your requirements. If you are required to continuously check the validity of the session token somewhere, you could however just do the same thing as I did and then store the session token in the user's session data, allowing you to check the token in each request.
I have seen a few examples of how to create RSS feeds using ASP.NET MVC, either by creating an Action or through an HttpHandler.
I need to authenticate feeds and am wondering how this is to be done (and supported by RSS readers rather than just browsing to the page/xml through a browser) and how would authentications differ between an MVC Action or HttpHandler?
the simplest way is to give each client an unique url. so in this case you always will know who is querying the feed.
http://site.com/rss/<some_secret_hash_here>
in other hand - you can use urls with standart user:password pair like:
http://user:password#site.com/rss/blabla.xml
and just parse user:password.
i prefer to use first one.
There are multiple ways to do it.
The best approach, according to me, is using REST architecture with credentials in either the path or as post-data (1st approach preferred).
1st Approach:
Step1: GET http://www.myserver.com/myfeed.rss/username/query => this should return a random value
Step2: GET http://www.myserver.com/myfeed.ress/username/hashed-password => The hashed password expected from the client is hash(<random-value>+<password>).
This will serve two purposes:
Original password is never transmitted on the wire
Random value ensures that the hash is unique, and hence, cannot be reused.
You may want to set an expiry date/time for the username + random-value combination with other IP related security actions to ensure that session hijack cannot happen.
EDIT:
Use HTTP Handler for the path="myfeed.rss" with verbs="GET" in web.config
and supported by RSS readers rather than just browsing to the page/xml through a browse
I would expect most readers to support typical (basic and digest) authentication. E.g. twitter's feeds require authentication.