How to implement remote authentication

I need to authenticate a user using a remote site. I’ve never done anything like this before, so I’m not sure of the security implications. The remote site will have passwords hashed, but I’m not sure whether I need to be sending the entered password hashed or not. Would calling GET on a url like this be insecure?

https://site.com/users/username/password

Maybe it would be better to call

https://site.com/users/username/hashedpassword

OR maybe it should just be

https://site.com/users/username

And then I can compare the hashed password to the hash returned in the response (I don’t like that idea because that means anyone could get the hashed password for any user if they know the username).

Some advice here would be much appreciated. I’m also open to using an existing standard if it’s easy to implement.

No, what you describe is for HTTP Authentication, and that’s not what you need.
And as far as the Man in the middle Attack goes: every request that is unencrypted is prone to the man in the middle attack (and even some encryption methods are prone to the man in the middle attack).

What you proposed was to do a request like:

GET http://www.example.com/secret/?username=someone&password=somepassword

The problem with this is that people can see the URL, see what it returns and they’re in.

If you were to do this very same thing using SSL, it still wouldn’t work, as the URL in the request is not encrypted, only the data sent to and from the server is.

That’s why I proposed a POST request, where the sent data is encrypted

POST https://www.example.com/secret/
Post-data: username=someusername&password=somepassword

That way the post-data is encrtyped on your server before it is sent and gets sent to other server that way. No man in the middle is able to hack that system. (unless he’s got several billion pc’s at his disposal; eventually everything can be hacked :))

Yes, do you have any suggestions on where to start with that?

I’m not sure I understand how that would work. How are credentials passed to the remote site in the first place? How would the remote site know which site to POST data to? I don’t really need anything secure coming back from the remote site, just a yes/no as to whether the user was authenticated or not.

You need a way that your site and the remote site are able to talk to each other, while people sniffing the requests have no idea what to make of it.
An easy way to do this would be for the remote site to POST data to your site, and your site has SSL on it. Then an atacker has no way of knowing which user is trying to log in and what his/her encrypted password is.

Alternatively, if you don’t have SSL, you could implement Diffie Hellman (which is what SSL is based on) yourself.
Beware, this algorithm is not simple!

I would think it would be definately insecure. Couldn’t you do it as a web service or use an API?

You’re incorrect, Wardrop. The full query string is sent during the TCP handshake process, before SSL negotiation is attempted.

To be honest, the following would be secure…

https://example.com/authenticate/username/password

As long as the receiving server only responds to requests over HTTPS, then this method should be as secure as any POST request over SSL. But to be honest, you want something smarter than just a dumb “Is the password “password” correct for username “username”?”. You’d need methods to prevent brute force attacks on the authenticating server, and something like a secret key would also be desirable, where the authenticating server only processes requests which include a certain key.

I could be wrong or possibly missing something, but as far as I’m aware, a GET request IS part of the data that gets sent to the server. My understanding is that the url is interpreted by the client, such as the browser, and converted into the appropriate request. So a request to “http://example.com/this/that” is converted to something like…


GET /this/that HTTP/1.1
Host: example.com
User-Agent: jibba jabba

…and sent to the server with the IP address corresponding to “example.com”. If SSL is used, then everything in the above code block is encrypted.

Scallio is right. You should encrypt your messages but if you want to harden the hackers job you should use one time encryption key for each session. Which is really a hard issue but not impossible :slight_smile:

Sure, if you’re sitting around waiting for the remote site to send a POST request back. However, if I’m just sending a GET request and basing the authentication off the response, that’s not prone to a man in the middle attack, is it?

Do you have a link to something that would explain how to implement the SSL-based authentication scheme you mentioned earlier?

I beg to differ. This approach is very prone to a Man in the Middle Attack.
i.e., your website sends a request to the remote site, asking if a user is logged in, the man in the middle intercepts this request, and answers “yes” (while the true answer might have been “no”).
Using SSL this attack is impossible, because of the use of Diffie Hellman.

Would something like this work? (Using SSL of course)

<?php 
// HTTP authentication 
$url = "http://www.example.com/protected/"; 
$ch = curl_init();     
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
curl_setopt($ch, CURLOPT_URL, $url);  
curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");  
$result = curl_exec($ch);  
curl_close($ch);  
echo $result; 
?> 

Found on this page: http://devzone.zend.com/article/1081

Listen to Scallio, he’s spot on.