I stumbled upon a method of securing user accounts which basically automates the user's password. From a user perspective I think it's much better than a conventional passwords and I think also from a security perspective it would be preferred over conventional passwords.
I'm developing a PHP based application that will be a companion app for a video game. Which is only relevant to explain the link I'm going to post for others to test the method I'm proposing. It involves multiple files so posting a link and asking people to try the method is the best "explanation" that I can provide but I will brief the method also.
The user provides an email address to create an account. The program generates an email with a link in it. When the user follows the link in their email, an access cookie is set on their device.
The user is given control over the cookies which grant access to their account. The user can revoke access cookies and set new access cookies on other devices.
The program also compares access cookies and fingerprints, and will revoke access cookies when the device's access cookie and fingerprint don't match with the database.
Revoking a cookie has two effects. The database connection between the device and the account is updated so the revoked cookie no longer provides access to any accounts, and the revoked cookie is subsequently unset from any devices it's found on.
Included is a picture of the user account page which shows the Access List, the list of cookies that currently grant access to this user account. The user can revoke access from this page or send another email to set a cookie on another device. The image demonstrates an account which has two access cookies granting access to the account from two devices.
The user or program can revoke all access cookies and still the user can send an email to the address associated with their account and easily regain access to their account.
Depending on the device fingerprinting method, the user will need to reset cookies on devices after browser updates or changing plugins.
On the positive, they don't need another password. Passwords are commonly referred to as the "weak" link in an account and this method essentially automates, refreshes and maintains the integrity of passwords through cookies and an associated email account. As I mentioned in the beginning, from the user perspective I think this experience was much better than a conventional password system. So now I want to learn how this method is vulnerable and how those vulnerabilities might be mitigated. I understand that this question is less concrete than what is expected for stackoverflow but if not here then where do I get this feedback? Links?
Obviously the actual code may be a security risk but I thought we could get to that level of detail later? If you're interested please try the implementation at the link. The site is themed after a video game so please be patient with the color scheme, only the account control feature is working right now. Navigate to the account page, enter a fake username and a real email address and then if you have multiple devices please try setting access cookies on them. I have verified the program working as intended on 2 Windows/Chrome devices and 1 Android device. None of your information will be retained.
development url
Related
I have a couple of questions regarding facebook integration and authentication in my social networking iOS application.
First of all, Users of my application are required to create an account and login before any content is available to them.
I have a separate backend system, so regular account registration inside my application is supported. When a user is logged in to an account he or she is supplied an access token which is used for future backend-requests, such as image-uploads.
Secondly, A user can choose to log in with Facebook, and thereby acquire an access token from the successfully opened FBSession.
This leads to my first question: How do I use the access token acquired from Facebook to authenticate my users with my backend system? Should I send the acquired token to my backend and have the system use that token for this particular user until further notice, or is there another way to go about this?
--
Now lets say that I solved the problem in the first question...
My second question: Imagine that a user created an account and logged in the normal way (i.e. without facebook) The next time that user wants to use the application, he or she chooses to log in with facebook. Now, In my backend-system, how would I know that these two users are the same, connect them and thereby be able to load the same content for both cases? Is it even possible to have hybrid accounts that supports double logins like that? A regular registration only requires email, username and password, so I cannot think of a way to determine that a facebook-loggedin-user is the same user as a normal-loggedin-user.
I Hope the above makes sense.
The only way to unite the two memberships is to use a common link as a username or identifier such as email. I am sure fb, google, yahoo and others relay the users email account information. Your database should allow for storing your user's email address. The hurdle then becomes what do you do when user login with facebook then the next day using gmail that's when it gets tricky and you have to implement some mechanism for those accounts to be linked.
A regular registration only requires email, username and password
In that case, you can ask the user to grant the email permission to your app. So, by matching both the emails (since, a regular registration requires email) you can determine that this facebook-loggedin-user is the same user as a normal-loggedin-user.
But yes, in some cases(very less) you might not be able to fetch the email (Register with Facebook sometimes doesn't provide email); but then, the registration process won't be completed- so that's not an issue I guess.
On my site, I intend to offer users the ability to authenticate via OAuth. I don’t want to ask them to first register with me and then connect an external account; I want to offer single sign on.
I believe we’re supposed to reuse Access Tokens; certainly within sessions and even between them.
Google goes so far as to say they’ll limit the number of access tokens to 10 per user per application. (Apparently Google still supports OAuth1, but recommends Auth2 now) 10 is a pretty small number.
Using cookies (like this) seems like a good plan for identifying a user between sessions, but I’m having trouble with the scenario where a user has deleted cookies or connects from a new machine.
How do I know who the user is before I’ve requested another Access Token for them? Request tokens do not contain the userid, right?
Thanks
You will have to maintain your own user accounts anyway, no matter which protocol and which provider you choose. A token (or a URL in the case of OpenID) that you get from a provider is unique for a given user and you are supposed to associate it with your internal user account and recognize user by it.
If you don't want to provide any registration UI it's okay: just get the token, retrieve all the user info you need from the provider and store all this somewhere in your database. You will also have to issue and recognize your own cookie for your users, or else they'll be forced to go through provider auth every time they visit your site.
We have a website (foo.com) that does online training. A user logs in, then completes their training.
We've agreed to allow another company (bar.com) to send their clients through our training. One of the requirements is that their users should not need to create a separate login account on our site.
Here is my initial plan of attack:
When a user logs into bar.com (the other company's website), their backend will make a secure HTTPS request to foo.com (our website) requesting a one-time access token specifically for that user. For example, they may request the following URL:
https://foo.com/api/request_token.php?user=bob&pass=A1B2C3D4E5F6
This requests access to bob's account. The 'pass' component is a shared passkey known by foo.com and bar.com that is used to verify that the request is legitimate.
foo.com will respond with a one-time access token (for example, 0123456789ABCDEFG) which is stored into a database along with the user's id (bob).
bar.com will present a hyperlink to the user that links back to the online training at foo.com. Something like this:
https://foo.com/api/login.php?user=bob&token=0123456789ABCDEFG
When the user clicks on the link, foo.com checks the token in the database and (if it has not expired) removes it from the table of valid tokens and creates a session variable indicating that bob is now logged in, then redirects him to the training.
What I'd like to know is, where are the security holes and how can I mitigate them? I know that the URL will be encrypted, and I know that an entry will show up in my server log, but it's a one-time token, so I'm not worried about that. I can imagine someone brute-forcing different tokens, so I've included the user name in the second login url that the user clicks on so that the token will only work with that specific account.
But what I'm really worried about is what I don't know. And I don't understand much about the security issues here.
(Please note that this only covers an existing user who is attempting to log in. I will use another method to actually create the user account on foo.com)
I am coding in PHP.
What you're looking for is known as single-sign-on (SSO). There are a number of different industry-standard protocols for achieving this, but what you're basically doing is having another entity authenticate the user and provide that information to you in a way that you can verify that something you trust (their authentication system, whatever it is) has issued it.
The most standard way of doing this is SAML (Security Assertion Markup Language). This is a protocol where the third-party would authenticate to their system and it would generate a SAML Assertion that basically says who the user is (and other information, should that be required). The assertion is digitally signed so you can verify who issued it. This requires that you and the third-party exchange keys (in the form of certificates) and come to an understanding about what your assertions will contain, etc (typically expressed in SAML metadata that is exchanged between the Identity Provider and the Service Provider).
There are a number of SAML implementations/references out there for many platforms, including PHP. If you want to do this right, and securely, that is what you should investigate and pursue.
We are building a PHP multi-tenant application. Each company's account will run on their own subdomain abcorp.example.com. The application allows companies to write and publish content (faqs, etc) for their customers to read.
They will tell their customers to visit: abcorp.example.com/ to read the content. Or they will put a link to that URL in their secure web application.
However these companies may not want just anyone reading the content by going to abcorp.example.com/
So, the question I have is there any way to provide some basic authentication without getting into username and password authentication. I was thinking about some kind of hidden token added to the hyperlink or something like that
My goal:
If users type abcorp.example.com/ directly in the browser, they will not be able to see the web page because they didn't authenticate or pass the token in.
Avoid using username and passwords
Another option would be Referring URL Authentication
Of course, if someone makes the token public, it will open up access to whoever finds it.
I suppose each company could link to their page using a shared token, for example:
abccorp.example.com/?t=4rrfwr23rwads3
Each token could be stored in a file or a database.
When someone requests a page, it checks the value of $_GET['t'] with the one stored on the server. If it matches, it loads the rest of the page. Of course, this variable would have to be carried throughout the site, and included in every link.
Again, this will not be very secure. An exposed token could give access to the site to the entire world.
Your "hidden token" idea is essentialy the way sessions work. A session can be used to identify a user (ie. keep track of what a user does as they browse through the site), and is propagated either by passing the session ID along in links or by storing it in a cookie.
However, using a session without any other sort of authentication is inherently insecure! When you expose the way to authenticate and track users to the user itself, the user can modify or forge their authentication. For instance, the user could change the value passed along for the session ID or change the value stored in the cookie.
Please read the PHP manual section on sessions and security.
Client-side certification. Check out http://en.wikipedia.org/wiki/Mutual_authentication.
You could also use the clients IP address as a token, giving different IP addresses access to different (parts / instances) of the system. But gain, this is not very secure, as
you have no way of knowing who is behind the client PC and
IP addresses can be spoofed. Perhaps you could develop additional specs; giving IP addresses only access during office hours, or check the clients browser (user agent) and check it against the user agent officially being used at the client.
You can use basic hashing whereby a shared secret password or "key" is stored on your system and each company system (a different key for each company and not published publicly), and then you hash the secret password with the subdomain in the link and include the digest as a parameter. Then you validate it by running the same algorithm on your side and compare to the digest.
the link might look something like
abc.example.com/?d=b5939ca22f5dcf345b4000641995478c5910dbd1607b1bdadcbf4a8618a95211
where digest is:
$d = hash('sha256', $secret_password.$subdomain);
or including the referer:
$d = hash('sha256', ($secret_password.$subdomain.$_SERVER['HTTP_REFERER']));
The hurdle to get over is making sure each of the companies can support the correct generation of these links based on the company specific key/algorithm - and that it is different for each company so one company cannot produce links for another.
It is better than no authentication, or a public shared token that is not validated at all, but I'm sure it still has vulnerabilities.
Is it possible to check (using PHP or Javascript) if a user is logged into his/her account?
I need the name, email and photo.
It is not possible unless you're twitter.com, cookies are only passed to the domain they're for (or a parent domain, depending on how they're set), for security reasons.
Imagine if you could do this, do you want any web site you visiting knowing your an SO member, your gmail login, your....you see my point, it would be a huge privacy breach, as well as a security one since you could steal a user's session on many sites.
You can't do it by reading the cookies. Each cookie is tied to a domain, and can only be read from that domain.
You can, however, use Twitter's REST API to get information about a user. Combining this with OAuth should let you make sure that the user actually owns that account, and let the user log in if they need to. Refer to Twitter's documentation for details.