I have many Ajax.ActionLink's on my ASP.NET MVC (v1) page that perform destructive operations. This is "legal" because I set HttpMethod to DELETE in this case so it's not a destructive GET.
My question though is how to mitigate XSRF attacks on this operation so that other sites cannot craft this same Ajax DELETE request to delete user data from another site. This ActionLink does appear within a form that includes <%= Html.AntiForgeryToken() %> but since ActionLinks don't post the form, the anti-forgery token doesn't go to the controller, so it can't validate it.
To prevent against Cross-Site Request Forgery attacks you must block requests that originate from another site. In asp.net you can do this by checking to see if Request.UrlReferrer isn't from your host name. If the ajax request originated from a different server, then you should ignore the ajax request. If the referrer is null, then you should also ignore the request.
This link covers one solution http://tpeczek.com/2010/05/using-antiforgerytoken-with-other-verbs.html
However the most ideal solution is that when you use the actionlink it adds the Anti Forgery token into the query string so I'm going to try writing my own ActionLink extension method that appends that on.
Finally I'm going to write an attribute that inherits from the ValidateAntiForgeryTokenAttribute and that accepts forgery tokens in both the Request.Form and Request.QueryString
Related
Checkmarx is complaining about an XSRF issue in our web application. We are using ASP.NET web forms with framework 4.0 (not MVC)
Checkmarx said: Method btnSubmit_Click at line 1760 of \ABC.aspx.vb gets a parameter from a user request URL from element text. This parameter value flows through the code and is eventually used to modify database contents. The application does not require renewed user authentication for the request. This may enable Cross-Site Request Forgery (XSRF).
Any idea of how to prevent XSRF from ASP.NET Webform application?
We have tried a lot of solutions but none of them pass Checkmarx:
Here are some things we tried:
https://software-security.sans.org/developer-how-to/developer-guide-csrf
or
http://willseitz-code.blogspot.com/2013/06/cross-site-request-forgery-for-web-forms.html?m=1
or
https://security.stackexchange.com/questions/187740/two-solutions-for-csrf-on-owasp-for-asp-net-webforms
I think the solutions above should work and protect/prevent our web form from CSRF/XSRF risks, but why can Checkmarx not detect it? Is this a false positive?
It is recommend to check the CxQL queries from Checkmarx Portal (Settings/Scan Settings/Query Viewer) to understand how Checkmarx find a vulnerability, including what kind of protection that Checkmarx is able to detect.
For your case, check the logic in CSharp/Cx/CSharp_Medium_Threat/XSRF.
For Web Form Applications, the query CSharp/Cx/General/Find_XSRF_Sanitize is used to find if you have done any protection in your application.
As the comment of Find_XSRF_Sanitize said:
For ASP Web Forms, the main solution to prevent XSRF attacks is to
assign a unique token to the ViewStateUserKey property of the page.
Also
AntiXsrfTokenKey
is also considered a protection.
If you use ViewStateUserKey or AntiXsrfTokenKey, all the http interactive requests that are defined in the same method as the ViewStateUserKey or AntiXsrfTokenKey will be considered as sanitized request, and will be removed for the potential tainted request list.
Note that in the CxDOM tree, ViewStateUserKey and the sanitized request have common ancestor, which is the method declaration.
No duplicate of “Server.Transfer from ASP to ASP.Net” ;-)
On an IIS web server (running Classic ASP), I have a local URL that a user is remotely redirected to. Presumably, this call is made with data in the query string or transmitted through POST data. When this request is made, I need to remove this data (especially the query string) server-side, so none will be visible to the client.
For example, the user is led to http://example.com/dir/?data=payload. This is what requested, and this is what the user’s browser will display. Now I need the request resource to strip QueryString and Form data, so that the user ends up in e.g. http://example.com/dir/.
On MSDN, they have HttpServerUtility.Transfer, which adds a boolean to the classic Server.Transfer method allowing to preserve or clear data. However, when I try this in an aspx file transfering to an asp file, I get a 0x80004005 HTTP exception (“No http handler was found for request type 'GET'”).
Is it possible at all to “redirect” from an ASP.NET file to a Classic one?
Is there another, better way to remove request data server-side?
My options would be:
Use a redirect on the page without querystrings: Response.Redirect() This will clear post data as well.
Do a HTTP Request to scrape the HTML of the other page, and view it in your current page.
I would probably do option #1
I have a web application where I have used http-handlers and jQuery for AJAX call.
Now the problem is user can type the same URL in the browser which is generated by the jQuery and operation is being performed.
Can I send some token with the query string and then on server side I can look for the right token before performing any operation.
Hope that I have written my problem correctly.
You may need to handle this in a similar fashion to how it can be handled in the MVC framework. Here is a similar post that describes a potential solution.
The above technique is called
Cross Site Request Forgery
Risk Impact
An attacker can hijack logged in users session for performing malicious transactions.
Recommendations
It is recommended implementing Page token (a random token as an additional parameter in the request) for all transaction pages. This token should be randomly generated and should be unique for each user.
The suggested URL are
http://www.owasp.org/index.php/CSRF_Guard
http://www.cgisecurity.com/csrf-faq.html
var cg = new CSRFGuard();
cg.SetupCSRFTokenNameAndValue();
SessionManager.CustomerConfig.CsrfTokenName = cg.CsrfTokenName;
SessionManager.CustomerConfig.CsrfTokenValue = cg.CsrfTokenValue;
Thanks a lot.
I have some functionality in the code behind, which after executing needs to forward the request to another page. I want to pass along data like you would by setting a request attribute in Java (i.e. - I don't want it in the query string of the redirected response). Is this possible with ASP.NET (c#)?
You can use Server.Transfer if you want to forward the request and keep all of the Request variables, or you can use Session.
Are you using ASP.NET Webforms or MVC? The following will redirect your request to a new page. You'll have to test and see if it forwards post data (I'm not sure). Now that you mention it, I don't think ASP.NET has a built in "forward:" request like java does. I think it just has "redirect" for security reasons. (Someone correct me if I'm wrong).
In Webforms:
try Response.Redirect("mynewpage").
In MVC:
at the completion of your action method return Redirect("mynewpage")
I don't know your use case, but it is generally not good practice to pass post data to a different page/request. Typically the posted action will take care of persistence, and then a GET request will be issued to the redirect page. If the redirected view needs access to the posted data, it should go to the persistence mechanism (DB) to retrieve it. This method is more secure, and generally better practice. This is a very general guideline, so use it as your needs allow.
HTH
Yes - See the reflection code at:
HttpModule to add headers to request
However - the question is - do you really want to use request headers? probably not. its a hack to use them. If you simply want to pass information, use the Context.Items dictionary to transfer your items between requests with Server.Transfer.
Depending on what you are doing and where your events are, you can also make use of Cross Page Postback.
See http://msdn.microsoft.com/en-us/library/ms178139.aspx
Otherwise, I'd go with vcsjones answer of Server.Transfer
I'm trying to 'AJAX-ify' my site in order to improve the UI experience. In terms of performance, I'm also trying to get rid of the UpdatePanel. I've come across a great article over at Encosia showing a way of posting using PageMethods. My question is, how secure are page methods in a production environment? Being public, can anyone create a JSON script to POST directly to the server, or are there cross-domain checks taking place? My PageMethods would also write the data into the database (after filtering).
I'm using Forms Authentication in my pages and, on page load, it redirects unauthenticated users to the login page. Would the Page Methods on this page also need to check authentication if the user POSTs directly to the method, or is that authentication inherited for the entire page? (Essentially, does the entire page cycle occur even if a user has managed to post only to the PageMethod)?
Thanks
PageMethods are as secure as the handler in which they reside.
FormsAuthentication will protect everything except the Login page.
On an unprotected handler, like login, you should expose only methods that 1) are not sensitive or 2) validate the user.
EDIT: in response to comments and other answers regarding CSRF and XSS please see http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx
You're trying to protect against CSRF attacks.
These attacks can be prevented by requiring an authorization code in the POST parameters, and supplying the auth code in the initial page load. (The auth code should be per-IP address and per-user, and should expire quickly)
For added security, you can make each auth-code only usable once, and have each request return a new auth-code. (However, if any request fails, you'll need to reload the page)
I am working on a project that heavily utilizes ASP.Net WebForms Page Methods which I talk to using Ajax. This is rather very convenient for me than writing all my codes in JavaScript.
However, Securing the page methods became an issue which troubled me. I see that I can access the page methods via Postman and Fiddler hence, enabling hackers to play with your APIs.
My solution was quite simple which I discovered accidentally. Adding a static Cookie request to the page method would return error for any app that is NOT the website.
[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public static string GetAnything(object dat)
{
HttpCookie myguid = HttpContext.Current.Request.Cookies.Get(Constants.Session.PreventHacking);
var hackguid = myguid.Value ?? ""; //other page method contents
return "anything";
}
A postman request to this method would return :
{
"Message": "There was an error processing the request.",
"StackTrace": "",
"ExceptionType": ""}
While a more detailed error would show if on LocalHost.
I understand there are browser ad-ons that can intercept API calls by sitting just beside the website. I have not tested this. A separate security fix has to be built for this however.
I'll update here once I perform some tests.
Think of Pagemethods like a mini webservie local to the page. The fact is they will have no extra checks and verifications in place except those that are placed on the entire website, and those that you choose to put in.
Using Pagemethods is a smart idea from the point of view of 'Encapsulation', and if you're going to use them it doesn't hurt trying to put in some extra security measures in place.