Vous êtes sur la page 1sur 4

T +44 1273 906 908 E hi@addedbytes.

com
Skip Navigation
Home
Work
What We Do
Our Previous Work
What Our Customers Say
Store
Blog
Latest Posts
Articles
Code
Recommended
Most Popular
Blog Writing Secure PHP, Part 1
Learn how to avoid some of the most common mistakes in PHP, and so make your sites more secure.
PHP is a very easy language to learn, and many people without any sort of background in programming learn it as a way to add interactivity to their web sites. Unfortunately, that often
means PHP programmers, especially those newer to web development, are unaware of the potential security risks their web applications can contain. Here are a few of the more common
security problems and how to avoid them.
[Writing Secure PHP is a series. Part 2, Part 3 and Part 4 are currently also available.]
Rule Number One: Never, Ever, Trust Your Users
It can never be said enough times, you should never, ever, ever trust your users to send you the data you expect. I have heard many people respond to that with something like "Oh, nobody
malicious would be interested in my site". Leaving aside that that could not be more wrong, it is not always a malicious user who can exploit a security hole - problems can just as easily
arise because of a user unintentionally doing something wrong.
So the cardinal rule of all web development, and I can't stress it enough, is: Never, Ever, Trust Your Users. Assume every single piece of data your site collects from a user contains
malicious code. Always. That includes data you think you have checked with client-side validation, for example using JavaScript. If you can manage that, you'll be off to a good start. If
PHP security is important to you, this single point is the most important to learn. Personally, I have a "PHP Security" sheet next to my desk with major points on, and this is in large bold
text, right at the top.
Global Variables
In many languages you must explicitly create a variable in order to use it. In PHP, there is an option, "register_globals", that you can set in php.ini that allows you to use global variables,
ones you do not need to explicitly create.
Consider the following code:
if ($password == "my_password") { 1.
$authorized = 1; 2.
} 3.
4.
if ($authorized == 1) { 5.
echo "Lots of important stuff."; 6.
} 7.
To many that may look fine, and in fact this exact type of code is in use all over the web. However, if a server has "register_globals" set to on, then simply adding "?authorized=1" to the
URL will give anyone free access to exactly what you do not want everyone to see. This is one of the most common PHP security problems.
Fortunately, this has a couple of possible simple solutions. The first, and perhaps the best, is to set "register_globals" to off. The second is to ensure that you only use variables that you
have explicitly set yourself. In the above example, that would mean adding "$authorized = 0;" at the beginning of the script:
$authorized = 0;
if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Lots of important stuff.";
}
Error Messages
Errors are a very useful tool for both programmer and hacker. A developer needs them in order to fix bugs. A hacker can use them to find out all sorts of information about a site, from the
directory structure of the server to database login information. If possible, it is best to turn off all error reporting in a live application. PHP can be told to do this through .htaccess or
php.ini, by setting "error_reporting" to "0". If you have a development environment, you can set a different error reporting level for that.
SQL Injection
One of PHP's greatest strengths is the ease with which it can communicate with databases, most notably MySQL. Many people make extensive use of this, and a great many sites,
including this one, rely on databases to function.
However, as you would expect, with that much power there are potentially huge security problems you can face. Fortunately, there are plenty of solutions. The most common security
hazard faced when interacting with a database is that of SQL Injection - when a user uses a security glitch to run SQL queries on your database.
Let's use a common example. Many login systems feature a line that looks a lot like this when checking the username and password entered into a form by a user against a database of
valid username and password combinations, for example to control access to an administration area:
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");
Look familiar? It may well do. And on the face of it, the above does not look like it could do much damage. But let's say for a moment that I enter the following into the "username" input
box in the form and submit it:
Writing Secure PHP, Part 1 - Web Development in Brighton - Added Bytes http://www.addedbytes.com/articles/writing-secure-php/writing-secure...
1 of 4 4/28/2014 11:06 AM
' OR 1=1 #
The query that is going to be executed will now look like this:
SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''
The hash symbol (#) tells MySQL that everything following it is a comment and to ignore it. So it will actually only execute the SQL up to that point. As 1 always equals 1, the SQL will
return all of the usernames and passwords from the database. And as the first username and password combination in most user login databases is the admin user, the person who simply
entered a few symbols in a username box is now logged in as your website administrator, with the same powers they would have if they actually knew the username and password.
With a little creativity, the above can be exploited further, allowing a user to create their own login account, read credit card numbers or even wipe a database clean.
Fortunately, this type of vulnerability is easy enough to work around. By checking for apostrophes in the items we enter into the database, and removing or neutralising them, we can
prevent anyone from running their own SQL code on our database. The function below would do the trick:
function make_safe($variable) {
$variable = mysql_real_escape_string(trim($variable));
return $variable;
}
Now, to modify our query. Instead of using _POST variables as in the query above, we now run all user data through the make_safe function, resulting in the following code:
$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");
Now, if a user entered the malicious data above, the query will look like the following, which is perfectly harmless. The following query will select from a database where the username is
equal to "\' OR 1=1 #".
SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''
Now, unless you happen to have a user with a very unusual username and a blank password, your malicious attacker will not be able to do any damage at all. It is important to check all
data passed to your database like this, however secure you think it is. HTTP Headers sent from the user can be faked. Their referral address can be faked. Their browsers User Agent string
can be faked. Do not trust a single piece of data sent by the user, though, and you will be fine.
File Manipulation
Some sites currently running on the web today have URLs that look like this:
index.php?page=contactus.html
The "index.php" file then simply includes the "contactus.html" file, and the site appears to work. However, the user can very easily change the "contactus.html" bit to anything they like.
For example, if you are using Apache's mod_auth to protect files and have saved your password in a file named ".htpasswd" (the conventional name), then if a user were to visit the
following address, the script would output your username and password:
index.php?page=.htpasswd
By changing the URL, on some systems, to reference a file on another server, they could even run PHP that they have written on your site. Scared? You should be. Fortunately, again, this
is reasonably easy to protect against. First, make sure you have correctly set "open_basedir" in your php.ini file, and have set "allow_url_fopen" to "off". That will prevent most of these
kinds of attacks by preventing the inclusion of remote files and system files. Next, if you can, check the file requested against a list of valid files. If you limit the files that can be accessed
using this script, you will save yourself a lot of aggravation later.
Using Defaults
When MySQL is installed, it uses a default username of "root" and blank password. SQL Server uses "sa" as the default user with a blank password. If someone finds the address of your
database server and wants to try to log in, these are the first combinations they will try. If you have not set a different password (and ideally username as well) than the default, then you
may well wake up one morning to find your database has been wiped and all your customers' credit card numbers stolen. The same applies to all software you use - if software comes with
default username or password, change them.
Leaving Installation Files Online
Many PHP programs come with installation files. Many of these are self-deleting once run, and many applications will refuse to run until you delete the installation files. Many however,
will not pay the blindest bit of attention if the install files are still online. If they are still online, they may still be usable, and someone may be able to use them to overwrite your entire site.
Predictability
Let us imagine for a second that your site has attracted the attention of a Bad Person. This Bad Person wants to break in to your administration area, and change all of your product
descriptions to "This Product Sucks". I would hazard a guess that their first step will be to go to http://www.yoursite.com/admin/ - just in case it exists. Placing your sensitive files and
folders somewhere predictable like that makes life for potential hackers that little bit easier.
With this in mind, make sure you name your sensitive files and folders so that they are tough to guess. Placing your admin area at http://www.yoursite.com/jsfh8sfsifuhsi8392/ might make
it harder to just type in quickly, but it adds an extra layer of security to your site. Pick something memorable by all means if you need an address you can remember quickly, but don't pick
"admin" or "administration" (or your username or password). Pick something unusual.
The same applies to usernames and passwords. If you have an admin area, do not use "admin" as the username and "password" as the password. Pick something unusual, ideally with both
letters and numbers (some hackers use something called a "dictionary attack", trying every word in a dictionary as a password until they find a word that works - adding a couple of digits
to the end of a password renders this type of attack useless). It is also wise to change your password fairly regularly (every month or two).
Finally, make sure that your error messages give nothing away. If your admin area gives an error message saying "Unknown Username" when a bad username is entered and "Wrong
Password" when the wrong password is entered, a malicious user will know when they've managed to guess a valid username. Using a generic "Login Error" error message for both of the
above means that a malicious user will have no idea if it is the username or password he has entered that is wrong.
Finally, Be Completely and Utterly Paranoid
If you assume your site will never come under attack, or face any problems of any sort, then when something eventually does go wrong, you will be in massive amounts of trouble. If, on
the other hand, you assume every single visitor to your site is out to get you and you are permanently at war, you will help yourself to keep your site secure, and be prepared in case things
should go wrong.
Ready for more? Try Writing Secure PHP, Part 2.
Writing Secure PHP, Part 1 - Web Development in Brighton - Added Bytes http://www.addedbytes.com/articles/writing-secure-php/writing-secure...
2 of 4 4/28/2014 11:06 AM
112 Comments

P(00)
Dump mysql_* functions and use mysqli or PDO with parameterized quieries, this will greatly
reduce the chance of errors.



jessica joselin
great work man. you clearly pictures the how to write secure php code. nice effort. keep it up



caballero619
Nice article about web security.
Keep it up.
Many of the web developers should be aware of this.


Mueez
awesome man, thank you for listing the fundamental loop holes we always missed in our
programming.



Chad Buie
Awesome tips, guess I have a lot of stuff to learn, but learning security is probably the best
place to start for application development. Thx!



Mohammad
Very nice articles... Thank you



sufalam
On the contrary, theres plenty of code out there that is frightening because it is so large and
overly-complex, that it takes a genius to figure out what is going on, let alone make sure its
secure. I rewrote one of Paypals checkout integration scripts a few months ago. Theirs was
roughly 190,000 lines of code. I accomplished the same thing, even adding features, and it
was about 500 lines when finished. There is definitely extremes in either direction.




Thanks alot, very good article



Sheshachaliah
Great! Good effort. More helpful!



Luke Pollard
Huge thankyou for this article, I have done lots of php coding before on sites.. however i'm
building an administration site now heavily using mysql, and this has been a huge help in
securing data against the world. My war on malicious hackers has begun :D !!



shu long
thanks a lot. I am a newbie in php and these security measures you wrote has indeed
enlightened and helped me.



Puneet
You saved my life by helping me out with passing variables (especially page url) in the url by
GET.



Ron
This is a very useful article as I am new to PHP and MySql. I will have to find more time to
finish rest of the series.
Thanks a lot for these great tips!



Mike
The password checking tool john (aka John the ripper) will also brute force passwords, so in
addition to not using dictionary words, and common substitutions, you should also pick a
longer password. Keep your system upto date and make sure that ALL the passwords on the
system are secure. An service account such as nagios with a default password of nagios, can
give a user access to your machine to gather more information, and launch attacks from
within your firewall.


Janice McConnell


Writing Secure PHP, Part 1 - Web Development in Brighton - Added Bytes http://www.addedbytes.com/articles/writing-secure-php/writing-secure...
3 of 4 4/28/2014 11:06 AM
2003 2014 Added Bytes Ltd (Company 8026399) Creative Commons License | Privacy Policy | Tags | Site Map
Writing Secure PHP, Part 1, by Dave Child, was posted on 16 July 2004 and has been tagged with code, coding, development, mysql, php, programming, security, tips, tutorial, web,
webdesign and webdev.
Thoughts from a Brighton geek about web development, marketing, freelancing, entrepreneurship and fatherhood. Probably not in that order.
Feeds
RSS (Full)
RSS (Partial)
More Feeds
Newsletter
Name
Email
Topics
PHP
E-commerce
Security
Online Marketing
Freelancing
For Beginners
More
Latest Posts
Articles
Code
Recommended
Most Popular
Hi! I'm Dave and I'm a freelance PHP developer from Brighton, UK. I build awesome e-commerce and CMS websites using platforms like Magento, MODX, Drupal and OpenCart.
I'm available for projects starting in June.
Check out my Services and Portfolio or get in touch!
Services
Website Development
- Magento Website Development
- MODX Website Development
- OpenCart Website Development
- TomatoCart Website Development
- Wordpress Website Development
- Drupal Website Development
- Bespoke Website Development
Online Marketing
- Search Engine Optimisation
- Social Media Marketing
Magento Extensions
- Store Locator for Magento
- Discontinued Products for Magento
- Mass Redirect for Magento
Quick Links
- Blog
- Cheat Sheets
Contact Added Bytes
Phone: +44 (0) 1273 906908
Twitter: @AddedBytes
Email: hi@addedbytes.com
Writing Secure PHP, Part 1 - Web Development in Brighton - Added Bytes http://www.addedbytes.com/articles/writing-secure-php/writing-secure...
4 of 4 4/28/2014 11:06 AM

Vous aimerez peut-être aussi