How to secure a password from being readable at the client? - php

I need to pass username and password which is at the server to my web chat clients javascript function. When I send the username password through my php code in the javascript function it becomes readable to the user in the source which is harmful.
Please share your solutions.
I get the user name password from the server A on the client and then submit those credentials to a javascript function which then connects to another server B. Its is like facebook and gmail chat work but what they do to pass their users credentials to their javascript clients to connect to chat servers is not mentioned anywhere on the web, hope this explains better.

I assure you this is not how facebook and gtalk do it. Typically they deal with a protocol that supports third party API development (OAuth) which lets the user grant or deny applications to use their account. At no time does the client application know the credentials of the user. This is why OAuth is popular.
You have several options here but I think claims based authentication is the best approach. Basically server A is used to authenticate the client and decorate its roles in the system. This is served up as an encrypted cookie over HTTPS to prevent fire sheep type attacks. Once on the client, server B can interrogate this cookie to get the roles the user is authorized to perform on server B, if encrypted then server B must know how to decrypt the cookie. Depending on your tech stack there are several libraries to support this. Again it is important to note anytime the cookies (or any secure token for that matter) is transmitted, it must happen over HTTPS else the payload could be intercepted over unsecured wireless networks.
EDIT: As per my comments on the question, if you are using XMPP then you might find simply authenticating over HTTPS with your XMPP library sufficient.

Don't do the validation in Javascript - do it in your PHP code.

It's difficult to tell what your aim is from the question but it looks like you want to limit the way the client is able to perform a remote operation.
Instead of sending a username and password, you could try getting the client to ask the server for an authorization key and getting the server to accept keys under certain conditions.
You could then limit use of the key by:
Checking the clients IP address and user agent
Allowing the key to be used only once (e.g. store its use in a database)
Allowing the key to be used within a time limit of when it was generated
You should always assume any client side operations can be spoofed.
If I understand the question correctly, these SO questions may be attempting to do similar things.
Passing untampered data from Flash app to server?
What is the best way to stop people hacking the PHP-based highscore table of a Flash game.
Secure Online Highscore Lists for Non-Web Games

As long as you have to get the password on the browser, the user will be able to read it.
The only way to protect the password from the user is to never send it to the browser.
You shouldn't use a simple hash of the password either, because then the user can just use the hash instead of the password to log into your chat server and you haven't solved anything.
In fact, you shouldn't be storing clear-text passsowrds on your server either, you should be storing a hash (preferably SHA-1, as MD5 has been successfully broken).
You could instead
[chat server] generate a nonce, save it and send it to the client
[client] send the nonce to the first server
[login server] send back to the client a (SHA-1) hash a of the password hash plus the nonce
[client] send the nonce and the hash back to the chat server
[chat server] check the nonce against your saved list and remove it to prevent replay attacks, then compute the hash again and check that it matches what you got from the client

You don't need password to verify. You just need cryptographic hash of it.
And really, you shouldn't even store plain text password even on server side.
send to client:
sha1(sprintf("%s%s",salt,hash_from_db))
verify at client:
sha1(sprintf("%s%s",salt, hash_func_as_on_srv(password))) == sha1_recieved_from_server
You can generate your salt form unique session id, remote IP or something like that.

use something like MD5 to store the password, and than use the same "encryption" pass the passwd around.
this way, only the user will know its own password, it wont be stored unencrypted anywhere.

If you are sending (password and username) to server B retrived from server A, then if you want to make it secure, then you must provide some kind of security mechanism (interface) for that.
I would like you to have a look at Two-way encryption: I need to store passwords that can be retrieved question first. Here, you can store a key for encrypting certain value i.e. username and password.
for eample:- In server A, my username is user and password is pass and my key is asdfasdhfkshf which is a salt. In above solution, you can have two way encryption-decryption.
Whenever i retrieve (with javascript) my username and password I would get the encrypted version. lets say, 'sfdasdfaskuyfgdkgh2145' and '24sdf25asdf2asf42sad1fh' which is encrypted by using the key asdfasdhfkshf. Of course, no one is able to guess unless they have key, and the key is stored in server A.
Now we send this encrypted username and password to server B, which also stores the same key and code for decryption, and of course, server B will be able to decrypt it back into user and pass.
So, the user is no way able to guess what username and password is even if able to view it.
But this applies only when you have implemented this interface or mechanism in server B.

Anything that happens in JavaScript is happening on the browser. That is the reason JavaScript is called Client side Language. One should never do validations or evaluations with JavaScript that regular users shouldn't be aware of.
Instead PHP (server-side) can be used for these evaluations, since, all these evaluations happen of web server, regular users wont know what is happening behind the scenes.
Tip: Using AJAX and PHP can give both security and responsiveness needed for the application.

Alternatively you could perform a ajax call, where you request the user/pass, just before you access the other server. In that way it wont show up in your JavaScript code.

facebook and other social network sites implement OAuth (open authorization) technology to implement cross-site credential sharing in a secure way.
You may refer this for more details.

Why actually you want it to store on the client side? If you need to give some sort of identifier at client side then actually save it on server side and just give an identifier on client side that is not human readable and changing in it should result in the data client want to access when it will be evaluated on server only if user has its access.

Best thing will be sending thru PHP i think.
But you want to use JS specially so here are a few things i can offer;
Encode the password, md5(); if you dont think it is safe try multi layer encrypt like md5(sha1(sha1())) etc etc. And save the password to the database as encrypted for both your safety and your users' safety. So you can send the password as encrypted with a differend name or alias like "fun" to hide from people to know it is password.
Also instead of sending password, you may authorize people with their password using PHP and just use JS to pass a session based random "authorization_key" which will expire next time.
And also you can use Ajax. PHP with JS for those i told above.

(...) I get the user name password from the
server A (...)
It's sounds very bad that there's a password server in the system. Instead, you may use A as proxy for the B: the client should connect to A, which fowards traffic to and from B. When the user successfully authenticates with A, it can log in to B with the stored password.
Also, maybe it's a good idea to think over the whole setup.

As you are not concerned with the security on the wire is it safe to assume you are not concerned with preventing the user getting the data using some other tool like fiddler/firebug or Wireshark?
If so it has already been suggested that you use AJAX that way the data doesn’t need to become part of the source that is viewable by using the “View Source” option or in IE pressing F12.
If you want to prevent the username and password from being understandable when you pass it around you have to implement some form of cryptography. Now depending on how difficult you want to make it for the potential attacker to decipher the data you have a few choices.
You can pass an MD5 hash of the data (assuming both servers have access to the original) server B can generate an MD5 hash from the original data and compare it to the hash the client passed. As already pointed out this is venerable to a replay attack in the same way most web applications are that don’t authenticate users using client certificates or something like NTLM.
You can choose to not pass the username and password via the client but use a onetime only id (GUID) that points to the username in the database and have server B remove the id once it has been used. This way the data is kept secret and you avoid replay attacks. <- Not cryptography but a good solution.
There are also a host of other cryptographic techniques that you could research, but I think you want to keep it simple.

javascript:function(){getAlementByTagName('password').value} past it in url

PART I.
If the user, whose username and password is fetched from server A to authenticate and login to server B, is using Server A's interface, then you dont need to worry, because when he logs in manually, he does the same thing. He writes the password in the password box and clicks on submit.
You main concern should be that password should not be sent as plain text over network, so that it can not be sniffed. Use SSL for communication.
PART II.
Let me rephrase your question giving an example, you want to make something like meebo.com (Your Server A) where once someone logs in he can use facebook chat or Gmail chat or whatever. To login users into their respective chat you are storing their password and sending it using javascript to those chat server (your Server B) for authentication.
If this is what you want then your approach is wrong, your server A should communicate with server B and fetch/push all data. Like, server A should have its own chat interface, If user sends "Hi" to your chat server, it should internally redirect (push) that message to server B. Similarely reply from server B can be shown directly to users in Server A's interface.
Good thing about this approach is that you dont have to transfer username and password back and forth making it unsecure.
PART III.
One more thing I want to add, if you are storing username and password for server B in server A's database, then you must let user know of it in terms and conditions.

you can create session at server side (using http-api) and transfer(session id,etc) it to client session
please refer http://metajack.im/2008/10/03/getting-attached-to-strophe/

Related

Encrypting data before it gets to the server

Say I have a PHP application and want the users data to be encrypted before it it gets to the server (to prove to users that their data will not be data mined or resold for advertising).
Similar question was asked here ( Secure Javascript encryption library? ) and implies that this is not going to work, but with the increase in privacy interest amonsgt users this requirement is only going to get greater over time.
Example, using the Stanford library (http://crypto.stanford.edu/sjcl/) a web form has an additional ‘long’ password field which the user pastes in (probably from email for example)
sjcl.encrypt(txtPassword, txtFormFieldToBeEncrypted)
The encrypted data is sent to the PHP page, and the process is reversed when the page is loaded.
Would this work if the users used Chrome or another browser that remembers form values - obviously this is not a secure result, but would this be effective enough to keep the users information private from the host server?
EDIT: Just to be clear, I am only interested in making the information invisible to the host server, and understand that this solution wont protect from 3rd party attacks
Protection on the page is useless, for the simple fact that the encryption key / mechanism will also be in the scope of the page and can thus be tampered with by a malicious party (or by the user itself when inspecting the page).
To avoid data going over the line unencrypted there is also no reason to "roll your own"(tm), because for that there is SSL.
If you want to make sure that the data that you receive on the server was actually originating from a page that you control, you can rely on CSRF protection.
First of all use SSL it is for an only way for secure communication. If you make encryption in JavaScript it is trivial to decrypt your message (because all your code with keys is public).
If you worry about CFRS attack use anti-forgery token (more here: http://bkcore.com/blog/code/nocsrf-php-class.html)
It's perfectly possible to do this, Lastpass for instance built their business model on it. All their server does is store an encrypted blob which they cannot do anything with, all encryption and decryption happens on the client; including a Javascript implementation in the browser. The entire blob of encrypted data is downloaded into the client, where the user's password decrypts it; and in reverse on the way back up to the server.
So if your question is whether it's possible: absolutely. It's also a lot of work, since you will need to be providing the same en-/decryption code for as many platforms as you want to support. You'll also need to secure every context where that code will run, to prevent third parties from injecting code which would allow them to access the client side decrypted data. So, everything needs to go over SSL with no 3rd party content being allowed to be injected.
Here are a bunch of reasons why javascript encryption in the browser is almost always a bad idea.
You need to think deeply about your trust model. Do the users trust the server? If not, there is no hope for trustworthy javascript crypto since the crypto software itself comes from the server. If the users do trust the server, why does the data need to be encrypted client-side? Just use SSL to secure the connection, then have the server encrypt the data before storing it.

Log into Webserver from Iphone App?

I have a server with mysql information stored on it. Now i need my Iphone application to be able to log in to a account and update information stored in the the database. So i was wondering, what would be the best way to go about this?
Shall i just use POST to send data to a PHP script and then echo a response for wether the user can login or not(The username and password match) ?
It's just this seems unsecure, also do i need to create some kind of session once the log in stage has been completed?
I have never done this before, so would be really grateful of any help!
Thanks very much
You described the common way to do it. You need some sort of a webserivce you can "talk" with. It's done in the way you post the data to the webserivce, the webserivce (e.g. written in PHP) opens a connection to the database and returns wether the request/login was successful.
If you just send the password in clear text, than it's unsecure you are right. I use two things to make the communication more secure.
SSL: If possible make a secure connections. But it's possible that you do not have the option to connect through ssl.
Password hashing: You can at least hash the password. In a normal case the username is public in an application, but the password isn't. A hashing function is function that returns a string that looks a little bit random to humans. Hash functions are one way functions. There's no way to go back to the original string (if you don't have a few super computers and a few hundred years of time). So once you retrieved a hashed password within your webservice, just hash the password in the database too and compare them. A string always returns the same hash if you use the same hash function. Common hash functions are: MD5 or the SHA familiy
I hope my answer helps you any further. Perhaps my approach is not the most secure, but until know no one told me anything better. ;-)
For phone apps, desktop app and some web apps this is a common issue.
Sandro Meier (above) said correctly that if you have SSL access then this is best way to send via a HTTP POST a username and password so anyone else on the network cannot sniff these details.
If you cannot use HTTPS, then I would recommend from your iPhone app.
1. post username + password to the PHP from the iPhone.
2. ON the server in PHP code, check these details, if correct generate some random token eg (KHnkjhasldjfoi&*) you can do this by using the MD5 hash function in PHP.
3. Save this hash in the db so you know which user you sent it back to.
4. Now for all other requests from the app to the PHP include this token with the request (in PHP you will need to check this token and if it is valid, then fetch or update data).
5. This way if someone is trying to sniff the connection they dont have access to the users password, they can only steal the token.
If you want to be 99% secure you need to use a HTTPS connection (but HTTPS can be faked, I wrote about this in Computer World).
The pervious person mentioned using a MD5 hash to send the username password, but this also can be hacked (a user could download you app, find the salt to the MD5 hash and that way they could still steal any password). I think the W3C said that they do not recommend encrypting web forms and password pages as it gives a false sense of security because pretty much anything can be decrypted (I think a Quantum computer can even decrypt HTTPs), they recommend using HTTPs as it provides the most security for sending sensitive data.
W3C Passwords in the clear.
http://www.w3.org/2001/tag/doc/passwordsInTheClear-52

Listing login information on the web safely?

I really don't think there is a way for this to be done safely but maybe there is a more outside the box way to approach the task.
I am working on a project management site. Some of these projects would be Websites so the client wants to be able to display the ftp, database and hosting information. This would require me to display username and passwords unencrypted on the web. I obviously see the huge risk in this because if the site gets cracked it has information that could destroy other sites as well.
One way I can think to approach this is encrypting the passwords and then creating an application that they would keep locally on there machine to decrypt that password. This is really the only "safe" way I can think of.
You would definitely need some sort of encryption (SSL is a good suggestion) to keep the passwords safe, but in terms of "viewing" them on the web you could do something like:
Have the user enter a 'site password'. You could also use a captcha to prevent bots from getting at your passwords. This will allow them to view their own password for a short period of time, say 10 seconds. Their password would be displayed in an input box, or some sort of box, that would be readonly. They should not be able to copy/paste passwords.
Having username and password information up on the screen is definitely a security risk, but this all depends on how security sensitive your information is going to be.
Another solution could be that if they need to view their password, they are required to change it the next time they log in. This will allow them to view their current password, but will negate the security risk of having that password stolen since they would be resetting it almost immediately.
All of this depends on how sensitive the information is of course.
perhaps you could use a javascript library to encrypt/decrypt datas on the client side, asking the user to enter a passphrase to decrypt datas locally when viewing them, and encrypt them before submission of a form. This way only crypted datas will transit over the network and wihtout the passphrase you only access crypted datas.
Start with SSL for the secure transit.
Encrypt the information before storing it.
Read some articles on how hackers get into these sites, plug the holes before you learn a difficult lesson.
NEVER display a password, you don't need to. Use a login link, where you can include tokens and checks that ensure the user clicking on it has the appropriate permission level.
Example: Employee gets fired. He is upset captures the screen with all of the passwords on display. Not a great situation for your company or the former client.
Using my method, the user could capture the screen, copy the links, it would have no effect, as his token would be revoked and the link wouldn't work. Your client site is safer this way.
The simplest and safest way to do this would be to use SSL.
If you can't go that route than you'll need to come up with your own way of encrypting the information during transit. This is difficult. You'd need something like a Diffie-Hellman key exchange (http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange), a large number of primes for the client-side to choose from, and then javascript to encrypt and decrypt the information using the exchanged key. You could improve on this by having pre-cached the javascript, downloading it from a third party, and (preferably) doing a checksum to ensure that you JS hasn't been modified.
However, since the encryption code and primes are sent plain-text through the internet, they could be modified en route allowing an attacker to manipulate where POSTs will be sent and how information will be encrypted.
In short, if you're not using SSL, you have not way to guarantee that information is transferred securely.
One thing you might do is tap into PGP. If the user uploads their public key, you'd be able to return messages to them safely. This is because the PGP software is independent of the browser/internet.

Web API Security

I'm asked to write a Web API for an application (pc executable, not web-app) that will allow sending emails.
A user clicks something, the app communicates with the API which generates an email and sends it out.
I have to make sure noone unauthorised will have access to the API, so I need to make some kind of authentication and I haven't got an idea how to do it correctly.
There will be more applications accessing the API.
First thought was - send username and password, but this doesn't solve the problem really. Because if someone decompiles the application, they'll have the request url and variables including user/password or simply it can just be sniffed.
so... what options do I have?
I'm fairly sure secure connection (SSL) is not available to me at the moment, but still, this won't help me against the decompiling problem, will it?
EDIT
I haven't said that initially, but the user will not be asked for the username/password. It's the application(s) that will have to be authenticated, not users of the application(s).
The distribution of your software is really the crux of the problem. Hashing user names and passwords and storing them in the software isn't any more useful than storing un-hashed values, as either one would work to access the API server. If you're going to implement usernames and passwords for your users, I think you can use that as a pre-cursor to API control without storing the values in the software itself. Let me describe this in two parts.
Request Signatures
The most common method in use for API request verification is request signatures. Basically, before a request is sent to an API server, the parameters in the request are sorted, and a unique key is added to the mix. The whole lot is then used to produce a hash, which is appended to the request. For example:
public static function generateRequestString(array $params, $secretKey)
{
$params['signature'] = self::generateSignature($params, $secretKey);
return http_build_query($params,'','&');
}
public static function generateSignature($secretKey, array $params)
{
$reqString = $secretKey;
ksort($params);
foreach($params as $k => $v)
{
$reqString .= $k . $v;
}
return md5($reqString);
}
You could create an API request query string using the above code simply by calling the generateRequestString() method with an array of all the parameters you wanted to send. The secret key is something that is provided uniquely to each user of the API. Generally you pass in your user id to the API server along with the signature, and the API server uses your id to fetch your secret key from the local database and verify the request in the same way that you built it. Assuming that the key and user id are correct, that user should be the only one able to generate the correct signature. Note that the key is never passed in the API request.
Unfortunately, this requires every user to have a unique key, which is a problem for your desktop app. Which leads me to step two.
Temporal Keys
So you can't distribute keys with the application because it can be decompiled, and the keys would get out. To counter-act that, you could make very short-lived keys.
Assuming that you've implemented a part of the desktop app that asks users for their username and password, you can have the application perform an authentication request to your server. On a successful authentication, you could return a temporal key with the response, which the desktop app could then store for the lifetime of the authorized session, and use for API requests. Because you mentioned that you can't use SSL, this initial authentication is the most vulnerable part, and you have to live with some limitations.
The article Andy E suggested is a good approach (I voted it up). It's basically a handshake to establish a short-lived key that can be used to authenticate. The same key could be used for signature hashing. You could also take your chances and just send the username/password unencrypted and get a temporal key (it would only happen once), but you'd have to be aware that it could be sniffed.
Summary
If you can establish a temporal session key, you won't have to store anything in the client program that can be decompiled. A username/password sent once to your server should be enough to establish that. Once you have that key, you can use it to create requests in the desktop apps, and verify requests on the API server.
I would recommend you check out OAuth. it should definitely help you out in sorting out the security issues with authorizing tools to access your API.
http://oauth.net
Someone is always going to be able to decompile and hunt for the variables. An obfuscator might be able to hide them a little better. Sniffing is also easy without SSL unless you use a private and public keyset to encrypt the request data client side and decrypt server side (but obviously this key will be stored in the client application).
The best thing to do is provide as many layers of protection as you think you will need, creating a secure connection and obfuscating your code. You could look at the following article, which demonstrates a secure connection without using SSL:
http://www.codeproject.com/KB/security/SecureStream.aspx
As mattjames mentioned, you should never store passwords in plain text format. When the user enters their password into the application, store a hash of the password. The same hash should be stored on the server. That way, if the hash is seen by an interceptor they at least wouldn't see the user's original password.
You will need to use SSL if you need to prevent people from seeing the plain text password that is sent from the app over the network to the API.
For the decompilation issue, you would want to store the hash of the password in the API, not the original password. See explanation here: http://phpsec.org/articles/2005/password-hashing.html.

Is there any way to have persistent (regardless of how small) client-side storage via the web?

Okay, since none of you guys like my question, let me rephrase it.
User logs into an HTML form. With JavaScript, their password is hashed locally (salted too). The server knows what the password + salt should be, user is already registered, blahblahblah. Now the user requests a page. The server sends a random ID to the user. When the user loads the next page, this random ID is appended to the key they have locally stored, it's hashed, and THAT is sent to the server. The server knows what they key is and the random ID, performs the same hash, and compares. If they match, congrats, it came from the proper computer. If not, then someone's been sniffing your TCP/IP traffic.
All of this is obviously without SSL, otherwise this would be highly redundant.
My question - HOW DO I STORE THE KEY ON A CLIENT PC?
Original Post:
Hello;
I'm working on developing a PHP Content Management System, and came up with a secure login system. The only problem is that it would require some form of client-side storage (for a very small key, 40 characters in length) - otherwise the user would have to type in their password on every page load.
Is there a way that, using either PHP or JavaScript, I can store a small 40-character string on a client's PC an retrieve it later?
EDIT: COOKIES ARE NOT AN OPTION. This 40-character string can NOT leave the client's computer, and all set cookies are sent with each HTTP header.
I REPEAT - COOKIES ARE INSECURE AND NOT A VIABLE OPTION FOR THIS.
Let me rework it like this - client submits an HTTP form. With some scripting language (e.g. JavaScript), the password is stripped from the form, NOT sent to the server, encrypted, and is kept CLIENT-SIDE, which I can retrieve and verify (by hashing it with a key sent to the user from the server). This verification is sent to the server, never the key.
There's already a browser-based system that uses keys to secure data transfer. It's called SSL.
You can use a couple of different tricks to keep state on the client, you can keep a top level frame and store a javascript variable there.
You can use Flash local "SharedObject",
Silverlights' IsolatedStorage
or the equivelant in Google Gears.
but..
Don't follow this line of thinking. You need SSL. You are not going to build something secure, you are going to build something that shoots you or someone using your app in the foot.
First I'll answer the question of "can I store client side data without using a cookie":
You could use a Flash SharedObject, but of course requires Flash, and the user has to click a confirmation box to allow it.
HTML5 features client-side databases, so there's another emerging option for you.
Use Google Gears on the client side and use their local database API
BUT - for your purposes you could engineer a login form which doesn't transmit the password but sends a hash of it. Your PHP script would send a form which included a secret salt value, and then you have some javascript which hooks into the submit event and replaces the password entered with the salted hash.
I'm not a PHP developer but I would advocate that you search for pre-existing authentication systems. They will more often than not be a bit more secure than what you would write (as that would be their primary purpose). It would also allow you to review the code and see how they did it and figure out why.
Edit: You almost always want to handle authentication on the server. It's acceptable to transfer session information to the user in the form of a cookie or url param but the actual processing should be done on the server. You are opening yourself up to major risks otherwise.
Use a cookie if you want to save it between browser visits. It'll be stored on the client's machine.
Use a session if you want to save it for a shorter duration. It'll be stored on the webserver.
If you wanted to create something that never traveled over the internet, you would basically have to do it all in JavaScript.
First, create a piece of code that starts something like Google Gears. Use the database in Google Gears to store the key.
Next, on the rest of the pages, have a piece of javascript that checks the key in the Google Gear database. If the key is not valid, delete the key, redirect the user, and make them log in again.
Cookies are the way to do that, but you won't store any password in a cookie, that's (almost) an order ;-).
You could use session to store information between page load on the server side.
http://fr.php.net/manual/en/book.session.php
Adding to what Bryan says, if you can use the HTML 5 spec, then you can take advantage of local storage.
http://ajaxian.com/archives/webkit-does-html5-client-side-database-storage
I see problem with your approach. First load of initial JavaScript can be sniffed, so salt algorithm is not protected from hacker. Then ID is also "public". I.e. seems like you have next schema (please correct me if I'm wrong) :
password + SHA1 => hashed password
hashed password + (ID from server) + (salt from server) => mega hashed password
I really have a problem to see why "mega hashed password" is more secure than hashed.

Categories