Gmail/Facebook without username/password - PHP Login Header Problem - php

I want to create my own personal login gateway into Gmail/Facebook/any other site. In this gateway I enter my master username and password, then I can choose where to login (gmail/facebook/etc) without entering those usernames because they are stored on the server.
I tried to implement this by using cURL to send POST request with the headers and post data sent in Firefox during regular login. However, this doesn't work for neither facebook or gmail.
Has anyone tried this or have an idea about why this doesn't work?
Thanks.
// Edited
I am thinking the problem that it doesn't work lie in the fact that the IP address of the php server which sent the curl request to gmail is different from my browser's so, when the response from the gmail server is fed back to the browser, it still cannot authenticate.
Or is that the cookie I sent using curl to Gmail server actually changes according to time.

Based on your reply to my comment cURL is useless for your problem. You need to authenticate your browser with your services (gmail, facebook, ...), what you are doing now is authenticating your script (or your server).
You will have to use JavaScript to accomplish what you want. If you store your credentials for the services on your server, then send them back to the client once you successfully log-in into your webpage. Then you could create a hidden iframe with the "src" attribute set to the login page of the chosen service. Once the iframe loads you can fill the login information (username/password) into the appropriate fields and submit the form. Once this is complete you should be loged-in into your services.
There are probably some other techniques but this is the first that springs to mind ...

This is not necessarily feasible, Gmail and Facebook may be doing very simple checks to see who the referer is and when it comes from your site rather than their own login page refuses to login. This is basic security checks.
You would need to look at their api to see if you can do anything, or possibly you could use javascript and a firefox plugin to write your username and password to the webform then submit the form, a bit of a hack but might do what you want.

There is no reason why the cURL method you tried wont work with the correct headers. playing around scraping sites like digg.com i found i needed a valid USER AGENT header and of course an appropriate REFERER URL, keep going with the curl technique if that will work best for you overall. use an http header add-on to firefox to see what headers you are sending to gmail and then fake them completely.

Tryusing firebug to find out what the response returned, It should always give you the best lead.
I see no reason why it wont work, I read my Gmail and analytics with Curl.

Have you configured curl to accept and store cookies? Usually once you've been authenticated for an online service it will send you a security token in the form of a cookie that you can send back with every subsequent request to verify your authorisation.

Related

Can you grab a webpage contents and the cookies?

I have a google apps domain that i'd like to create a custom login page for but am having problems.
Google provides documentation for SSO/OpenID/userApi that will do this. The implementation on these docs that I can understand states once a user hits your site they will be sent to the regular gmail login and then sent back to your site once logged in. I'm trying to have them login in a custom page and not be sent over to googles default gmail login. There is other documentation that seems to require SSO and a lot of integration that I am too incompetent to understand which would let you do that, but as I said it's way over my head.
Then I thought I could just copy the form element and create custom css seeing as the action value on the form would authenticate via google. This worked sporadically until I figured out that when you go to https://accounts.google.com/ServiceLoginAuth (the default gmail login) it creates a value (name="GALX" value=Randomletters) in the html form that must match a cookies name and value to be able to submit and authenticate to google.
From here I thought no problem I'll create a hidden iframe to the google login so the cookie populates (it does get the cookie) and then read and insert the value in the html form. That is until I discovered you cannot alter or read another domains cookies for security reasons which makes perfect sense.
Then I thought I could just use php's file_get_contents on the gmail login url to get cookie and the right html and just insert the html into my custom page. I received the html but no cookie this time.
Is there anyway to send a request that would return the html/cookie pair with something like php's file_get_contents('url') or curl? This way I could traverse the file_get_contents object and insert the html into the page via the DOM. Or am I barking up a tree that will never work because security reasons specifically prevent this?
If the above isn't possible could someone explain how I could login my users via a custom login screen?
the google docs for such a project are:
https://developers.google.com/appengine/docs/python/gettingstartedpython27/usingusers
https://developers.google.com/appengine/docs/python/users/#Python_Signing_in_and_out
https://developers.google.com/google-apps/sso/saml_reference_implementation
I believe this is what you're looking for...
http://curl.haxx.se/docs/http-cookies.html

Is there a way to load another website login page, wait for it to be submitted, then read the location querystring?

I need to load the login page of another website (different domain), wait for the user to fill it in and submit it, then read the URL/Location/Querystring for a token parameter to my site and close the login page.
Don't want the username or password, only interested in the returned token (http://www.othersite.com/?token=blahblahblah), which will then be passed as a querystring to a page on my domain (http://www.mydomani.com/loadtoken.php?token=blahblahblah).
Currently, a user has to do this in a separate page, copy and paste the token into my page, since these tokens only have a short life, it's somewhat irritating practice, and if it can be done behind the scenes by the site instead it would make it simpler for everyone.
Reading around on iframes, divs and ajax suggest this is not possible due to security policies, cross site scripting, etc.
Is it possible? What should I be looking for or concentrating on, or can you give some examples.
Thanks for your help.
Edit: Should have said, I understand that it's possible to take the username and password and do a POST behind the scenes, but I really want to avoid making the users give my site their login details to another site, for obvious reasons.
The simplest method is to present the login form on your own site. The form posts to your server, and the handling script then does a CURL request to do its own request to the other server. This sends the login response (which presumably contains that token) to your server.
However, if this token takes the form of a cookie, and the cookie's required for the user to do further operations on their own on this other site, then this won't work. There is absolutely no way for your server to accept the cookie on the user's behalf, then send the cookie to the user in such a way that it appears to have been set by the other server.
The easiest way would be for you to post that form's information to the remote host and have that site send the token to a callback script on your own host.
I need to load the login page of another website (different domain), wait for the user to fill it in and submit it, then read the URL/Location/Querystring for a token parameter to my site and close the login page.
You can't do that
What should I be looking for
OAuth / XAuth (which will require the co-operation of the site you are trying to log in to)

how I can give my credentials with get_contents? php

I have looked at some examples and they use Curl in php etc but I just want a simple command that passes my credentials to a site so it can login and give me access to download a file. Current problem is when I try to use get_contents I get stuck at login page because it needs a login before it can allow a download so isnt there a way to send my login info before get_contents in php? Thanks
for example we can assume the website is located at www.confluence.com
You're out of luck. file_get_contents() can only get content, hence the name. You can try to authenticate via the get syntax for standard authentication, like http://username:password#example.com.
If you have to post your credentials via HTTP POST, you'll have to use curl.
The problem is that when you log in the server send to your browser a cookies that your browser automatically stores.
With file_get_content() you can actually pass cookies ( the third context parameter of file_get_content() can handle this).
Have a look at stream context create.
By the way, you need to first send your login info to the login page (with curl), when you recive cookies back, pass them as option to file_get_content() and the trick is done.
If the server is using a login system different from cookies let us know, so we can help you

What Differences Are There Between Form Submissions and cURL Requests?

I'm trying to submit data to SalesForce.com, but I'd like to do it through AJAX. Since there are restrictions to deter XSS, I'm having jQuery use AJAX to submit to a PHP page on my server and then having that page simply forward the formdata it's passed along to the proper URL.
If I submit the form with JS turned off, everything goes through fine. If I turn it on, Salesforce confirms receipt of the data (in debug mode), but it's not showing up in my queue, or anywhere really, in SF. SF spits back all of the fields it was passed, and it's spitting back every field that I have in my form, properly filled out.
Are there any differences between submitting something through this method (jQuery's $.ajax() to PHP cURL) and through the native HTML Submit button? Something that could be causing SF to register the data, but register it differently? I've tried adding CURLOPT_HEADER/CURLOPT_HTTPHEADER information
Well, the only thing that's different that you can't fake is the IP address of the request. Depending on how tough the protection is that salesforce is using, you may not be able to spoof from a separate IP address (it would detect and deny the request).
Everything else should be 100% fakeable (headers, etc). What I would suggest is that you get firebug or TamperData and look at the raw headers being sent to salesforce from your browser normally. Then replicate that exact request from PHP. If you need other information, you could detect it in JS and pass it to PHP (Cookie information, browser info, etc)...
$.ajax() transmits cookies from the client browser; and it also adds a "X-Requested-With: XMLHttpRequest" request header.
Maybe try adding the (external) IP address of the machine that is running the php code to the list of trusted networks in salesforce. Login to salesforce, and go to setup -> security controls -> network access, and add the IP there.
I ran into a similar problem and had to add the ip address of the server that was running the java app that connected to sf and this fixed the problem for me.

Why does livehttpheaders show my login and password and how can I prevent it?

I was looking at the livehttpheaders plugin for Firefox and decided to test my login page. I noticed that the parameters shown inside of it contain my login and password. For example:
username=sarmenhb&password=thepassword&submit=Login
in plain English.
I don not see this on other sites.
What can I be doing wrong? I see this as a security flaw. The login page, all it does is validate and log in the user. All fields are ran through mysql_real_escape_string (in case that is relevant).
The information has to get to the server from the client some how. Use SSL if you are worried about security.
Even if you do an MD5 hash in Javascript, this does not help because it is trivial to submit the hash to the login page, and the hash effectively becomes the password. All things are plain text until they, or the transport, is encrypted. POST the variables, use SSL.
To add from my comment below. You may not see the headers for other-sites because they may use AJAX, POST method or another client-side mechanism to authenticate.
This reminds me of a certain building in a large city (I am sure there are others in other places) where they have a web based interface to the building concierge. Residents can log on to a web site (over http) and specify (among other things) who is allowed to enter their apartment for repairs etc in their absence. I am sure the whole thing was programmed by someone's nephew who is a 'guru'.
I am sure it is, shall we say, good enough.
You're seeing it for your site and not for others because livehttpheaders shows the URL for GET requests, but doesn't show the content for POST requests.
Sending login information through GET requests is a minor extra security hole over sending them POST, in that the URLs for GET requests are often logged in various places, whereas almost no one logs POST content. Does everyone with permission to look at the webserver logs have permission to know the CEO's password?
However, as others have pointed out, unless you're using https: for login, data is going across the network in plain text whether you use GET or POST. This is almost always bad.
Still, as an intermediate measure I would change your app to send username and password stuff as a POST, not a GET, so that you don't end up storing usernames and passwords in your webserver logs - it's no use using https over the wire if you're doing something that then writes the username and password to an insufficiently protected logfile on the server.
When you are using http and submit a form, the form contents are sent across the wire "in the clear", as you're seeing. When that form submission includes credentials, then yes, you have a security issue.
Among your alternatives are:
Use https, so that over-the-wire communication is encrypted
Use OpenID for login, which pushes management of https credentials off onto the user's OpenID provider
Use Javascript on the client side to encrypt the credentials before posting the form
The latter approach tends to get people into trouble if they're not very careful, because the mechanism for encrypting the credentials is fully visible to anyone who cares to inspect the javascript.
HTTP live header shows POST requests as well. Post sends the data the same way as GET does but the only difference being that the variables are passed in the url itself in GET but in POST they are appended to the HTTP header.
To get better security use encrypting in JS (only password or token+password). But that still can be hacked using rainbow tables for say MD5 or any other hashing technique.
SSL is the only way to achieve high security.

Categories