Consider a web application that consists of only HTML and JS for Front end and that communicates with a Web API.
I am trying to protect my application against CSRF attacks and for that I have took reference of this article.
Using the methods in this article, I am able to generate Anti CSRF tokens and pass it to the client. However it depends on first AJAX call that must happen before making regular CRUD operation calls.
With this approach, I need some clarity on few things as well as some alternatives if any. Consider a client visits this web application (which is protected by AJAX based Anti CSRF token), and keeping his session open, he visits a malicious website that contains page that makes the same AJAX calls to get CSRF tokens (assume that attacker is aware of this process), I suppose he can use the headers to make unintended calls thus resulting in an attack.
So how can I protect my application against these?
Please provide more detail regarding this, or if its misleading then help me by providing correct details so that I can tackle it better.
First of all you should use an encrypted communication with the server so the attacker won't be able to read any header data.
If your attacker uses the same calls as you do, he is not be able to guess the anti XSRF token that you use in your calls. A new token is generated for every call to your API. I hope this page helps you with some details:
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
I think if we use token based authentication, client have to pass authentication token in each request. And if client do not store it in browser cache and store it in localStorage then browser will not send token in call automatically. And if our service receive any request without auth token then it will discard the request.
Related
I have a client-side application on domain client-domain.example and a server-side application on domain server-domain.example. There is an API on the server-side. The client-side application sends AJAX requests to the server-side application. I use token-based authentication, so the client-side application sends token in headers with each AJAX request, for example: "Authorization: Bearer {some token}". It works fine with AJAX requests, when I need to get or post some data.
But the server-side API also keeps files. For example images. The files are private, only authenticated users can get them. And I need to show this images on the client-side in <img> tag. I can't get them using <img src="http://server-domain.example/path/to/image"> because in this case browser will not send Authorization header to the server-side.
What is the adopted solution? How client applications load images from server-side API?
There are three methods to solve it, the best approach to solve it is using the signed URLs
1. signed URL (can be insecure)
The first method simply creates a route without authentication (anonymous access) with a signature hash parameter that indicates if the resource can be loaded or not.
<img src="http://server-domain.example/path/to/image?guid=f6fc84c9f21c24907d6bee6eec38cabab5fa9a7be8c4a7827fe9e56f2">
When the server receives the request it must validate the guid if the expiration time has not been reached and, of course, check if the guid has a valid signature.
This approach is used by several files/documents servers like Dropbox, S3, CDN providers, etc.
See the technique in some companies.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html#private-content-overview-choosing-duration
https://client.cdn77.example/support/knowledgebase/cdn-resource/how-do-i-set-up-signed-urls
SECURITY:
the guid can not be just UUID of the image/user, because this doesn't provide any protection.
the guid can not be the same token you use for authentication (for example, you can't use auth-JWT tokens), because the user can share the link - and the user will share his tokens (see also (2)).
as mentioned above: guid should have a server-side mechanism of validation (date/signature/...) and should not provide more permissions than "access to the requested file"
2 Query String with JWT (most probably a security breach)
The second method is to pass the token by querystring with the image URL.
This method is not recommendable because it exposes clearly the URL and many servers sometimes write and expose public logs of URL accessed. The bad notice is that the JWT exposed normally the user can get control a lot of features further the image load.
<img src="http://server-domain.example/path/to/image?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c">
When the server receives the request you must validate the token by querystring and response with the content.
SECURITY NOTES: worse than (1) - because now authentication info (JWT auth) is exposed in the URL and can be cached/logged by servers OR accessed by any server in the middle OR the user can simply share the "image link" with their colleagues.
But if JWT is NOT an access token, but a one-time token generated specifically for accessing that particular file in a form of JWT then it provides the same level of security as (1).
3. cookies
The third method creates an authenticated cookie to validate the access of the image.
This method is not recommendable because is out of API pattern (webapi/token based authentication in general).
When the server receives the request you need to validate if the validate cookie is valid.
SECURITY NOTES: if you can provide security for your cookies and XSS and CSRF — are not just letters for you then it is a solution. But keep in mind: cookies are sent by the browser automatically with each request. Much more information about possible threats and solutions: Where to store JWT in browser? How to protect against CSRF?
My solution to basically this exact same problem, based on Jeferson Tenorio's answer below (option 1), was to sign the URL to my API call with an encryption of the image and the user's JWT token, e.g. path/to/image?token=xxxx. In laravel this is easily accomplished with encrypt($your_object) and decrypt($token) (https://laravel.com/docs/5.7/encryption), and then I used the extracted token to verify the user had access to the file in question. But there are probably many other libraries capable of handling this.
I would be curious if there are any security concerns, but from my perspective the JWT is never exposed via plain text and the encryption relies on a secret key that malicious actors shouldn't have access to, so it seems like it should be fairly secure. My only real complaint is that the token is quite long using this method which does not make for presentable URLs.
Greetings SO Community!
I'm trying to think through a security issue with an ajax process in a highly cached environment, and could use some advice. My situation is this:
The users of the site are not logged in.
The site pages are highly cached (via akamai).
I have a service API that is to be accessed via AJAX from pages within my domain.
I need to protect that API from being used outside of my domain.
I can check the incoming "host" in the headers to see if the ajax request came from my domain, but that seems insecure, as such headers could be spoofed. Also, it seems to me that the usual token passing scheme will not work for me because my pages are cached, so I don't have the opportunity to inject tokens unique to the user/request (e.g. as described here: How can I restrict access to some PHP pages only from pages within my website?). Clearly, it's insecure to make a token request via ajax after page load, so I'm not sure how to make this happen. I suppose I could generate a shared use token that loads with the page and has a lifetime twice that of my maximum page cache life, but it seems like there must be a better way!
What are you trying to accomplish? Are you trying to prevent cross site request forgery or someone\something from using your API that is not the javascript you served to the user?
The former is accomplished via tokens that are stored in the source of the page. You can make it hard to conduct an XSRF attack by having tokens in the source ( or some code that creates tokens). Unfortunately, unless you can get unique data per user/request into the source, someone can always just grab your source and reverse engineer the token. Then they can forge requests. The general rule is don't worry about it unless the user is loged in because the attacker could just go to the page themselves.
The later(preventing unauthorized use) is impossible in anycase. An attacker can always make an account, strip the tokens/keys/credentials she needs, and then use some API on their server.
My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app? Like, say I have an option for the user to deactivate the account, which can be done by clicking a button. This is done via Ajax.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
HELP!!!
My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app?
From a security perspective, there is no difference between an HTTP request that involves JavaScript and one which doesn't (e.g. that uses a regular form, or is handcrafted).
… but you can't call methods from the client, you can only make requests to URIs. The server might cause a method to be called based on receiving a request to a specific URI.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
They could, which is why you need (trustworthy) authentication / authorisation and CSRF protection (just like you would for a request to disable an account that didn't involve Ajax).
This is not a problem with AJAX alone, but with any arbitrary HTTP request that wants to authenticate/maintain a session. The user needs to be authenticated in some way in order to make requests, this is usually done with cookies. Using AJAX does not make the matter any worse though because it is still a HTTP request.
Authentication alone is not enough though, someone could always be listening on the wire and capture the authentication cookie, and thus get hold of the session - "become you". The only solution here is to encrypt the connection on a lower OSI layer level (using SSL/TLS). This is why you should always use SSL when it comes to authentication.
This Ruby on Rails security guide has a great explanation on how to deal with AJAX requests that could be potentially exploited. It's not specific to RoR so the concepts can apply to any platform.
One way to reduce the risk of cross site requests is to use POST for actions that modify or delete data.
I'm trying to protect an application (php and lots of JS) from CSRF.
I want to use tokens.
A lot of operations are done with AJAX, so I have to pass the token in Javascript.
If I want to generate 1 token per session or per page load it's simple - I generate new token, put it somewhere in a DOM and then find it with Javascript and send to the processing side.
But what if I want to use new token for every operation?
I was thinking about doing an ajax call to regenerate token and then pass the result to processing page.
Does this increase security risk?
I was thinking about luring user to page with script which would ask for token and then use it to make the request but then again cross domain Javascript is forbidden.
Can it be done with flash?
Maybe another approach for protecting ajax calls from CSRF?
Thanks!
There are several techniques, which when used together provide a sufficient CSRF protection.
Unique Token
A single, session-specific token is good enough for most applications. Just make sure that your site doesn't have any XSS vulnerabilities, otherwise any kind of token technique you employ is a waste.
AJAX call to regenerate the token is a bad idea. Who will guard the guards? If the AJAX call itself is vulnerable to CSRF, it kind of defeats the purpose. Multiple tokens with AJAX are in general bad idea. It forces you to serialize your requests i.e. only one AJAX request is allowed at a time. If you are willing to live with that limitation, you can perhaps piggyback token for the second AJAX call in response to the first request.
Personally, I think it is better to re-authenticate the user for critical transactions, and protect the remaining transactions with the session-specific token.
Custom HTTP header
You can add a custom HTTP header to each of your requests, and check its presence on the server side. The actual key/value doesn't need to be secret, the server just needs to ensure it exists in the incoming request.
This approach is good enough to protect CSRF in newer versions of the browsers, however its possible too work-around this if your user has older version for Flash Player.
Checking Referrer
Checking for the Referrer header is also good to protect CSRF in the newer browsers. Its not possible to spoof this header, though it was possible in older versions of Flash. So, while it is not foolproof, it still adds some protection.
Solving Captcha
Forcing the user to solve a captcha is also effective against CSRF. Its inconvenient as hell, but pretty effective. This is perhaps the only CSRF protection that works even if you have XSS vulnerabilities.
Summary
Use a session based token, but re-authenticate for high value transactions
Add a custom http header, and also check for referrer. Both are not foolproof by themselves, but don't hurt
We're currently developing an entirely AJAX based app that will interact with the server via a RESTful API. I've considered potential schemes to protect against XSRF attacks against the API.
User authenticates and receives a
session cookie, which is also
double-submitted with each request.
We implement an OAuth consumer in
Javascript, retrieve a token when
the user logs in, and sign all
requests with that token.
I'm leaning toward the OAuth approach, mainly because I'd like to provide 3rd party access to our API and I'd rather not have to implement two authentication schemes.
Is there any reason why an OAuth consumer would not work in this situation?
Most AJAX libraries will set an additional header "X-Requested-With: XMLHttpRequest", which is difficult to fake in a basic XSRF attack (though possible if combined with XSS). Verifying that this header exists is a good defense-in-depth strategy if you expect all your requests to be AJAX.
Use a two-step request, the first asking for the server an unpredictible token, the second asking for the real action with the token.
As the attacker can't predict the token, and can't read it (same origin policy) he can't give a valid token in the second query.
But be careful to not leak tokens (learn about capturing json using when they affect value to a global variable and so on) and read :
http://www.google.com/search?q=xsrf+defence
The easiest way to prevent XSRF it to check the referer of every RESTful request to make sure the request is coming from the same domain. The session cookie is important for keeping state, but it will not defend against XSRF becuase it will also be sent with a forged request. Its common to see referer based XSRF protection system on embedded network hardware with limited memory requirements, Motorola uses this method on most of their hardware. This isn't the most secure XSRF protection, token based protection is better but both systems can still be bypassed with XSS. The biggest problem with token based XSRF protection is that it takes alot of time to go back and fix every request and you will probably miss a few requests.
Make sure to read up on the same origin policy and to scan your site for xss. You should also read the OWASP Top 10 for 2010 A3-Broken Authentication and Session Management.