The scenario is:
I have a web API, which is being accessed by two clients:
Web App written in Javascript, which is minified
iOS App
SSL is all set up on the server hosting the API, and it works fine. There is no User Auth for the API because it's a sort of location-based searching app.
I want to ensure though that only the web app and the iPhone client are able to actually make requests to the API. For the iPhone client it's easy - a shared secret between the server and the app will do, and it's encrypted with SSL so we're not worried about people spying on it.
But for the web app the same solution won't work. I can't just leave a string in the code, and even if it's encrypted in there that's all somebody would need.
Basically, I'm looking for a good solution to this problem. I just want to make sure it's kept only to clients who are allowed to use it, but I'm not sure how I can without going and implementing OAuth which I think is probably overkill. Any ideas?
Thanks!
Dan
It can't be done. Even with oauth. Even assuming that your iOS app is secure, is wrong: it can be decompiled. Any code that runs on the client, can be tampered with, and can't be trusted to be who he says he is.
Only question is: is the API you provide valuable enough, and how much trouble would someone want to go through to hack it. And how hard do you want to make it for whomever wants to hack it.
The iOS version is indeed way safer than the javascript version. In the webapp you can obfuscate your code to make it harder to hack. You can (if you don't intend to use it on iOS) use java or flash to further hide your signing code (HMAC-sign your requests, don't just send a shared secret with them. You may think SSL is secure, but there is a moment before the url is encrypted....).
The way the "big guys" deal with this is:
Whatever you build, assume that someone will be able to hack it (as in: use your API for some other purpose than you intended).
Think about how bad this really is (note: they wouldn't be able to build a business on it; it would be WAY TOO vulnerable to lawsuits). Is it really the end of the world if a lone wolf uses your API.
If you do care about the lone wolves, make it as hard as possible (but honestly, isn't it cheaper just to loose some money from the lone wolves, than to spend 2 developer-months on it?)
If somehow there is serious interest in hacking into your API, try to come to an understanding with the hackers (e.g. I like the way how Spotify reacted to despotify. Basically they said "hey, if you don't release anything that makes it really easy to steal our music or circumvent our businessmodel, we won't try too hard to block you")
Related
Say I wanted to write a local web server that listened on a random port.
Now I want to write HTML that works in most browsers that can do AJAX calls to it.
Is there any fundamental limitation here?
EDIT: I've confused people - probably because this is almost the first time I've ever posted with the javascript tag and I don't have a feel for how to ask questions.
I recently became aware of node.js - which I didn't learn more than it makes writing stand alone web servers easy to implement.
Then I had the vision of a site sort of like this one (any programming board really) but where code samples could execute on end users local machine. I don't like browser plugins at all though, so I started trying to think of a way to make it happen with minimal knowledge between the web/browser part and the local machine's service (there has to be interaction - i just wanted to think of the minimal amount).
And that is just an example - really I write intranet business apps for a living (in which case defining well known ports is easier so I don't need an answer to this question for that purpose..)
The same origin policy will prevent you from accessing other ports (at least in most browsers), but you I guess you could send JSONP requests to every port on localhost, and then catch the port that gives a valid response.
...If you really wanted to, that is. There is a lot of valid ports, so it could take some time.
Is there a way to 'hide' structure and content of javascript objects?
I have fairly extensive JavaScript objects on my client side holding information about the users UI (and other things). It holds a lot of information about the resources that the user will be operating on. As it is, someone with Firebug can just open the console and see the structure of all that data. I'm not crazy about that for security reasons.
Are there any ways I can protect this data?
Thanks,
No, you cannot protect that data. Anything that can be seen and used by the browser can also be seen and used by a person inspecting what the browser has.
You really need to think about why is this a problem for you? If you're concerned about a man-in-the-middle snoop who might intercept that data, then you should run your connections over https.
If you're concerned about the end-user themselves seeing this data, I'd ask why are you concerned about that? It's the user's own state. There should be no secrets in there.
If you're concerned that the user might manipulate things to do things on your server that they shouldn't be allowed to do, then you need to implement protection on your server for things the user shouldn't be allowed to do. Clients cannot implement such protection because clients are, by definition, not secure in this regard.
If there is actually secure data on the client that the end-user themselves shouldn't have access to, then you need to rethink how your app works and keep that data only on the server. The client should only have data that is absolutely required to be on the client. It's possible to implement a UI with very little actual data in the client except specific fields that are being edited if you generate most of the UI server-side.
So ... in summary. Don't put data in the client that the end-user shouldn't have access to. Rethink how your app works if that's a problem. If the end-user can have access to it, then don't work. If nobody else should have access to it, then run your pages over https.
As for obfuscation, it's barely worth any effort. Obfuscation does not provide any true security as it can always be defeated. At best, it provides a level of annoyance to someone trying to look at your code. A determined hacker will be able to get through the obfuscation by just spending a little more time on it and running it through some tools. Certainly there is no harm in minifying your javascript code as that makes it smaller and makes it less readable by humans, but do not count it as any form of real security.
No, there is not.
However, you have some options:
You can obfuscate your javascript -- this will help slightly as it makes it harder to read and understand your code. There are plenty of good obfuscators out there. I advice against this!
You can minify your javascript -- this might look like an obfuscation method, but is not. It can easily be reverted back to readable javascript and is mainly intended for limiting bandwidth. I encourage this, but advice against it for this reason!
You can try to put as much of your sensitive data and code on your server. This might make sense, or it might not.
You can encrypt your data and decrypt it on-the-fly via your own javascript decryption library. Not a good idea, as it is fairly easy to by-pass this security and it is resource intensive. However it will slightly discourage "theft" of your data. I strongly advice against this!
If you can accept to only target Google Chrome (for now) or Chromium, you can implement your code and data in Native Client, which basically is compiled C code running in a sandbox in your browser (Chromium/Chrome). The only way to get access to your code is decompilation. If you are really paranoid over data theft, you can obfuscate your C code before compiling, to try to kill debuggers from snatching your data, and possibly fetch all your data over SSL from your server in real time rather than having it in your binary.
Though, remember, even with option 5 there are ways to claim your data, though it will be very few who both have the will, time and know-how to get it.
And also remember, if you are looking for a way to conceal sensitive data on the web, it is highly likely you have thought out your solution wrongly. Never ever put sensitive data on the client or use client side verification as your only verification. Perhaps the web is not the platform you are looking for? Perhaps you're looking for a distributed solution?
If it's a security concern, don't send it to the client. Even if you obfuscate it, you're not making it more secure.
Obfuscation can only get you so far, because the nature of Javascript is that it is downloaded to the user's system so that their browser (and user) can read it. Making something harder to read is not hiding it completely. You cannot encrypt it without giving your users some way to decrypt it, thus defeating the purpose. What you're looking for is a server-side language that's compiled before the user sees it, such as PHP, Python, Java, etc.
No, not really. You can obfuscate, pack and do all kinds of stuff to make the source code harder to read. Hell, you can even give your objects really weird and indescript properties. But that's it really, you only make it harder to read. The data is there, and a determined attacker can find out what he wants if sensitive data is sent to the client.
So don't store sensitive data client side. Anyway, what's so horribly secret about UI state? If a user wants to break his state, let him?
I would not suggest to try to obfuscate the javascript logic. But you can minify it (i.e. uglifying it). at least you would make it more difficult to read.
If you are concerned about the security of your client side code, then there is no way but to use server side code. Perhaps making more code available through services and then calling your services through $.ajax or someting similar.
It's quite hard for me to figure out if this sort of thing has ever been implemented. I want to look for any libraries that may exist so I don't go about reinventing the wheel.
I have this idea of having a web app that connects the people who are on the site. Every user that is connected to the site may communicate to another user also on the site via the server. So the protocols will be implemented in JavaScript, and the server simply helps to identify users, and just echoes data to enable the communication. For instance I can use this to implement my game networking ideas in javascript, and easily test them without having my testers download any executables, they can just log onto the site.
Now obviously this isn't going to be an effective architecture for any kind of serious application. But I think if I can get it working I could build really cool networking apps without having any sort of download.
What I'm thinking about is using ajax for client->webserver and webserver->client (Comet?) and I can code up the webserver echo bit with PHP or a cgi script. And then I can implement an entirely separate protocol in JS that the webserver does not care or know about.
The reason for having the webserver echo everything is because I don't want to use java or anything else that I can open up sockets in. Why make it harder for me? Because I can and because I happen to be really enamored with javascript at the moment. It's the only web technology I trust. Screw java applets.
Does this make any sense to anyone? Am I crazy?
Don't know about the crazy part (there's a proposal at area51, go check that) but it's definitely doable.
You could use a plain old XMPP server and a javascript XMPP client (there are libraries - for example strophe)
You could do it with AJAX and a PHP backend: Making an AJAX Web Chat
You could use the fancy Websockets from HTML5: Start Using HTML5 WebSockets
You could use some existing component if you can find any (I couldn't find any I would use)
Cheers :)
I've been thinking of developing a web application using HTML and JavaScript for a little while now, but I've hit a wall during my ponderings. I want to be able to connect (long-term, not briefly) to a remote host with this app, one which is unfortunately not the server that the page was requested from.
From what I've read, JavaScript can't support long-term connections, and furthermore it won't request from anywhere that's not the domain the page was downloaded from. I considered hidden Java or Flash objects, but Flash seems to cost money, and Java requires a signed applet (and I don't know whether it's worth getting it signed).
The only solution that I think could work is using my server as a proxy to the others (through an unsigned Java applet?), but I really don't want to do that if I can help it. Is that my only realistic option, or are there other solutions I haven't considered yet?
(I considered asking on one of the other SO-alike sites, but StackOverflow seemed most apt, since this is largely a programming and design issue.)
After carefully considering my own plans for the application, I've decided to go forward with the server-as-proxy approach. Having the client handle the connections sounded like a good idea at first, to save on server resources, but it would have made other implementation ideas unworkable. Sticking to a strict server-as-proxy model handily solves these and other issues I was pondering over, so I suppose that's that!
I have got a particular requirement where some critical algorithms have to be handled in the client-side script and it got to be secured. Using javascript will just expose the algorithm. I am currently evaluating ways to secure the algorithm on the client script. Appreciate any suggestions and alternative approaches.
One option I am thinking about is to download a small applet to the local PC, get the calculations done in it and update the results back. Before deciding on this, I want to know if a client script itself can be made secure coz that would be much easier.
Thanks in advance!
You CANNOT secure anything on a client PC.
Everything you are doing client-side is crackable and spuffable.
That's the PC of the client. It will be doing anything the client has requested it to do.
Script is not secure, also what level of security do you need? If you download anything to the client the client will be able to look at the algorithim. Of course if you download a native dll, then decompiling it will be harder, the question is if this is good enough.
That an important thing most people miss when evaluating security nothing is trully 100% secure. Because your server admin could go in and steal the binaries off your server. And if your using third party hosting who knows who has access to the server.
The idea is to raise the bar. Do you want to prevent the average script kiddie? Obfuscate it, make it hard for them to understand the gain of understanding the algorithim might not justify the pain in trying to understand it.
The best that you can probally do is keep the algorithim on the server and expose it via a web service.
Everything that the end-user is controlling to 100% may be tampered with, and this is especially true with JavaScript that is so easily exposed.
You are going down the wrong path. You need to rethink your approach.
You could build a web-service containing the critical algorithm and call it from javascript.
Bottom line is, if someone wants your logic ... they will get it unless it is server-side and they never obtain it in any way.
What you want is a Javascript obfuscator
Nothing on the client side can be totally "secure".
Anything you make them download will have to be run on the client PC, and so can be analysed. If you have them download an applet or a native executable, it will still contain machine instructions that can be analysed at the very least to an assembly level.
Is there no way you can have the client upload the data to your server instead and perform the calculation on the server side?
It it's client-side, then it's not secure. Anything with critical security concerns should be done on the server.
An NPAPI plugin will execute on the client-side and make reverse-engineering much more difficult.... but of course a determined hacker will be able to reach-through...
Theoretically (and I mean this is a Comp.Sci. sense) this is possible. The cryptographical technique is known as "fully homomorphic encryption". For now, the method isn't practical yet. There are no compilers available that are able to transform your algorithm in its equivalent secure form.