A Dropbox browser client with application API key and secret stored in its source code is a bad idea as anyone could impersonate the application using them.
But what about the Dropbox API key encoder, if used, can a
third-party obtain the original key/secret?
If an attacker obtain the key/secret pair, what is the worst case
scenario that can happen to users of the compromised application?
What are the best practices dealing with Dropbox security in a
browser only client in order to have a perfectly secure
implementation (if possible)?
I think that the application stored on the client can never be completely secure, but I still would like to hear from developers more experienced than me.
Thank you in advance for your help
Caveat: I'm not a security expert.
Using the encoder might discourage a casual "attacker" from picking up your app key and secret, but it doesn't provide any true security. Here's a line of code using the JS library that converts an encoded key back into the unencoded key/secret pair:
Dropbox.Util.atob(Dropbox.Util.encodeKey(encodedSecret).split('|')[1]).split('?')
That said, the security risk here is that someone else uses your app key and secret, which is arguably not the end of the world. Pretty much all client apps that use OAuth (in the browser, on the desktop, and on mobile platforms) suffer from this problem. For example, here's one article discussing Twitter's leaked consumer key/secret: https://news.ycombinator.com/item?id=5337099.
I think the most likely consequence of exposing your app key and secret is that someone will copy/paste your code and use your credentials. This would be misleading to users (who will see the name of your app when they authorize via OAuth), and if another app takes your key and uses it in a malicious app, your legitimate app might end up being collateral damage.
Related
I am working on a project with a group of fellow students providing some apps for a company. These apps will have a Bluetooth connection to a device (one of the devices is a raspberry pi if that helps at all) We need help providing some kind of security to the data being transferred over the Bluetooth connection. We are thinking of doing a hash but we are unsure how that would look. We dont want a super strong hash as that would slow the connection, just anything to provide some kind of security to the data being transferred will work, thank you for your time.
P.S we will also be using Xcode too for another app too so if anyone has experience with xcode providing security on that would be great :)
Symmetric-key Encryption might solve your problem. Symmetric-key Encryption is a cryptographic algorithm that allows for shared secrets between two parties. In your case, if you wanted to send a secret message from an xcode app to a raspberry pi via bluetooth, you would first give both parties (the xcode app and the raspberry pi) a copy of a secret key. With this secret key, whenever one party wants to send a secret to the other, it encodes the data with the secret key, sends it to the other party, and the other party decodes it with the secret key.
Without the secret key, it would be virtually impossible to decode a message that has been encoded with a secret key. Therefore, you're fully protected against middleman attacks. Some secret key algorithms out there are Twofish (although I don't recommend it), Salsa20, and IDEA.
Symmetric Key Encryption is most likely avaliable on a standard crypto api.
For more information: https://en.wikipedia.org/wiki/Symmetric-key_algorithm
I assume with 'security' you mean 'confidentiality' and 'integrity' of the data in transfer. You said you wanted to have a hash, but hash (or rather an MAC/HMAC) can offer you only integrity checks. With encryption you could achieve both.
If using symmetric encryption isn't to much of a deal and you have no problems with sharing keys across the devices (or storing hardcoded secrets), I would go for symmetric encryption. I'm not the expert in JavaScript so I took a look on what is available out there... Man, I thought encryption in Java sucked.
Just find something people are using in JS now days and check the quality yourself.
I am using twitter oAuth in a app, each time of app starts asking for authorisation, but I want a single time authentication to use timeline and other things for that I want to store access tokens, How is it possible.
Thanks in advance..! :)
I use localStorage for this. There's a simple guide with samples here: http://www.smashingmagazine.com/2010/10/11/local-storage-and-how-to-use-it/
On other platforms (Android), I wouldn't recommend this since the app's sandbox can be easily compromised on some devices. On BB10 though, the app file can't be obtained by rooting the device (since it is secure) and the sandbox can't be compromised. If you're extra worried about security, run the token through an algorithm to 'encrypt' the token before saving it to localStorage. Since the code in your app can't be compromised (again, secure platform), that algorithm is safe and secret.
Also, BB10 affords you 25 MB of space in localStorage, which makes it a really nice container for dynamic things. Local Storage will persist when you close the app and open it.
Again, this is not a best practice for all platforms, since on some platforms the app or it's sandbox can be compromised such that someone could get your API keys or tokens just by extracting your app file. But it should be safe on BB10.
Good luck!
John
Note, response is my own and is not endorsed by my employer.
I am successfully implemented HMAC verification from the backend but would like to offer JSONP support. Since I dont want the client to know about the secret key, what is the best way to take advantage of HMAC and make calls from the client?
If the attacker knows the secret key then he will always be able to generate a valid HMAC. An attacker will be able to obtain this HMAC value by looking at the traffic or by modifying the JavaScript. A JavaScript debugger like firebug could also be used.
In short, this security feature doesn't exist anywhere because its completely and totally worthless. It sounds like you are very carefully implementing a CWE-602 violation.
Trusting the client is the worst mistake you could make. The very foundation of modern web application security is about defending the server from the client. I think you have a lot to learn.
Cryptico seems like a super slick RSA encryption library.
cryptico.wwwtyro.net
In regards to JavaScript applications, suppose I want to send data to the client, have them do something to the data, and pass it back. How can I use RSA to ensure that the data clients send back to the server is not tampered with? Since JavaScript is easily reverse-engineered, is there any practical client-side application of cryptico?
Do you - by your example - mean that you want to hide from the user what his client is doing with the data? If so - it's impossible.
You should never trust any data which comes from the client.
If you send encrypted data to the client to process - you must assume that the user knows (or will know if he wants) the encryption key, otherwise it will be impossible to process. In other words there is no secure way to hide from the user what his client processes. Obfuscation - like you've noticed can always be cracked no matter what language you use.
I think that the most common and practical client-side application for this library would be encrypting user's data and sending them to server or vice-versa. There may be some cases you can't use SSL. Moreover, you can make -for example- an encrypted post on facebook which only your friend will be able to decrypt (because he knows the key).
There is a solution to what you seek (I'm sure there is more than one). My answer requires two non-conventional approaches to what we call a 'secure connection' and how you receive the 'client code'.
You need a physically pre-shared key that initiates a secure connection, and because it's pre-shared it doesn't have to be RSA, which then opens up speed opportunities and higher levels of encryption security for you.
Physically pre-share your client code in a similar manner, i.e., download the code from a cd in a magazine or from a pre-paid card sold in a market. This stops the MITM from sending you tampered and exploited clients, which ssl allows. Once client is known to be secure, and a real secure connection, mentioned in (1), is established, the client code can be updated.
With the combination of a pre-shared key that develops a secure connection and client code that can pass a checksum, you can achieve what you are after.
Ideally, we should have pre-shared secure connection keys available in the market now, but we don't. So, for you to do it alone, would require to implement something similar for you website specifically until people in this country get their act together with some real security. You would have to give them keys over your phone, through the mail, etc. And your client code would most likely have to be a browser extension to install it due to cross domain security issues.
How can a user, using one of the major modern browsers, know for sure that he is running my unmodified javascript code even over an untrusted network?
Here is some more info about my situation:
I have a web application that deals with private information.
The login process is an implementation of a password-authenticated key agreement in JavaScript. Basically during login, a shared secret key is established between the client and the server. Once the user logs in all communication with the server is encrypted using the shared key. The system must be safe against ACTIVE man-in-the-middle attacks.
Assuming that my implementation is correct and the user is smart enough not to fall victim to a phishing attack there remains just one large hole in the system: an attacker can tamper with my application as it is being downloaded and inject code that steals the password. Basically the entire system relies on the fact that the user can trust the code running on his machine.
I want something similar to signed applets but I would prefer a pure javascript solution, if possible.
Maybe I am misunderstanding your problem, but my first thought is to use SSL. It is designed to ensure that you're talking to the server you think you are, and that no one has modified the content midstream. You do not even have to trust the network in this case, because of the nature of SSL.
The good thing about this approach is that you can fairly easily drop it into your existing web application. In most cases, you can basically configure your HTTP server to use SSL, and change your http:// requests to https://.
This is an old, open question but the answers seemed to not do this justice.
https:// provides integrity, not true identification nor non-repudiation.
I direct you to http://www.matasano.com/articles/javascript-cryptography/
Don't do crypto in JS, because a malicious injected script can easily grab passwords or alter the library. SJCL is neat, but it offer a blatantly false sense of security (their quote, and quoted by above)
Unfortunately, this is not as great as in desktop applications
because it is not feasible to completely protect against code
injection, malicious servers and side-channel attacks.
The long-term issue is that JavaScript lacks:
Uniformly working const
The ability to make objects deeply const and not reprototypable.
Code-signing
// codesign: cert:(hex fingerprint) signature:(hex MAC)
Certs would be managed similar to CA certs. MAC would be used with appropriate sign/verify constructions.
Crypto, clipboard stuff are reasons to have JavaScript native plugins (signed, of course)
Getting JavaScript engines to all implement a standard is another thing, but it's doable an it's absolutely necessary to end a large swath of malware.
You could have an external Javascript file which takes an MD5 hash of your login JS, and sends an Ajax request to the server to verify that it is correct and up-to-date. Use basic security or encryption practices here - public/private keys or some other method to be sure that the response came from your server.
You can then confidently display to the user that the client-side scripts are verified, and allow the login script to proceed.