I want to add integration with a third-party service to a web application (developed in HTML and Javascript) which targets Android / iOS (and later Windows Phone). Thus I have access to all "modern" features. This third-party service needs credentials and is controlled via GET-Parameters.
For example, a request url could look like "http://www.example.org/foo?username=user&password=1234".
Changing the third-party service to accept hashed passwords is no option as I have no access to it.
As the user does not want to type in his username and password every time he uses the service or starts the application, I want to save his credentials somehow.
Now I wonder, what's the best way to do so.
I know that real "security" is an illusion here but I do not want to expose the credentials to unnecessary risks by saving them the wrong way.
I already thought about several possible ways
Plain Cookies: The most
straightforward way - is it "secure"
enough in this scenario?
DOM-Storage:
Any differences to cookies in this
relationship?
Encrypted Cookies: The
credentials would be encrypted, but
you could easily find out the key
when looking at the source code of
the page or debugging it.
Which one should I choose? Are there any better ways?
Is bothering with encrpytion actually worth it when it can be cracked that easily?
All the ways are bad and insecure. So is sending username and password as a get param - you even run this over https?
The way to do this usually is to not store the username/password at all, but a GUID/hash that identifies the users session, and then let that session be persisted.
That way, even if somebody else gets access to the session, they won't have the username/password. As part of this, people cannot change the password unless they supply the existing.
Connect to and authenticate with the 3rd party service through a backend proxy if it absolutely needs to have username/password sent.
Related
I'm experimenting with PouchDB and client-side Javascript. The example on the PouchDB site works great for me: http://pouchdb.com/getting-started.html. My question is, is there any way to obscure the username and password when I connect to the remote server? The code in question:
var remoteCouch = 'http://user:pass#mname.iriscouch.com/todos';
This is all client-side JS and publicly viewable. I'm stumped on figuring out a way around it.
When you're communicating between servers you can use SSL to remain secure. The client and server establish a secure connection before sending any data about the request (i.e. the file name, the basic authentication creds, etc.).
As far as what lives on the client side, it's more of a question of how secure do you want to be. Since everything is JavaScript, especially so with PouchDB, you have to settle for one of two things
Having a fancy switch that shows you menus or hides menus
In this scenario you have a main screen with all the important menus. The user either supplies the right password, which takes them to that screen, or the program says "Error incorrect username or password". But since it's all in JavaScript, anyone with enough knowledge of your system could say something like MyApp.User.isLoggedIn = function() { return true; };.
Encrypt what you need
If there is sensitive data on the client side, you can ask them to supply their password and encrypt the sensitive data using that password. Depending on the payload, it may or may not be too performance intensive. You might have to implement your own sessions in this case so you don't end up keeping that password or sensitive data around in memory. Then all Eve would have to do is go to the JS console and hit console.log(MyApp.User.password);. Even though the password is hashed and salted (or should be), Eve likely still has access to the hash function and salt.
Good luck! Would love to hear what you come up with.
If the username and password are to be provided by the user, you can present them with a login prompt and use a secure CouchDB session cookie. The cookie is tamper-proof and will be deleted when the browser session ends or you explicitly delete it.
I'm developing a static website that accesses a web service for some data which uses basic HTTP authentication. I'd like to ask the user for the credentials once, and use those credentials in multiple pages of the static site.
I'm trying to figure out where to store the password with reasonable security. Cookies and local storage are inherently insecure, even if I encrypt the data (the key would still be in the Javascript code). Session variables (i.e. sessvars) seem to be even worse.
I really would like to avoid using a server for this since I don't need a server for anything else.
The only thing I could come up with is building the entire site as a single HTML page and store the password in a closured variable. Even if it's safe enough (which I doubt), it'll still require the user to enter the password each time they visit the page and therefore not ideal.
Any ideas?
I need to access an api which requires http authentification on a per user basis using a jquery mobile api.
I plan to make the app available as a website as well as packaging it in Cordova for various devices.
If I have a login form which captures the username and password and store this as a javascript variable, is there any way this data could be exposed?
If so, what's the best alternative to handle storing the users authentification details? I am reticent to build an intermediary server if I don't have to.
Many Thanks. :D
I would suggest not storing the username or password in the localStorage, but instead to store an access token. Access tokens can be updated and changed frequently, it also doesn't reveal who the user is or what their hashed password is.
Besides iOS Keychain or if you're coding it for a non-iPhone device for added security you can:
Change the access token at each login and each time the app is used
Store the device ID in the server database (see http://docs.phonegap.com/en/2.2.0/cordova_device_device.md.html#device.uuid)
Clear the localStorage and request a new login if the access token or device ID doesn't match the data stored in the database
Make sure you don't store the device ID in the localStorage.
For added security you can also store the user's IP address in the database and check (server side) if the IP address matches, but this might too much since the user would have to login every time they connect to the internet in a new location or if their IP address changes.
Storing the IP address in the server database then checking if it matches (server side) would probably be the safest since it wouldn't matter if someone got hold of the localStorage data.
So I understand you don't control the backend you log in to? If you do, I would be more inclined to send username/password once, and then store some access token that will allow you subsequent access.
If you don't control the backend, you're stuck with storing username/password. I would say, setting them in localStorage is as safe as it gets (which is, admittedly, not very safe. Then again, if your login doesn't happen on HTTPS, I would be more worried about passwords leaking there than from the device itself). You could make the passwords harder to find, not call the variables "username/password", encrypt them in javascript, obfuscate your code. But in the end, they can always be retrieved without too much effort with the right access to the device.
After packaging as native app, you have more options, e.g. iOS keychain: http://shazronatadobe.wordpress.com/2010/11/06/ios-keychain-plugin-for-phonegap/
I made fire fox add-on using java script. I want to give password protection to this add-on. Where can I store the user password permanently ? How can I do this?
The best solution would be to store on an external storage. Just like websites. You send the authentication data, server checks for user and returns true or false. There are a few problems with this. If you want to restrict parts of add-on for non-registred users, that's not possible. The whole code is available to the user and he can modify it.
If you create a website specific add/on search for a data (most likely in the cookies and preferences of the website) that is a secret, unpredictable, unique and uniform for a single user. You can hash that and use it as a password. Along with the username of that specific website. This way you can avoid registration.
Server communication trough HTTP is not too secure, but hey, most websites still use it.
If you don't have an external server available, you can use local storages like a SQLite, or i you have a single password you can use the preferences which are also available under about:config. But these are far from permanent. It's there until the user reinstall operating system, which unfortunately is quite common.
If you want closed source to hide storage mode, hash generating or something like that XP-COM components might help you but I don't recommend because it's really hard to maintain (all versions on all platforms).
If the password is required to authenticate the user to a server then you should use nsILoginManager to store it. The password will be stored encrypted on disk if the user defines a master password. If you want to protect the extension's user interface from the user then it doesn't matter where you store the password - this kind of protection works only against inexperienced users. E.g. you can use Preferences to store it.
given the following scenario: We have a html form for changing an account's password. It looks like this:
CurrentPassword: __________________
NewPassword: __________________
NewPasswordAgain: __________________
We want to send this request via an ajax call. If we send it and we leave our computer (without logging out and staying on the exact same page) someone could open the webkit inspector (or firebug) and see something like this:
http://cl.ly/3y213W1q0U2y2e251k0O
What would be your solution for making this more secure? Is it even possible using an ajax call here or would it be better to use a "normal" html form which reloads the whole page after sending?
Using a "normal" html form has the same problem, as packet sniffing could reveal the same data in a POST or GET header just as easily.
The best solution I can think of is to encrypt the password user-side via javascript. You don't really have to worry about the "what if the user has javascript disabled?" case since, in that case, the AJAX request won't go through either. Obviously this may have ramifications regarding how you store the password, but it will allow you to continue to use AJAX requests for the password update.
The author is not interested in encrypted connections here. He may as well be doing that already. What he wants is to be able to hide the password (and username) from any one who has an access to the computer, and can open the inspector tools to view the networking that occurred on the page.
One of the simplest things you could do is to refresh the page in case the authentication succeeded.
Something that you should do is to refresh the page whenever the user pressed "log out". This should clear all previous network data.
The less good options are about encrypting, obfuscating and hashing the password prior to sending it.
Hashing the password on client-side is not ideal because this prevents the use of hashed passwords with keys on the server-side (think HMAC). HMAC'd passwords are the best, because the key is kept on the filesystem whereas the salt is kept on the database. Cracking the password hash requires a rather solid access to the system.
Obfuscating and encrypting the password can be reversed. If someone sees a login request on the Webkit Inspector, he might be very interested in spending the time to undress your defenses.
I highly recommend refreshing the page at some point to avoid the problem entirely. Other options do not seem as good.
Encrypt the password on transport and make sure the calls you are making are being done over SSL!
To make this secure without using SSL, hash the passwords on the client using SHA-2. While that will protect the password itself, it won't protect someone from sniffing the hashed password. So you can't simply authenticate with the hashed password, either.
One way to do this is to use a server-generated random salt when authenticating. To authenticate, the client requests salt from the server, then hashes the password once (in order to match the hashed version stored on the server), then hashes again using that salt that it received from the server, then finally authenticates using a second ajax query with the salted-hashed password.
The server will authenticate only if this matches its own stored hashed password, hashed with the same salt it previously provided the client.
This way, it is impossible for someone to authenticate using the simple hashed version of the password. Since each salt provided by the server is valid only once, it would be essentially impossible for someone to intercept it and authenticate. (They would have to intercept the salt request, and then try to authenticate before the legitimate client could, all the while spoofing their session).
This protects users' passwords without using SSL, prevents logging in using data intercepted while the legitimate user is authenticating, and is fairly easy to implement. Of course there is no substitute for SSL as far as protecting the actual data on your site, but for a lot of typical web sites where there's not really any sensitive information, you should be more concerned about preventing theft of your users' passwords since people use the same password so often. This addresses that problem.
Note that this also does nothing to prevent session hijacking, but you can minimize the risk and damage of this by doing things like including browsers-specific information with the users's session, and allowing only a single active session at once, and requiring re-authentication to change email address or password.
Depending on the level of security you need, you could use RSA and public-key cryptography to encrypt the password within the browser prior to sending the ajax request. On the server-side, you would decrypt the passwords and process them as normal.
Of course, you would also need to be careful to delete any variables used to hold the entered passwords, and I am sure there are other security holes in this, but encryption will at least offer you some large degree of protection against that sort of attack.
Here's one library I found with a quick search. (disclaimer: I have not tested this, but it looks pretty good)
Lastly, I would strongly recommend that you transmit all login information via SSL. This adds an extra layer of security on top of the whole browser session between the browser and your server.