0% found this document useful (0 votes)
18 views

writing_secure_php

Uploaded by

baltamassae
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

writing_secure_php

Uploaded by

baltamassae
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 29

Writing Secure PHP

Applications

How things can go wrong?


How to prevent the disaster?
Never, ever, trust user inputs
Input Validation
Always use server side validation as client
side (javascript) validation can easily be
bypassed
Use white-listed values
Use built-in escape functions
Validate for correct data types, like
numbers
Don’t expect the return value from
selections, radio buttons or check boxes of
a form to be the ones you mentioned. So,
always revalidate.
PHP Error Messages
Great tool for both developer and hacker.
Can reveal server software and directory
structure, even database login information.
Need to set error_reporting to 0 using php.ini
or .htaccess file in production server.
Should have separate .htaccess files for
development and production servers.
Use proper error handlers when necessary
(instead of just showing the error message
and die()ing )
Further Reading :
http://perishablepress.com/press/2008/01/14/
advanced-php-error-handling-via-htaccess/
Bad Features of PHP
Register Globals
 Consider the following code -

test.php

if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Lots of important stuff.";
}

 test.php?authorized=1 will produce “Lots of important stuff.”

 To disable register_globals using .htaccess file –


php_flag register_globals 0

 To disable register_globals using php.ini –


register_globals = Off
Bad Features of PHP
Magic Quotes
Originally introduced to save programmers the
trouble of using addslashes()
Major problems associated with it is –
a. When both magic quotes and addslashes() are
used, you end up with multiple slashes being
added, causing errors
b. If you think magic quotes is turned on, but
actually it is not, then inputs go unchecked.
c. It only escapes double and single quote, but
there are other database-specific characters
that need to be escaped
Bad Features of PHP
Magic Quotes

Disabling using .htaccess –


php_flag magic_quotes_gpc 0
php_flag magic_quotes_runtime 0

Disabling using php.ini –


magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
SQL Injection
 Most common and most destructive security hazard
 Lets see the common way to check username and password
entered into a form –
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users
WHERE Username = '".$_POST['username']."' and Password = '".
$_POST['password']."'");
 If we enter the following in the “username” input box and
submit -
' 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 = ''
 As you can see, this query will return all the users from the
database and as generally first user on a user table is the
admin, the hacker will easily gain admin privilege.
 We need to either use mysql_real_escape_string() on all
database inputs (not just on string types) or use mysqli
extension.
File Manipulation
 Some sites currently running on the web today
have URLs that look like this:
index.php?page=contactus.html
 The user can very easily change the
"contactus.html" bit to anything they like. For
example,
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.
 When users download a file from your server, if the
file name depends on user input, he can easily
manipulate it to download system files by giving
inputs like – “../../../etc/passwd”
File Manipulation
 To prevent remote and system files inclusion,
make these changes in your php.ini file –
1. Correctly set “open_basedir”
2. Set “allow_url_fopen” to Off

 Always validate file names to make sure only


valid characters are included –
function isValidFileName($file) {
/* don't allow .. and allow any "word" character */
return preg_match('/^(((?:\.)(?!\.))|\w)+$/',
$file);
}

 Use database and hidden, generated file


names if possible for file downloads.
Using Defaults
MySQL uses default username of “root” and blank
password
SQL Server uses “sa” as default user with a blank
password
Hackers will first try to use the default username,
password combination everywhere – be it a MySQL
server or CMS like Wordpress, Joomla or Drupal.
Make sure first thing you do after installing any
software on server is to change default username,
passwords.
Also, create separate users other than “root” with
appropriate permissions on MySQL.
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
If a hacker wants to gain admin access of your
site, first location they will try to look into may
be - http://www.yoursite.com/admin/
Make sure your admin area is not predictable.
Use something like –
http://www.yoursite.com/jsfh8sfsifuhsi8392/
Same goes with username and password. Don’t
use an username ‘admin’ or ‘administrator’.
Pick something unusual
Use a combination of lower and upper case
letters along with digits to prevent dictionary
attack.
File Systems
Always disable directory listing by placing a
‘index.html’ file in every folder. You can also
disable by using .htaccess or httpd.conf file, but
using ‘index.html’ will make sure you’re protected
even if your server settings are changed.
Don’t place common files in a directory like
‘www.mywebsite.com/includes/’. Use something
out of web root for that and give it an unusual
name.
Don’t give a file the extension ‘.inc’ as it is usually
rendered as text and can reveal the whole source
code (and maybe database login information too).
If you must use ‘.inc’, use ‘.inc.php’ instead as it
will be rendered as php file.
Session Hijacking
By default, session information in PHP is written
to a temporary directory. The file itself contains
the information in a fairly readable format.
As the file has to be readable and writable by
the Web server user, the session files can
create a major problem for anyone on a shared
server. Someone other than you can write a
script that reads these files so they can try to
get values out of the session.
Encrypt everything that you put into session. It
is not completely safe though.
Store session data in a different place, like a
database.
Storing Passwords
Do not store password as plain text
Do not try to invent your own password security
Do not encrypt passwords as they are
reversible. Security through obscurity is not
sufficient.
Do not use MD5 – though this cryptographic
hashing function is irreversible , it is quite easy
to make a list of millions of hashed passwords
(a rainbow table) and compare the hashes to
find the original passwords. MD5 is also prone
to brute forcing (trying out all combinations
with an automated script) because of collisions.
Storing Passwords
 Do not use a single site-wide salt. A salt is a string
that is hashed together with a password so that
most rainbow tables (or dictionary attacks)
won’t work.
$password = 'swordfish';
$salt = 'something random';
$hash = md5($salt . $password);//Value: db4968a3db5f6ed2f60073c747bb4fb5
 Use a cryptographically strong hashing function like
SHA-1 or even SHA-256 (using PHP’s hash()
function).
 Use a long and random salt for each password.
 Use a slow hashing algorithm to make brute force
attacks near impossible.
 Regenerate the hash every time a users logs in.
Storing Passwords
Code to create the hash and salt
$username = 'Admin';
$password = 'gf45_gdf#4hg';
// Create a 256 bit (64 characters) long random salt
// Let's add 'something random' and the username
// to the salt as well for added security
$salt = hash('sha256', uniqid(mt_rand(), true) .
'something random' . strtolower($username));
// Prefix the password with the salt
$hash = $salt . $password;
// Hash the salted password a bunch of times
for ( $i = 0; $i < 100000; $i ++ ) { $hash =
hash('sha256', $hash); }
// Prefix the hash with the salt so we can find it back
later
$hash = $salt . $hash;
Storing Passwords
 Code to validate password

$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

You might also like