Hello friends, I have built simple PHP application by looking at various articles and tutorials around the web. Since I am now giving it to a few clients, I am worried about its security. How do I make sure it doesn't get hacked?
The most important thing when developing a web application is to treat user input like the plague. It is evil, and cannot be trusted!
Any time you are working with a variable that can be possibly modified (such as POST, GET, or other variable) by the client / user, then it needs to be sanitized. Remove any excess cruft that is not part the input you are expecting.
For example, if you have the following code:
$var = $_POST['myNumber'];
echo 'You entered the number ' . $var . '!';
This code is vulnerable to attack - you would want to sanitize the POST variable here:
$cleanVar = sanitize($_POST['myNumber']);
echo 'You entered the number ' . $cleanVar. '!';
Where sanitize(string)
is a function to remove excess quotes, and things like that. You could conceivably pass a second parameter in, to correctly filter the types of content you'd expect. For example, tell your sanitize function to strip crap in a certain way for numbers, and in another way for strings.
If you're talking just from the perspective of making your code secure, there are some things you should be aware of (this is an incomplete list but should get you started):
SQL Injection
If you have any SQL queries in your application and any of them use input from the user, you could be vulnerable to SQL Injection. This is when the user submits something malicious in the place of a form field, which, when inserted into your query, will give the attacker the ability to access other parts of your database.
How to prevent: any input you get from the user needs to be sanitized before you use it in a query. In order to do so, you can use prepared (or parameterized) statements (ie. mysqli::prepare
or PDO) or use a function that properly escapes your input values before you use them in your queries (ie. mysql_real_escape_string
)
Cross-site scripting (XSS) attacks
If you take any input from the user and output it in another page (for instance, you might collect user data and then output a list of users), you could be vulnerable to an XSS attack. The way these work is by adding code (generally <script>
tags) into form fields, and if they are not sanitized before being output, the attacker will have added their own Javascript into your page, which will run in the context of your page (and therefore, have access to things like your cookies).
How to prevent: Unless there is a good reason to be letting your users output HTML, every time you output something that comes from the user, it should be sanitized with htmlspecialchars, which will turn potentially dangerous characters (<
and >
for instance) into HTML entities. If you must let your user output HTML, you should have a specific set of tags that are allowed and ensure that only those tags are allowed through (using a DOM parser or strip_tags
for example).
See also: The Cross-Site Scripting (XSS) FAQ
Cross-site request forgery (CSRF) attacks
This is an attack where an attacker tricks a user's browser into making a request on its own (for instance, by injecting code into your site, though the attack can actually originate from anywhere) that takes advantage of authentication cookies stored in the user's browser. For example, let's say you had created a banking application, an attacker could cause a legitimate user who still has an active authentication cookie for your site to request http://yourapp.com/transfer_funds.php?to=attacker
, without knowing it.
How to prevent: GET
requests should be idempotent (that is, should always have the same effect, or should not cause your application state to change). That means that any operations that the user can do (for example, CRUD operations) should be made through POST
, not GET
. Similarly, you should check $_POST
, and not $_REQUEST
for these operations, because $_REQUEST
will contain values from both $_POST
and $_GET
.
However, your application can still be vulnerable to CSRF even if you're using POST. In order to protect better, many people use a system of challenge tokens, where the application generates a random string that is related to the user session. This challenge token is passed along with any relevant requests the application itself makes (by including it in the form) and then is verified before any operation is allowed to take place. Note that if your application has an XSS vulnerability, your challenge token can be compromised.
See also: The Cross-Site Request Forgery (CSRF/XSRF) FAQ
Exploiting eval
or system commands
If you use eval
along with user input, you are opening up your entire application environment (and beyond that, your server environment) to a potential attack, because if you aren't extremely careful (and even if you are), you are giving users the ability to run whatever arbitrary code they want. This could result in anything from modifying your database, changing your server environment, installing and running scripts or binaries on the server, deleting your PHP files... (this same sort of attack applies to any PHP function that makes a system call, including system
, fopen
, any of the functions that access the filesystem...so be very careful when you use user input!)
How to prevent: Do not use eval
with user input. If you think you need to use eval
with user input, there probably is a better (and safer) way to solve the problem.
For web application security, you really can't miss the OWASP. It consists of a group of security guru focusing on web application security and have regular updates on related resources.
The most famous one is the OWASP Top 10 (latest version 2010) which summarized the top 10 security risks commonly encountered by web applications. This has become de facto references when people are trying to assess the security level of a web application during penetration tests or code review.
For developers, you might also be increased in their development guide, which contains some DO's and DON'Ts when you write you codes.
Besides, the {ISC}^2 also has some good reference in this topic. I would recommend the one about how to integrate security into your software development life cycle (SDLC). You might also want to read the Web application security 101 presentation slides.
my functions of choice for cleaning up user input are
$input = mysql_real_escape_string($input);<br>
$input = trim($input);<br>
$input = strip_tags($input);<br>
$input = htmlspecialchars($input);
and then if I want to disallow certain characters then I just do the following.
$nono = array("=", "{", "}", ";", "[", "]","$","&");<br>
$input = str_replace($nono, "", $input);