I was thinking of writing my own authentication script but I don't know much about security.
From the articles I've reading, it looks like it usually involves hashing the password with a salt and storing it in the database. Then when user requests to log in, password is hashed and compared with the database. If it matches, then the user's data is stored in $_SESSION.
However, I don't know if this is secure or not. I read something about storing session keys in the database but I'm not sure about how that works, or how to implement that.
Can someone explain how to implement secure authentication?
Also, are there any suggestions for PHP authentication libraries I can incorporate that are easy to learn instead of writing my own?
Check this answer here.
Although the answer is 3 years old, the suggested phpass library is up to date.
Also, +1 to Aron Cederholm. Password security is an extensive subject and you should look first at the related questions already discussed here on StackOverflow so you will be more familiar with the subject and best practices in security.
Although I like frameworks (Symfony, Zend, etc) as they generally implement these good practices, just using them don't make you a good programmer. You have to learn its inner workings. I always salute a programmer dwelving into coding his own secure authentication mechanism (as long as they don't implement it in a live site that really needs strong security), because that's the best way to learn and understand the inners of the subject. Always start from an existing implementation, and THEN use that as an example for creating your own codebase.
Things to keep in mind:
Authentication; verifying the user is who they say they are.
Authorization; ensuring the user is allowed to do what they are trying to.
Accounting; recording and auditing what they do.
For authentication, you'll need to track "users" connected to and (often) authenticated with the system. This requires knowing an identifier (a username, email, or some other unique token) and a pass-phrase. Store the username and pass-phrase somewhere, but never store the pass-phrase without securing it first: don't use a message digest algorithm (like MD5 or SHA1) with a salt. Use bcrypt instead. Although it's not a bad idea to use a framework here, do not always rely on a framework to do the right thing.
For authorization, you'll need to track what actions the user is taking and perform permission checks to see if they are allowed to do the action they are attempting. This can be accomplished in a number of different ways and all of them are domain specific -- you won't often find a cut-n-dried example of it, though you can find lots of frameworks to help you.
For accounting, you need to record what actions the user does. This is the most often neglected part of any application, but when bad things happen, it's utterly crucial knowledge to have and reconstructing it from web server access logs is a nightmare. Again, this is domain specific but a good framework should ease the implementation of it.
Lastly, tying all three of these together is your user's session. When you call 'session_start()' in PHP, it sends a session identifier as a cookie to the client and stores a file to the server's hard drive containing the contents of $_SESSION for that user. You can also configure PHP to override the default functionality and save session data using session_set_save_handler. You can then store that information to the database.
TL;DR: Use a framework like CodeIgniter, Drupal, Yii or some other actively developed solution. The vast majority of frameworks out there will do just about anything you need them to, and if they don't, they can be modified very easily. Don't create your own framework for this; use one that is already available.
I use tank_auth (a Codeigniter plugin) which is pretty good. The source code is a good reference for how to implement secure login.
Related
I am working on an Android app that deals with some slightly sensitive information (Names, Usernames, Passwords, Badge number, etc)... As far as code work goes, I know how to connect to a MySQL database with PHP and pull information from it via JSON. I am just worried about the security of doing this. I know there are plenty of Android and iPhone apps that currently implement login systems, but I was curious as to how secure those logins are.
Does anyone know where I can find some information on creating a secure connection to a database with PHP and MySQL for my login system through an Android app? I know nothing is completely impenetrable, but I want to make sure the security of my app is as tight as possible.
As always, I am still getting used to StackOverflow, so if I was not clear or this question has already been answered, let me know!
If you're rolling your own authentication code, it's really hard to say how secure it is. Often people get this horribly wrong and the code has the opposite effect: Instead of securing the site it exposes several severe holes that can be used to hijack it and download arbitrary data.
A development framework like Laravel comes with an authentication system built-in. If there's vulnerabilities in that code, which is reviewed by the community, there's usually an advisory posted so you'll know and can patch as necessary.
If you follow best practices, you should be fine. JSON via PHP or any other language is a good way to go if you want to keep things simple and secure.
Its really hard to gain 100% , but you can use some techniques like
SSL
Session for each user
something like verification code sent through SMS
Encryption data before sent over API calls etc
It is incredibly insecure to connect to a remote db from an app. Think of it like connecting to a database from javascript in your browser, because it is the same level of security.
As an important aside,
slightly sensitive information (Names, Usernames, Passwords, Badge number, etc).
Passwords are not slightly sensitive, they are critically sensitive. I'm not sure if you are implying that passwords are being stored in a reversible format, but they should be hashed.
Anyway, to your main question, instead of connecting directly to a database from the client-side device, you will want to create an API that provides limited access. You would write this in the form of a web service, using some server-side programming. From there, you'll simply use an API key/roles based on the current logged in user. This is the secure/proper way to design this system. You do not want to put db credentials in an app, unless they are for a local db on the phone.
To extend what Gray said, you can pass the JSON data through the URL that you're shipping to the web service that's providing the front end to your DB. There are a couple of other examples that you can find here to start. As pointed out, it's a really bad idea to have direct DB access. Even with a front end, you'll want to ensure that you're doing lots of data checking in the front end. Don't pass direct SQL queries! They're too easy to hack. SQL injection continues to be one of the most successful attacker techniques.
You might consider a Mobile Backend as a Service provider, like Kii, Kumulos, Kinvey, Kony (not sure why they all start with K...), or built.io. They'll cost you money, but save you headaches.
Question
Is this post on WikiHow a good reference to create a secure login script in PHP and MySQL? In the warnings section, the author(s) emphasizes that the code only can be used with HTTPS. I am not able to use HTTPS, but need to implement a relatively secure login script in PHP and MySQL, and was therefore wondering if the script could be implemented for an HTTP connection as well.
Solved
A third party solution is the best solution to create a secure login script in PHP and MySQL. By utilizing a PHP framework (e.g. Symfony, uLogin) or external parties (e.g. Facebook, Google), the need to create an entirely new working login script plus authorization (the Remember-Me functionality) can be avoided. If others have done thorough research and gained experience to create login functionalities, it is much safer and easier to use their work.
Although you could create a login system yourself, it is strongly recommended to let external parties do it for you.
It takes a lot of experience to get it right, and it is so often done wrong.
Although the tutorial looks okay to me, there are just so many factors that to consider, and it also seems to be semi-old. PHP 5.5 offers password_hash and password_verify, which I would recommend over what your page suggests.
So if you have to make your own system; consider making use of the above-mentioned functions, if you're restricted to lower php versions, there are backports up to version 5.3.7 available.
If you don't have to make your own system, make use of external parties (Google, Facebook) to handle the logging in for you, or make use of a framework that has authentication support.
So in the general gist of it: Don't try to do it yourself, make use of what other people offer which years of experience in it. As it is incredibly difficult to get it right.
This script securely encrypts the user's entered password in their browser and clears the plaintext password field prior to the form's submission, so the password can't be read by any third-party. To that extent, the script can be used safely over HTTP.
However, the rest of the form's data - user's name, email address, etc. - is not sent securely, so a third-party (e.g. man in the middle) could identify the user just by reading his/her (non-encrypted) personally-identifiable information being sent by the form. Not only does this leave your users vulnerable, but insecure handling of users data can leave your employer/client open to legal risk in case the data is ever sniffed/hacked/stolen.
There's also the real risk that a man-in-the-middle could intercept the transmitted data and modify it undetected before it's received by the server hosting your script. HTTPS/SSL not only protects passwords but also ensures that no data is tampered with.
As Zarthus mentioned, best course of action is to go with a third-party solution, especially if you can't offer HTTPS for yours.
I'm trying to think out my user authentication system for a site in development and have read many of the posts on stack overflow and elsewhere to get my head around this. I found a couple of options I was wondering if this one looks like a decent starting point:
http://php.about.com/od/finishedphp1/ss/php_login_code_6.htm
It appears to encrypt the passwords and avoid some of the obvious pitfalls.
Also, perhaps a silly question, but I want to use the authentication for 2 reasons:
1. To provide the user with some extra functionality on an otherwise public page. (Think "Hello [username]" at the top of the page).
2. Provide user access to private pages also.
These 2 types of applications (login = added stuff on public page versus login=access to private page) are reliant on the same authentication, right?
In other words, whether I wanted to do one or the other or both shouldnt' impact how I think about authentication, correct?
Please let me know if I'm asking for trouble by using an about.com tutorial for this....
Thanks in advance.
FOLLOW UP EDIT:
Ok, so the about.com tutorial has some holes. I found a more complete system below that appears to use SHA1 encryption instead. This also has an email verification for new users and some other nice functionality. At first glance, does this seem like a solid route to take?
http://www.unlimitedtree.com/topic/1503-tutadvanced-login-member-system-php-tutorial/
Yes, you are asking for trouble. There are several reasons why I would avoid the about.com approach:
User name and password are stored on the client side. You'll never want to do that. First: if a malicious attacker gets access to the cookie, he can use the id and password hash to take over the account. Second: there are huge data sets out in the wild called rainbow tables which allow malicious attackers to find out which string (= password) results in the given hash. This means that if you don't have a long/complicated password, someone may use the rainbow tables to get you clear text password and try it on this and other websites you are registered to.
The variable $username is used unchecked and unfiltered. Hello SQL Injection.
The password is encrypted using a simple md5() function. MD5 puts you at the risk of hash collisions. Nowadays you should use better hash functions like SHA-1 and use salt.
Security is a complex topic. I recommend you to use well tested authentication and authorization solutions as provided by established frameworks. Also think about OpenID.
A few PHP frameworks and their auth components:
Apache Zeta Components (former eZ Components): Authentication
CakePHP: Authentication and Authorization
FLOW3: Security (Authentication and Authorization)
Symfony: Security (Authentication and Authorization)
Zend Framework: Zend_Auth and Zend_Acl
Concerning your question:
In other words, whether I wanted to do one or the other or both shouldnt' impact how I think about authentication, correct?
Yes. You have to differentiate between Authentication and Authorization. The former helps you to identify who the user is and the latter helps you to find out what the user is allowed to do. Read this short introduction to learn about the topic.
I'm looking to implement user login onto my site for the first time. I'm happy to either build my own solution, or implement something open source, however no package has been an obvious choice in my search so far. Equally, I'm fully aware that as an intermediate php programmer at best, I am highly likely to miss something obvious if I roll my own solution, and leave the doors well and truly open.
Any suggestions? We're not talking super sensitive or payment data here, but equally, I'm keen not to have people mess up my site!
requirements are
- php based
- simple as possible, not need for fancy bells and whistles
- not Zend framework, since i've now rolled my own very basic frameworkthanks to this post
Thanks for your input.
A few good security gotcha's are
never store the an un-encrypted users password in the database
never store the users password or even a hash of the password in session or cookie data.
If you need to have ensure that the login is secure you have to use https.
I found these article very helpful in building login systems with cookies:
blog post on the fishbowl.
Improved Persistent Login Cookie Best Practice
"You'll put your eye out kid."
Security is hard. I hate to say this, but the odds of you making a simple authorization scheme that is secure are quite slim. There is no easy mode here. So you might want to start by reading through a bunch of authentication code in the various frameworks/cmses, and other places where you can see how others have done it, and begin researching.
Here are some links:
http://www.topmost.se/personal/articles/casual-cryptography-for-web-developers.htm
http://pear.php.net/packages.php?catpid=1
I find that for some uses, building my own using http authentication is sufficient. I'd recommend this as a starting point.
Since you have your own basic framework, it should not be too difficult to include the authentication code in some place that is common.
Some advantages are
Not a lot of code.
Does not require
cookies or URL rewriting.
Disadvantages
Doesn't scale well to more granular
access control.
No easy way to "log
out".
--
bmb
This is not that hard, and fun to code, as a beginner.
You need a place to store your data (let's say a mysql database).
You should at least have a login field, and a password field. (the password should be stored crypter using sha1() for instance).
Now, you have to display a login form. I assume this is ok for you.
What is to be done, whenever we get the login and the password?
Query the database to see wether there is a match with login_base == login_form and password_base == sha1(password_form).
If yes, you set something, like a session for instance.
So on a page where one should be logged, you only have to check if there is a session set.
This is for the basis; then you can add some levels and so on.
I understand the mantra of "don't roll your own" when it comes to site security frameworks.
For most cases anyway.
I'm going to be collaborating on a site that integrates text-messaging into the system.
I'd like to use an existing, well-tested security framework to protect the users data, but I need it to also protect a users phone number as well.
I wouldn't want to be the one responsible for a list of users cell phone numbers getting jacked and spammed.
What suggestions can the community offer?
Note that techniques applied to passwords aren't applicable here. You can store a password salted and hashed (although the value of doing so can be disputed), but that doesn't work for phone numbers.
If someone jacks your server, they can do anything the server can. This must include recovering the phone number, but doesn't include recovering the password if it's hashed well. So the phone number is just a particular case of protecting confidential data.
If phone nos truly are the only sensitive data in the app, then you could look at walling off the part of the app that sends the texts, and asymmetrically encrypting the phone nos. In a different process (or on a different machine) run an app that has the key to decrypt phone nos. This app's interface would have maybe one function taking an encrypted no and the message to send. Keep this app simple, and test and audit the snot out of it. Either hide it from the outside world, or use authentication to prove the request really came from your main app, or both.
Neither the db nor the main part of the app is capable of decrypting phone nos (so for example you can't search on them), but they can encrypt them for addition to the db.
The general technique is called "Privilege separation", the above is just one example.
Note that phone nos would generally need to be padded with random data before encryption (like salting a hashed password). Otherwise it's possible to answer the question "is the encrypted phone number X?", without knowing the private key. That may not be a problem from the POV of spammers stealing your distribution list, but it is a problem from the POV of claiming that your phone numbers are securely stored, since it means a brute force attack becomes feasible: there are only a few billion phone nos, and it may be possible to narrow that down massively for a given user.
Sorry this doesn't directly answer your question: I don't know whether there's a PHP framework which will help implement privilege separation.
[Edit to add: in fact, it occurs to me that under the heading of 'keep the privileged app simple', you might not want to use a framework at all. It sort of depends whether you think you're more or less likely leave bugs in the small amount of code you really need, than the framework authors are to have left bugs in the much larger (but more widely used) amount of code they've written. But that's a huge over-simplification.]
Since you need to be able to retrieve the phone numbers, the only thing you can really do to protect them (beyond the normal things you would do to protecting your db) is encrypt them. This means that you need to:
Make sure the key doesn't leak when you inadvertently leak a database dump.
Make sure your system doesn't helpfully decrypt the phone numbers when someone manages to SQL inject your system.
Of course the recommendation of not rolling your own still applies, use AES or some other well respected cipher with a reasonable key length.
I’m pleased to announce the release of hole-security system for PHP
This project stands for bring to PHP the kind of security that is provided in Java by Spring Security the formerly Acegi Security System for Spring. It’s designed to be attractive to Spring Security users because the philosophy is the same. It’s an unobtrusive way to add security to a PHP site. The configuration is made using substrate IoC/DI as Spring Security use Spring IoC/DI.
An example configuration ship with the framework and can be used like this:
$context = new substrate_Context(
'./path/to/hole-security/hole-security-config.php'
);
$context->execute();
$hole_Security = $context->get('hole_FilterChainProxy' );
$hole_Security->doFilter();
Just be sure that the bootstrap code of the framework is executed before the bootstrap of the MVC of your choice.
WebSite:
http://code.google.com/p/hole-security/
Documentation:
For the moment you can use reference documentation of Spring Security where it’s apply. You can get a general idea using the Acegi Security reference documentation because hole-security use the same way of configuration, but keep in mind that it’s based on Spring Security.
License:
It’s released under Apache License Version 2.0.
Features:
hole-security brings an pluggable security system where you can adopt the security requirement of your environment. Currently there is a very simple security system because it’s on the first release but with the base foundation that it brings you could suggest or request for new features to be added to the project.
Currently Features:
In memory dao authentication as a proof of concept, you can switch to your preferred dao or implementation that get’s user data from database or wherever you store it. In futures release an PDO based implementation will be created.
Configured filters for be applied to url patterns. Url path matcher can be plugged to, currently it ship with a ant styles path matcher.
Authorization Manager can be used in your application to decide wherever or not do something, always obtaining the reference from the substrate context.
Shared Security Context accessible from any code of your application if hole_HttpSessionContextIntegrationFilter is applied. You can use this context to save information related to the session without use the session object directly.
You can use a custom login page and customize it according to the hole_AuthenticationProcessingFilter configuration, or customize hole_AuthenticationProcessingFilter according to your custom login page.
The default password encoder is plain text, without encoding. Futures releases will have implementations for MD5, Sha based, Base64 and others related encoding. You can create your own password encoder and get configured.
All the objects are loaded as required, if something like a filter it’s not used for a request would not be loaded. This increase the performance of the application
There are others features related that hole-security have.