I'm trying to send a post request to a different site, specifically Zoho.eu, to enable me to login with one click. Effectively I want to POST to the login URL, my username, password etc etc.
I have ran into the Cross origin problem and I have looked at many different solutions such as JSONP, the iFrame method, CORS etc but all of these require me to have access to the third party backend which I don't have.
How do I get around this problem? I understand I can use a proxy somehow to enable me to avoid the cross origin problem but I'm not sure?
Thanks in advance.
If I understand you correctly then the short answer is you can't.
A proxy won't help you to create a session in the user's browser and login. When using a proxy you are doing the requests in behalf of the user from your server, and can't set the required session values to the user's cookies for the target domain.
This is intentional. The whole concept of Same-origin policy/CORS was invented so that others will not be able to do something in behalf of a users in a domain they don't own.
I would consider OAuth, it might be the right way for you to implement this kind of cross-domain login flow.
One easy solution (which is only a temporary fix, you will have to find a more permanent solution for production code) is to hard code the name of the server from where the request is coming in your server controller code and allow access from it.
CORS protection is intented.
Zoho provides cleaner way to authentication to their site with OAuth integration. That is cleaner way to integrate.
Documented clearly here on the steps,
https://www.zoho.com/crm/help/api/using-authentication-token.html
Any other mode of authentication is not allowed and may be blocked by Zoho.
Hope it helps.
Related
I want to create an API at www.MyDomain.com that is accessible from public websites www.Customer1.com and www.Customer2.com. These public websites display each customers inventory and do not have any login features. They will use AJAX calls to read data from my API.
How can I secure the API so that it can be accessed via AJAX from different domains but no one can access the API to be able to scrape all of my customers data and all of their inventory?
I have tried thinking of different solutions on my own but they would all either require people to login to the public websites (which isn't an option) or it would require some secret "key" to be displayed publicly in the browser source code which could then be easily stolen.
Any ideas would be greatly appreciated.
Thanks!
P.S. Are their any obstacles that I am going to run into using Javascript & CORS that I need to look into now?
Anything that is accessible without authentication from a browser is by definition insecure, so you can't stop that. Your best bet is to have to have a relationship with the owner of customer1.com and customer2.com - the server apps for those two websites would make an HTTP call to you and authenticate with your service. Going this way also avoids the CORS issues you're talking about.
If you've already designed the client functionality, you can still probably do it without much change to the javascript - have it point to customer1.com for its AJAX call instead of your API, and customer1.com would accept this request and just act as a proxy to your API. Aside from the authentication, the rest of the request and response could just be pass-throughs to your API.
You can use Microsoft.AspNet.WebApi.Cors.
It's just need add ONE line at webapi config to use CORS in ASP.NET WEB API:
config.EnableCors("*","*","*");
View this for detail.
The simplest way to provide a minimum security here is to provide some kind of token system. Each app has its own token, or combination of tokens which it must pass to the server to be verified. How you generate this tokens is up to you and other than being linked to app's access, doesn't have to mean anything.
Provide a way for each API implementer to open an account with you. This way you will know who is accessing what and in some cases you can block/stop service.
For instance, a token can just be an MD5 hash:
7f138a09169b250e9dcb378140907378
In the database, this hash is linked to their account. On each request, they send this token with what they want. It is verified first to be valid, then the request is fore filled. If the token is invalid, then you can decide how to deal with it. Either don't return anything or return an "access denied" (or anything you want).
One thing to avoid is having a single token for everyone, though this can be a starting point. The reason for this is if some unauthorized app gets a hold of this token and exploits it, you have to change the token for everyone, not just the app that somehow leaked the token. You also can't control if someone has access to something or not.
Since you listed ASP.NET, I can also point you to WCF, which is fairly complex but has all the tools that you need to setup a comprehensive web service to service both you and your clients.
I hope this gives you a starting point!
EDIT:
There are security concerns here in the case that someone leaks their token key somehow. Make sure that you setup a way in which the app/your service do not expose the the token in anyway. Also have a flexible way of blocking a token, both by your clients in you, if it so happens that a token is exploited.
Given the simplicity of writing a server side proxy that fetches data across domains, I'm at a loss as to what the initial intention was in preventing client side AJAX from making calls across domains. I'm not asking for speculation, I'm looking for documentation from the language designers (or people close to them) for what they thought they were doing, other than simply creating a mild inconvenience for developers.
TIA
It's to prevent that a browser acts as a reverse proxy. Suppose you are browsing http://www.evil.com from a PC at your office, and suppose that in that office exists an intranet with sensitive information at http://intranet.company.com which is only accessible from the local network.
If the cross domain policy wouldn't exists, www.evil.com could made ajax requests to http://intranet.company.com, using your browser as a reverse proxy, and send that information to www.evil.com with another Ajax request.
This one of the reasons of the restriction I guess.
If you're the author for myblog.com and you make an XHR to facebook.com, should the request send your facebook cookie credentials? No, that would mean that you could request users' private facebook information from your blog.
If you create a proxy service to do it, your proxy can't access the facebook cookies.
You may also be questioning why JSONP is OK. The reason is that you're loading a script you didn't write, so unless facebook's script decides to send you the information from their JS code, you won't have access to it
The most important reason for this limit is a security concern: should JSON request make browser serve and accept cookies or security credentials with request to another domain? It is not a concern with server-side proxy, because it don't have direct access to client environment. There was a proposal for safe sanitized JSON-specific request methods, but it wasn't implemented anywhere yet.
The difference between direct access and a proxy are cookies and other security relevant identification/verification information which are absolutely restricted to one origin.
With those, your browser can access sensitive data. Your proxy won't, as it does not know the user's login data.
Therefore, the proxy is only applicable to public data; as is CORS.
I know you are asking for experts' answers, I'm just a neophyte, and this is my opinion to why the server side proxy is not a proper final solution:
Building a server side proxy is not as easy as not build it at all.
Not always is possible like in a Third Party JS widget. You are not gonna ask all your publisher to declare a DNS register for integrate your widget. And modify the document.domain of his pages with the colateral issues.
As I read in the book Third Party Javascript "it requires loading an intermediary tunnel file before it can make cross-domain requests". At least you put JSONP in the game with more tricky juggling.
Not supported by IE8, also from the above book: "IE8 has a rather odd bug that prevents a top-level domain from communicating with its subdomain even when they both opt into a common domain namespace".
There are several security matters as people have explained in other answers, even more than them, you can check the chapter 4.3.2 Message exchange using subdomain proxies of the above book.
And the most important for me:
It is a hack.. like the JSONP solution, it's time for an standard, reliable, secure, clean and confortable solution.
But, after re-read your question, I think I still didn't answer it, so Why this AJAX security?, again I think, the answer is:
Because you don't want any web page you visit to be able to make calls from your desktop to any computer or server into your office's intranet
I'm working on a JavaScript library and I would like anybody using it can make request to my server.
Because this I have added the access-control-allow-origin,method headers to my server responses.
Thigs works fine but my is question is: Is that secure for my server? there is any other implication I can take into account?
Thanks a lot.
It's as secure as the code on your server is. If you allow people to send an AJAX request that can drop a table, then no it's not secure. But if you follow best practices for website/scripting security it should be as safe as handling any other request your server normally would.
Can anonymous users make changes to your server (e.g. incrementing a vote counter, post a comment, delete a post, etc)? If so, does it matter if a website you don't control makes some or all of their users make use of this feature of your site? Do the access control headers allow remote XHR to make those requests? If so, you have a problem.
Can known users make changes to your server? If so, does it matter if a website you don't control makes some or all of their users who are also your users make use of this feature of your site? Do the access control headers allow remote XHR to make those requests? Do the access control headers allow authentication methods (such as cookies) through? If so, you have a problem.
In short:
Can a user do something potentially undesirable on your site?
Do your access-control headers prevent third party websites from making users do those undesirable things?
I have a piece of javascript executing on a jetty server which is sending a XMLHTTPRequest to a scoket on another server(wamp server).
The request gets sent to the socket, however the XHR response seems to be getting blocked.
My only thoughts on this is it may be an issue with XSS(cross site scripting).
Is there a way in which i could enable cross site scripting for this particular request or is there something else i should be doing?
Any help would be greatly appreciated!
That sounds about right. Browser cross-domain policy blocks XHR requests to other domains. Try using the JSONP technique in order to circumvent this.
It may seem odd that cross-domain policy can be so easily circumvented, but that's because when a server exposes a JSONP interface, it is clearly a mutual agreement.
Good luck!
Take a look here, this lets you expose an ajax endpoint across the domain boundary without the use of JSONP - its plain XHR with a little bit of cross domain messaging on top.
For the exact example of cross domain ajax, see this http://consumer.easyxdm.net/current/example/xhr.html
By the way, this is what the Russian version of Facebook (vkontakte, 75+mill users) uses for its API.
You cannot make xmlhttprequests to other servers. You have 2 options
proxy everthing through the server that servs the javascript.
use a <script> tag to pull data off the otherserver using dynamically generated js on that server.
Thanks guys for your response but I actually found that the issue was with same origin policy as I am running both servers from the same host but with different port numbers.
JSONP seems like it may solve the problem, but I am going to try just use the one server now for completeness.
The following article explains my problem under the background heading.
and in column four of the table.
http://taossa.com/index.php/2007/02/08/same-origin-policy/
I was reading about CORS and I think the implementation is both simple and effective.
However, unless I'm missing something, I think there's a big part missing from the spec. As I understand, it's the foreign site that decides, based on the origin of the request (and optionally including credentials), whether to allow access to its resources. This is fine.
But what if malicious code on the page wants to POST a user's sensitive information to a foreign site? The foreign site is obviously going to authenticate the request. Hence, again if I'm not missing something, CORS actually makes it easier to steal sensitive information.
I think it would have made much more sense if the original site could also supply an immutable list of servers its page is allowed to access.
So the expanded sequence would be:
Supply a page with list of acceptable CORS servers (abc.com, xyz.com, etc)
Page wants to make an XHR request to abc.com - the browser allows this because it's in the allowed list and authentication proceeds as normal
Page wants to make an XHR request to malicious.com - request rejected locally (ie by the browser) because the server is not in the list.
I know that malicious code could still use JSONP to do its dirty work, but I would have thought that a complete implementation of CORS would imply the closing of the script tag multi-site loophole.
I also checked out the official CORS spec (http://www.w3.org/TR/cors) and could not find any mention of this issue.
But what if malicious code on the page wants to POST a user's sensitive information to a foreign site?
What about it? You can already do that without CORS. Even back as far as Netscape 2, you have always been able to transfer information to any third-party site through simple GET and POST requests caused by interfaces as simple as form.submit(), new Image or setting window.location.
If malicious code has access to sensitive information, you have already totally lost.
3) Page wants to make an XHR request to malicious.com - request rejected locally
Why would a page try to make an XHR request to a site it has not already whitelisted?
If you are trying to protect against the actions of malicious script injected due to XSS vulnerabilities, you are attempting to fix the symptom, not the cause.
Your worries are completely valid.
However, more worrisome is the fact that there doesn't need to be any malicious code present for this to be taken advantage of. There are a number of DOM-based cross-site scripting vulnerabilities that allow attackers to take advantage of the issue you described and insert malicious JavaScript into vulnerable webpages. The issue is more than just where data can be sent, but where data can be received from.
I talk about this in more detail here:
http://isisblogs.poly.edu/2011/06/22/cross-origin-resource-inclusion/
http://files.meetup.com/2461862/Cross-Origin%20Resource%20Inclusion%20-%20Revision%203.pdf
It seems to me that CORS is purely expanding what is possible, and trying to do it securely. I think this is clearly a conservative move. Making a stricter cross domain policy on other tags (script/image) while being more secure, would break a lot of existing code, and make it much more difficult to adopt the new technology. Hopefully, something will be done to close that security hole, but I think they need to make sure its an easy transition first.
I also checked out the official CORS spec and could not find any mention of this issue.
Right. The CORS specification is solving a completely different problem. You're mistaken that it makes the problem worse - it makes the problem neither better nor worse, because once a malicious script is running on your page it can already send the data anywhere.
The good news, though, is that there is a widely-implemented specification that addresses this problem: the Content-Security-Policy. It allows you to instruct the browser to place limits on what your page can do.
For example, you can tell the browser not to execute any inline scripts, which will immediately defeat many XSS attacks. Or—as you've requested here—you can explicitly tell the browser which domains the page is allowed to contact.
The problem isn't that a site can access another sites resources that it already had access to. The problem is one of domain -- If I'm using a browser at my company, and an ajax script maliciously decides to try out 10.0.0.1 (potentially my gateway), it may have access simply because the request is now coming from my computer (perhaps 10.0.0.2).
So the solution -- CORS. I'm not saying its the best, but is solves this issue.
1) If the gateway can't return back the 'bobthehacker.com' accepted origin header, the request is rejected by the browser. This handles old or unprepared servers.
2) If the gateway only allows items from the myinternaldomain.com domain, it will reject an ORIGIN of 'bobthehacker.com'. In the SIMPLE CORS case, it will actually still return the results. By default; you can configure the server to not even do that. Then the results are discarded without being loaded by the browser.
3) Finally, even if it would accept certain domains, you have some control over the headers that are accepted and rejected to make the request from those sites conform to a certain shape.
Note -- the ORIGIN and OPTIONS headers are controlled by the requester -- obviously someone creating their own HTTP request can put whatever they want in there. However a modern CORS compliant browser WONT do that. It is the Browser that controls the interaction. The browser is preventing bobthehacker.com from accessing the gateway. That is the part you are missing.
I share David's concerns.
Security must be built layer by layer and a white list served by the origin server seems to be a good approach.
Plus, this white list can be used to close existing loopholes (forms, script tag, etc...), it's safe to assume that a server serving the white list is designed to avoid back compatibility issues.