Ok forget what you may have already learnt. I will be showing you the do's and dont's of php security. This is from my vast experiance of making unsecure scripts so i know what i am on about.
Before i start, i have to say that the if statements i use may look different to what you guys are used to. Do not worry, they are perfectly valid php statements.
Examples:
| PHP Code |
|---|
<?php
if ()
{
}
if ()
{
}
else
{
}
if ()
{
}
else
if ()
{
}
else
{
}
?>
|
| Select all |
can also be:
| PHP Code |
|---|
<?php
if ():
endif;
if ():
else:
endif;
if ():
elseif ():
else:
endif;
?>
|
| Select all |
I use this because i think it looks cleaner. Personal preference no performance gains that i know about.
So you may have heard this term thrown about in many tutorials. If it is enabled, it automatically adds slashes to any post, get, cookie input. This can be annoying because if you use add slashes and the server has magic quotes enabled then your input will be slashed twice. Not what we want.
How to check for magic quotes. Here is a simple if statement that shows how to check if magic quotes are enabled.
| PHP Code |
|---|
<?php
if (!get_magic_quotes_gpc()):
// code here
else:
// code here
endif;
?>
|
| Select all |
On a side note, magic quotes will be disabled by default in php 6. Im not sure if it is disabled in php 5.3.
This part of the tutorial will show you how to make strings took from post, get, cookie to be safe for database insertion.
| PHP Code |
|---|
<?php
$input = $_POST['text']; // You can use post, get, cookie or anything you like.
if (!get_magic_quotes_gpc()): // Checks if magic quotes is on or not
$input = addslashes($input); // If its not on, add slashes
endif;
$query = mysql_query("INSERT ... {$input} ... ;"); // A query lol
?>
|
| Select all |
Its as simple as that. $input is now safe to insert into a database.
This is really simple and i only included it because... well i have no reason. This code assumes u put data into the database using the above code.
| PHP Code |
|---|
<?php
$query = mysql_query("SELECT ... FROM ... LIMIT ... ;");
while ($result = mysql_fetch_assoc($query)):
echo stripslashes($result['column']);
endwhile;
?>
|
| Select all |
Easy huh?
This here is the reason why i dont register to alot of sites that seem to have "noob" php coding. This is because i dont feel that their passwords are secure enough. I will show you two ways to encrypt a password. The first uses two well known php functions, the second is a function that i made a while back.
| PHP Code |
|---|
<?php
$password = $_POST['password'];
if (get_magic_quotes_gpc()): // Checks to see if magic quotes is enabled
$password = stripslashes($password); // If it is, strip the slashes it added.
endif;
/* Ok you may be wondering why i done that check when the text is going to be encrypted anyway.
Well this is because some servers have magic quotes enabled and some dont. Lets say you didnt
use that if statement and u had people with passwords that have quotes. The password will be
encrypted without the magic quotes effect. Now imagine you got a new host this time with magic
quotes enabled. Because u encrypted the passwords without magic quotes and the new server has
it enabled, when someone with quotes in their password goes to log in, the hashes wont match. */
// The first encryption way
$password = sha1(md5($password));
/* This is very simple. It md5 then sha1s the password. Very effective at hashing. But what
if you are extra paranoid? If someone gets their hands on your hash, if they are smart they
will know its a sha hash. Theoretically once they crack it, they just have to crack the md5 hash
afterwards and theres your password (i said theoretically, this would take years to crack even
with supercomputers) */
// The second encryption way (for the paranoid, like me)
// First we define my hashing function "Xel"
function xel($str)
{
$str = sha1(md5($str, true)); // First returns the binary md5 of the input then sha1s it
$str = preg_replace("/([0-9])/e", "chr(97 + intval('\\1'))", $str); // Replaces all numbers with letters (0-9, a-j)
$str = str_rot13($str); // Performs a simple rot13 algorithm on it
return $str; // Returns the "Xel" hash
}
// How to use it
$password = xel($password);
/* This will return a hash that looks something like this:
uroorrnuqtpupppoprqqvsnntntnorsuvnrvnopn */
?>
|
| Select all |
Using either method will make your password safe. I prefere Xel for that added security but in reality most would see it as over kill. Use which ever method you see fit.
Chances are most of you havent used eval before. It has its uses. But... if used incorrectly, it can prove deadly if someone who knows what their doing messes with your script. For example, if you put input by a user into an eval function, be aware that if they enter something like:
?input1=exec('some deadly command to kill server');&input2=...
If input1 was to be run using eval, the exec command would be run with the command inside and boom goes your server... not literally. Ways to stop stuff like this happening, hard code eval commands and only use inputs you trust. never use user input on functions like exec, system without escaping the input with escapeshellcmd() first.
This is something i see alot of people miss out. The neglegence of defining variables first hand can be bad for your script. What i mean is, lets say you have a variable called $admin:
| PHP Code |
|---|
<?php if ($result['admin']): $admin = true; endif; // Now the admin variable only gets initiated if $result['admin'] is true (has a value other then false) // ... further along the script ... if ($admin): // do some admin stuff # endif; # /* Now this if statement will be looking for $admin. If it finds admin with the value of true then it will do some admin stuff. However, if the admin variable wasnt created, the if statement cannot find the variable so assumes it as false. So far nothing of concern right? Heres were i forget some stuff so i will try to explain what i mean: Some php installations by default create variables from $_GET and $_POST strings. What i mean is: index.php?someattr=abc&etc=etc... Once index.php is run, a variable called $someattr with the value of abc is now accessable by the script. It is also accessable by $_GET['someattr'] and $HTTP_GET_VARS['someattr'] etc... Now in our above example, the admin variable has not been created. All someone has to do is page.php?admin=true and they have admin rights because the $admin variable is created with the value of true As you can see, this can be a big problem if not protected against Stopping this is really simple, just define the admin variable */ . . . $admin = false; if ($result['admin']): $admin = true; endif; // Simple as that ?> |
| Select all |
At the top of your config file or at the top of the file you want to test. That will produce an error everytime you have not defined a variable.
I hope you have enjoyed that tutorial on php security and i hope you use some of these techniques in future programs.
<?php
$_POST = array_map('stripslashes', $_POST);
?>
etc
Discuss