Authentication and Login on 2 website - php

I have 2 site: example.com and exampletwo.com
I want that when a user login on example.com then he is automatically authenticated also on exampletwo.com
How can I do that ?
I use Django + Nginx on first website and Tornado framework + Tornado server on second website.
Thanks ;)
.
P.S. If you don't know this platforms ( Django or Tornado or Nginx ), I accept also a solution for a generic PHP+Apache platform and then I will do some research :)

I would have the code handling user registration on example.com immediately send an https request to exampletwo.com (which authenticates it based on certificates, of course) meaning "add this user with these credentials". This approach seems to be workable for any two web servers / frameworks / languages as long as they're able to send and receive HTTPS requests and authenticate certificates.
If you can't authenticate certificates, you could send the "add this user" message encrypted (as long as the two sites can share a secret to use for the encryption). This may be vulnerable to replay attacks, but if you make a timestamp part of the "add this user" message, you can highly restrict the time window of vulnerability for the replay attacks, probably enough to make this approach viable.
If you can't safely share secrets between the two sites, not everything is lost: you can still use public key encription. The sender encrypts the "add this user message" (including the timestamp of course) with its own private key, then with the receiver's public key; the receiver decrypts what it receives with its own private key, then with the sender's public key. A bit messy and perhaps a bit slow, but under such difficult constraints it's surprising that it can still be done at all;-).

Assuming both the websites can access a single shared database this can be done with both the webpages accessing a table and checking whether a user has logged in or not. I am not familiar with Djano or Tornado, but if the above solution is dubious, you may wish to expose a Web Method (Web Services) of one website and then use (call) the web method from the other.
Cookies are a no brainer as they are site dependent.
And another approach is tracking the user through the IP, but dynamic IP's can pose a great problem and may be used to breach the security.

The problem is that one site cannot set cookies for another. Even if your login code on example.com were to do a server-to-server request to tell exampletwo.com that the user's validated, there's no way to set a cookie to carry this message over when the user actually visits exampletwo.com.
Client certificates are way around this, but if this dual-auth system is for the general public, not a particularly good one. Most people will see some weird request ('Do you want to add this cert?') pop up and run off to the hills screaming.
The workaround is do have example.com spit out SOMETHING that'll cause the user to load something from exampletwo.com. An image, a chunk of javascript, etc... and put an encrypted token in the request (<img src="http://exampletwo.com/login.php?remoteauth=ENCRYPTEDTOKEN">). Then exampletwo can decrypt the token, and if its contents are ok, and send out the image (or whatever you're transferring) with the appropriate cookie set.

Related

Private authentication algorithm - web security

I'm working on a project which generates audio from text(TTS) and provides player with speed/pitch control to users.
My question is related to request security.
The user got widget_id during registration on my site, he put some js in his site, and api works on his site. When the user click on send button, the api.js file sends ajax POST request to my site with widget_id data as well. Then on my side I got the widget_id and the referer:
$referer = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : '';
I'm getting the site value related to the widget_id from my database, and comparing it with $referer.
...
if($website_url == $referer) {
$website_checked = true;
}
...
So my question is: can the attacker using some lib(maybe Curl) change the $_SERVER["HTTP_REFERER"] value, and broke my security?
for example if he use curl and the code:
curl_setopt($ch, CURLOPT_REFERER, 'https://anysite.io/');
Thanks.
So I've updated the question cause as I was thinking that can not be trusted. So please the basic steps of Private authentication algorithm...
Update3: So I started a bounty cause I need to understand the algorithm of Private Authentication in my scenario.
Securing Js
When client browser try to access js library, your server should able to save the client info like complete browser name, OS, IP, Device etc. And server should generate a unique ID for that client
Your Js should set cookie in client browser based on unique ID generated
When user click on send button, pass unique ID from cookie. On server side, validate the client details with the details available on server againest unique ID. This is to insure that the POST request is coming from the client who have requested for JS file. A restriction to directly call POST API without initializing JS file
Validating POST request
Add token expiry date
Always check unique ID generation time and Send Button click time and block suspicious API call based on it. (e.g. Time period is too short between ID generation and Send button click / getting POST request on server)
Destroy/Disable unique key once server receive the POST call
Monitor the IPs from which you are receiving the requests. This will help you to identify the robots and disable the server requests for them. A small program will do your work.
No, it is not reliable. Users can (and do) forge them, for example, with Referer Control or RefControl - though, such things are done by the user modifying their own browser.
Most referers are correct (simply because the number of people who'd go to the effort of forging them is small), but if security is an issue, you shouldn't depend on them. For this to be secure, those making requests should include private authentication, to that they can prove they're who they say they are.
So I do not see any activity here.
I think that if I generate random-token on client side, then make ajax request to my server and store the user random-token associated with his widget id, then making another request with same token, and comparing with saved value, will solve my problem!
To perform a secure call you can use JWT encrypted REQUEST, you can read more about JWT security here If you can decode JWT, how are they secure?:
There is a very reliable library to generate this in PHP, you can use generated token in a any client side language such as JavaScript
https://github.com/firebase/php-jwt
For example below example will include a private/public authentication keys, along side your other data which you can validate on your server side, i.e your widget_id in
use \Firebase\JWT\JWT;
$key = "example_key";
$payload = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000,
"widget_id" => 123
);
$jwt_public_key = JWT::encode($payload, $key);
You can validate REQUEST with various parameters in payload, and also look into refreshing tokens methods of the library.
Answer to your question is, as other wrote, : no. Referer cannot be trusted and can be tampered easily, or even blocked by browser.
BUT :
Is this a real problem ? Security is always a tradeoff between usability and risk, so you have to measure your risks.
For instance, Google Maps widget security relies on referer. It shows two things IMO :
Google did not find/have anything better to check the widget integration comes from the right place
Even if referer can be tampered... they don't care. It is unlikely to happen but more important : if it happens it is not a big problem (for Google at least, the client who have its Google Maps widget "stolen" won't be happy).
Again, real question is : how sensitive are your widget and your data ?
If you really need security, you will have to implement some private authentication (which is just an other way to say a login) and manage credentials, and a place to store them (a database ?), and handle token exchange, and user will have to log in everytime...
So yes, it is possible to have a real secured widget but as I said it is always a tradeoff, nothing comes for free.

Is there any computer specific information besides the IP address for tracking?

I am developing a program to that only allows the same computer to view a specific page once, and after that I am blocking access to that page.
My question is, the IP address works ok but some users have a new IP every time they visit the site. I have come across other sites in the past that use some other means of tracking users, as even with a different IP on the same computer I can't view restricted content.
Anyone have any thoughts?
What are the other option(s) to the IP Address?
The best you can do is tie up the functionality to a user account. That way, you have control over what the user sees.
Tying up to a machine isn't reliable.
IPs change frequently or can be spoofed. What if the user used proxies?
UAs can also be spoofed
Cookies can be disabled or deleted
LocalStorage can also be deleted and is not widely supported
Basically, a user has all the freedom to be free from your restrictions unless they opt to sign up with your service. That's what you call privacy as well.
And did you ever think when users share PCs? What if your dad got blocked on your laptop? You can't view it on your laptop anymore.
There isn't one method that you can use to be unique to any one computer.
You can set a cookie on that browser, but the user could use another browser or just delete the cookie.
There are 3rd party services that run a flash module to get computer specific data to create a guid that you can use, but that's more expensive and also requires the user to load your flash module, which means it wouldn't work on some mobile browsers.
If the page is not public and sent to the user (ie by email), you can generate the URL with an ID, and them invalidate the ID once that the page is visited.
This is the usual approach used by email validation pages.

I've been asked to perform authentication without usernames and passwords, what are my options?

I've been asked to leave passwords and user names aside since most of the site visitors are stop-buy-come-back-several-months-later-kind of visitors, and the motivation was somewhat along the lines "they would forget there passwords any way and have to request new ones".
I suspect there is no realistic way for me to do this thinking IP:s probably change and browsers get updated, cookies are cleared and so forth.
Or do I have any options?
(not that I'm looking for code but rather concepts and pseudo but the language in the project is php/js coupled with an apache server)
Use OpenID.
Let Facebook, Google, Wordpress, or even Stack Exchange handle the authentication for you, and people wont have to remember another password.
Alternatively:
Many users understand the "forgot my password; check my email" routine by now, so why not just short-cut it by having them input their email and send them a login url with a randomly generated token to log in with.
Once they're logged in, keep them logged in for as long as you deem secure.
We do the following in our e-commerce solution:
We use email as a unique identifier.
When a customer makes a purchase using the same email, the order will be attached to their existing user. You don't however get any address details or stuff like that, but have to enter it manually.
The customer will receive an email with a generated password if it is a first time buy. If it is a second time buy, they will just be instructed to log in. This can however be combined with a url and a login token. Likewise for logging into the site, you could just have them enter an email to receieve a login url token.
Combine this with a long living cookie and/or the browsers datastorage to remember the customers details (address and stuff like that).
Another option would be to have them entering something about themselves that they would always know, but others wouldn't. However it is hard to have an internationally workable solution for this.
You could use so-called supercookies, which is offline storage on the client side. Either through html5 offline storage, or plugin like flash to restore deleted cookies. Although, these cookies is likely to be banned at some point, since they're mostly hidden for the user, and very hard to get rid of. (Not recommending this approach, just saying it's possible)
Authentication credentials break down to three options;
Something you know - passwords
Something you have - physical keys, cards
Something you are - iris, retinal and other biometrics
The best you can do is use cookies I think. Or...I guess you could have them download a file, and upload that file as their access credential - same idea as a cookie but unlikely to be deleted. You would have to think carefully about what to put into the file however - their user id isn't enough, as it would be easily hacked. A random long string would do, one that is saved into the database on their account. Nothing that can be predicted, and nothing that can be used to guess a different account's credential.
A couple of options come to mind:
Use a persistent cookie, but only do this in conjunction with SSL (so it simply can't be sniffed off the wire)
Another option is OpenID like you use here - therefore vistors can use an account they use often to log into your site.
It seems to me that your only option is giving them a forever cookie and hoping it doesn't get purged between visits.
You can read about them here.

How to pass login credentials from foo.com to bar.com securely?

I have two websites https://www.foo.com and https://www.bar.com. bar.com is the actual application, but foo is where the clients would prefer applicants log in. Historically I have logged in at www.bar.com, but now wish to create a form on foo.com to login to bar.com that passes the login to bar.com securely. If there is an error with the info entered into foo.com, i'd like to redirect to bar.com.
[both sites are https]
I've got a form built for the clients, but certainly don't want to send passwords in clear text.
clarification The form is to be given to multiple clients that they will then put on their own page to login to the actual application. The clients are SaaS, that no longer want the company that "does all the lifting" to be what their clients log into
It doesn't sound as though you need any complicated server-side solution for this. Just copy the form from bar.com to foo.com, and modify the action attribute of the form element to start with https://bar.com/. No other changes would likely be necessary, and this would be no less secure than logging in on bar.com directly.
You don't want to pass credentials between sites. This is inherently insecure. What you want is a single sign-on (SSO) solution that allows for centralized authentication and access control.
Read up on SSO:
http://en.wikipedia.org/wiki/Single_sign-on
CAS is a popular SSO, and there are many languages you can use.
If you make those two web sites http://www.foo.com and http://secondsite.foo.com then you could share a single login cookie between the two sites (rooted to "foo.com") and the user could freely go between the two sites, logging in on either one.
There are some javascript md5 encryption functions that can encrypt your password before sending it to http://bar.com/login. If you choose this method be aware those functions have mistakes and some of the generated hashes aren't right.
I would personally choose using ssl as this is the most secure way.

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