How can we prevent cross-site request forgery (CSRF) attacks in ASP.Net webForm. i want to secure some of pages in website and also how can we prevent if we received URL in the Email, from the attacker to perform CSRF.
You can take some extra precautions.
First connect your user authentication and actions, with the IP and the browser information's. So on each action, also verify that the actions are done from the user that have all that criteria.
encrypt some critical data/variables (that CSRF have to change) - and not let the variables only pass from SSL but plain text -
always use encrypted SSL cookies. requireSSL=true.
Do not allow cross app redirects enableCrossAppRedirects=false
Use one database table, to connect each authentication cookie with user actions like the log-out, so you know that the cookie is (maybe ?) logged out, or inactive, or something - even if its valid.
Block in advanced blocked ips that they have found that attacks.
http://www.phoenixlabs.org/pg2/
Related
I have ASP.NET MVC app that uses Forms Authentication. After user is authenticated, in response he will receive forms cookie that contains auth information. Now regarding the forms cookie: It is encrypted by a machine key and it is protected from tampering by signature. I also use HTTPS... However, what if somehow I get the cookie and try to make request from another client (meaning that the request will be made from another IP address)?
It seems to me that this scenario will work. Are there any ways to defend from this kind of attack?
If you are using HTTPS everywhere on your site and set requireSSL="true" on your system.web/authentication/forms element in web.config, you are instructing the browser to only pass that cookie back over an HTTPS connection. This will protect against the vast majority of traffic sniffing-based session hijacking attacks and you should definitely use it if your site is HTTPS only.
Forms Authentication is inherently stateless. The server is encrypting the following information and storing it client-side: CookiePath, Expiration, Expired, IsPersistent, IssueDate, Name, UserData, Version. Assuming your machineKey hasn't been compromised, the client will just see this as a blob of encrypted data. When it presents that blob to the server again, the server decrypts it and converts it back into a FormsAuthenticationTicket, validates the fields in the ticket against config, verifies that the ticket isn't expired, etc. and decides whether to treat the request as authenticated. It doesn't 'remember' anything about which tickets are outstanding. Also note that it doesn't include the IP address anywhere.
The only real attack vector I can think of if you are HTTPS-only, take care to protect your machineKey, and set the forms auth cookie to requireSSL would be for an attacker to target the client's browser and/or computer. Theoretically they could steal the cookie from memory or disk out of the browser's space. It might be possible for a virus/trojan to do this or even a malicious browser extension. In short, if a user could get their hands on a valid, non-expired Forms Auth cookie, they could present it from any machine they wanted to until it expired. You can reduce the risk here by not allowing persistent auth cookies and keeping your timeouts to a minimum.
If they had the machineKey, they could create FormsAuth cookies from scratch whenever they wanted to.
Oh.. Can't forget Heartbleed. If you had a load balancer or reverse proxy that was using an insecure version of OpenSSL, it's possible an attacker could compromise your private key and intercept traffic over HTTPS connections. ASP.NET doesn't use OpenSSL, so you're safe from this in a pure-MS stack. If you ever hear anything about a vulnerability in MS' SSL implementation, you'd want to patch it ASAP and get your passwords changed and certificates re-issued.
If you are concerned about the browser/machine based hijacking, you might want to take a look at a project I started [and abandoned] called Sholo.Web.Security (https://github.com/scottt732/SholoWebSecurity). It's goal was to strengthen Forms Authentication by maintaining state on the server at the expense of some overhead on each request. You get the ability to do things like revoke tickets server-side (kick/logout a user) and prevent users from moving tickets between IP addresses. It can get annoying in the traveling mobile user scenario that Wiktor describes (it's optional). Feel free to fork it or submit pull requests.
The Anti-CSRF features that 0leg refers to apply to the UI/form mechanism that initiates the login process, but to my knowledge there is nothing in the Forms Authentication process itself that relates to CSRF. That is, once the cookie is issued to the client, the only thing protecting it from being bounced between servers is the fact that cookies are restricted to the domains/subdomain they were issued for. Your stackoverflow.com cookies won't be presented to serverfault.com. The browser takes care of that stuff for you.
Are there any ways to defend from that kind of attacks?
You shouldn't. Years ago we have had implemented such feature and abandoned it soon. It turned out that:
a single user making requests from the very same browser/machine but switching between http/https can sometimes be seen from different IP adresses
a single user traveling and using her mobile phone sometimes makes consecutive requests from different IP addresses when her phone switches between BTSes
Just to clarify the terminology, session hijacking is usually referred to the vulnerability where an unauthorized user accesses the session state on the server.
Authentication cookies are different from session cookies. ASP.NET puts a great deal more precautions in safeguarding authentication cookies. What you describe is better described by the term CSRF (Cross Site Request Forgery). As #Wiktor indicated in his response, restricting access by IP is not practical. Plus, if you read how CSRF works, the exploit can run in the user browser from the original IP address.
The good news is that ASP.NET MVC has built in support for CSRF prevention that is pretty easy to implement. Read here.
I have a Web API application and have configured SSL for it.
Our authentication mechanism is via the header. Each request will have to contain a pair of keys that we will validate them against our database. We're not using Forms/Basic or Digect authentication.
I'm just wondering do we have to do anything with regard to the Cross-Site Request Forgery (CSRF) issue? is it applicable in this case?
I thought because we're not using the cookies so it should be safe.
Indeed, forcing another user to do a request only has an advantage for an attacker if that user's browser automatically pushes some credential that the attacker does not have. That can be:
auth cookie
HTTP Authentication (Basic/Digest/Windows Auth)
TLS session ID (in HTTPS)
implicit authorisation from IP address or network location (eg intranet site)
If you are not relying on any such credential, then there is no CSRF attack to defend against.
Seeing as using session and cookies are so unsafe, is it possible to securely use just servlet context variables and hiddenform fields, url rewriting to implement same things that session does?
But will it be equally secure and convenient? Why is this method not used?
I am just trying to avoid cookies! Plus, if I save user details in servlet context variables , will it not work same as cookies, but just in server side?
Is that the reason that cookies are ultimately used,That they are client side?
No, Cookies are different from Servlet Context. ServletContext is singleton per application. Not per user.You should avoid using ServletContext for user specific information because you also need to take care of User Lifecycle such as deleting the User info when he is idle.
If you do not want to use Cookie, the alternatives for session tracking are:
URL Rewirting
Hidden Form Fields
But you can make Cookies Secured with the help of following properties:
httponly: On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other, non-HTTP APIs (such as JavaScript).
secured: A secure cookie has the secure attribute enabled and is only used via HTTPS, ensuring that the cookie is always encrypted when transmitting from client to server.
Domain : They tell the browser that cookies should only be sent back to the server for the given domain.
Path: They tell the browser that cookies should only be sent back to the server for the given path.
I'm writing a mostly ajax-driven web application and I'm looking at how to protect the user from CSRF attacks. I'm planning to run the pages of the application where the user is logged in to do his work in HTTPS mode.
Does running the page on HTTPS work to protect against CSRF attacks?
No, running a page on HTTPS does not protect it from CSRF. The fact that the communications between the browser and server is encrypted has no bearing on CSRF.
I suggest reading the OWASP guidance on preventing CSRF.
A general, golden rule woule be:
Never trust that the incoming client request is a legitimate one. Be always suspicious and assume that the request could be maliciously forged.
Few specific rules beyond the mentioned OWASP article:
if your data needs authentication/authorization, avoid generic interfaces on the server, like the CRUD interface. easy to code, difficult to authorize specific requests coming from clients. instead, offer a SOA-style interface with explicit methods dedicated to specific use cases where you will have direct control over requests and their parameters.
http://msdn.microsoft.com/en-us/library/ms954638.aspx
even if the framework provides some control over the request validity (ASP.NET viewstate), check again if the user is authorized to pass the set of incoming parameters.
I'll try to explain:
• HTTPS prevents from someone on the same network to get your Session KEY/ID. Say they got your session identification key/id, then they can fake your IP if needed and send all POST requests they want back to server.
With HTTPS all HTTP body (the whole "HTML") is encrypted. Hence no session key is being guessed.
• What happens in CSRF is that the user is clicks a link, which also creates a request to another server and communicates with it, say using user's session but NOT ON THE SAME NETWORK. Means that it cannot listen to what the server replies back to user. If the attacker knows the replies and can communicate them, voila. No problem. No money's left on the user account. But if the server sends a random token to the IP associated with the session, then the attacker cannot guess it on a different network!
The best possible solution is to include secret tokens - to identify the user - in form submissions to the server. Refer to the following links for more information.
http://en.wikipedia.org/wiki/Cross-site_request_forgery
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html
http://seclab.stanford.edu/websec/csrf/
https doesn't safeguard your app from xss attacks. You need csrf token which should be (1) encrypted (2) expiring after some time (3) CSRF token based on page & time
I intend to use SSL on the login form so that the username and password is encrypted during user login.
But, after the user has been authenticated, if I return to HTTP, the Autentication Cookie will be passed from client to server on each request. How safe is this? Obviously i'll use SSL on pages where the user is entering sensitive information, but for most of the time, for performance reasons, i'll just want them to remain authenticated and use HTTP.
I note that if I set RequiresSSL="True" in my forms authentication section in web.config then the authentication cookie is not passed if I use HTTP so I cannot identify the current user.
I guess my question is:
"Is it bad practice to set RequiresSSL="false" and allow the Authentication cookie to pass over HTTP"?
The forms authentication cookie is encrypted and checksumed with the machine key for your server if you set protection="All", so it's not particularly bad to drop back to HTTP.