PHP/DB and security

Snippets, useful things or other stuff here.

Moderators: ne_moj, zewa, vadimako, ne_moj, zewa, vadimako

zewa
Site Moderator
Site Moderator
Posts: 15
Joined: Jan 15th, '09, 06:45
Location: Graz - Styria - Austria
Contact:

PHP/DB and security

Postby zewa » Jan 23rd, '09, 08:54

Hello there ...

in the world of open Internet access and enormous masses of users the point of security and safety
of your scripts gets more and more important.

As you use our high-grade products you will see, when searching the source-code, that lot of time
has been invested into securing the work with your DB, but of course there can always be some hidden
vulnerabilities you most of the time, see just comin' when its too late.

1.) Variable checking

Keeping the security aspect in mind, one should always try to write his own scripts with a proper variable checking.
it protects from missplaced values, intentional attacks like SQL-Injection and so on.

Using frameworks for PHP offers you often good solutions for protection, but not everyone wants to code
under such restricted environments and prefers his own clean solution.


Now think back of all your codes, nevertheless they are used or just experimental. Can you say for sure
that you always checked every variable for its value? Have you protected all your POST and GET vars from
Site-Hijacking? Is SQL-Injection no threat for you?
For sure at least one or two leaks are hidden in every Coders apps.

To encounter this, one should learn to always check everything and everywhere, from the beginning on.
So try to build up your own CHECKING-Classes to prove you access to fast and reliable checking, or use some
already setup ones.

If you type in Google -> "PHP sql injection", "PHP variable checking" etc. you'll find dozens of secured code.
some links coming here:




2.) Proper DB design

Most of time, security can come easily through proper Database design and administration.
Keep in mind that not every user in the web needs full access to your database.

    * So lets say for read-only parts on your page, a DB-user with read-only rights will be enough
    * Never give all rights to users (GRANT for instance is never needed in real scripting)
    * Dont let users be able to DROP DATABASEs ...
    * Setup secure entrances to your scripts with proper Login scripts
    * Protect your Database with good (for instance md5) passwords
    * If you are developing local applications in PHP, allow access to your database only for internal IPs

3.) Conclusion

Keeping up with that thoughts you should be able to handle a lot of time consuming, and frustrating
pains with correction of hacked Databases or websites.

Invest some time in the beginning for proper checking and administration, and you'll get the effort back
in long-durable and high-secure software. Of course the thanks of your customers too :)

Let safety of your scripts go hand in hand with your developing phase.

Greetings
Zewa

simmo
Newbie
Newbie
Posts: 5
Joined: Apr 2nd, '09, 14:31

Re: PHP/DB and security

Postby simmo » Apr 3rd, '09, 08:14

This is an interesting article about security. Everyone should give it some thought. It occurred to me that some people might not know how to do the following:

* If you are developing local applications in PHP, allow access to your database only for internal IPs


Here are a couple of suggestions:

1. Go to your site with ftp and change the properties of the file containing the database information to 400.
2. Another solution is to put the file containing the database information inside a protected folder. Visitors trying to access this folder will be asked for a username and password, but php running internally on the server will ignore this.

These are my suggestions, if anyone has any other ideas I would like to hear them.

konvict
Newbie
Newbie
Posts: 1
Joined: Oct 3rd, '11, 06:54
Contact:

Re: PHP/DB and security

Postby konvict » Oct 3rd, '11, 07:01

Security should be a top concern throughout the development of any PHP web application. There are some very simple measures you can take to protect your application from potential abuse. This post will cover some of the basics of PHP security. For more detailed explanations of good security practices, check out the PHP Security Guide.

I do not consider myself a PHP security expert, but these are things that every developer should know. Also keep in mind that security is a process and not a result.
1. Input Filtering

Assume everything is dirty until proven clean. Filtering all data from external sources is probably the most important security measure you can take. This can be as easy as running some simple built-in functions on your variables.

When it comes to accepting user input, never directly use anything in $_GET or $_POST. Check each value to make sure it is something expected and assign it to a local variable for use.

// input filtering examples

// Make sure it is an integer
$integer = intval($_POST['variable_name']);

// Make it safe to use in a URL
$url_string = urlencode($_POST['variable_name']);

You can also check a value against a list of acceptable values. Here are two methods of doing this:

$page = 'home'; // initialize the variable

// Check input against a white-list of known options
$valid_options = array();
$valid_options[] = 'home';
$valid_options[] = 'downloads';
$valid_options[] = 'about';

if(in_array($_GET['page'], $valid_options))
{
$page = $_GET['page'];
}

// OR this also works
switch($_GET['page'])
{
case 'home':
case 'downloads':
case 'about':
$page = $_GET['page'];
break;
}

PHP as of version 5.2 provides a set of filtering functions designed just for the purpose of filtering user data. The filter_input() function is used to access a filtered version of input variables. This way you never have to touch the raw input via the $_GET or $_POST arrays.

// filter_input examples

// Make sure it is an integer
$integer = filter_input(INPUT_POST, 'variable_name', FILTER_SANITIZE_NUMBER_INT);

// Make it safe to use in a URL
$url_string = filter_input(INPUT_POST, 'variable_name', FILTER_SANITIZE_ENCODED);

// Make sure it is a valid URL
$url = filter_input(INPUT_POST, 'variable_name', FILTER_VALIDATE_URL);

See some more examples of the filter functions in this post: Easy Text Validation Without Regular Expressions
2. Output Filtering

It is also important to filter what comes out of your applications. You want to avoid outputting the wrong characters and breaking the page rendering. This is also important in order to block certain attacks involving JavaScript injected by malicious users. There are a few functions to know for cleaning up text to display to the user:

htmlspecialchars(): Converts special HTML characters to entities
htmlentities(): Converts all possible characters to HTML entities
strip_tags(): Remove all HTML tags from a string (you can also selectively allow tags using the second optional parameter)

$text = '<a href="test">Test</a>';
echo htmlspecialchars($text); // &lt;a href=&quot;test&quot;&gt;Test&lt;/a&gt;
echo strip_tags($text); // Test

3. Database Queries

If your application uses a database to store data, this is another source of potential vulnerabilities. SQL Injection is a very common attack that involves maliciously crafted user input designed to change the logic of a query. This potentially allows the user to run any kind of query or bypass security measures. Stopping it is usually as easy as properly escaping data, or using prepared statements.

Escape functions:

mysql_real_escape_string(): For use with the mysql_* functions
mysqli::escape_string(): For use with the MySQLi extension/class
pg_escape_string(): For use with PostgreSQL
addslashes(): This is a generic escape function to use only if your database engine does not have a specific function

Here is an example using each function:

// $db refers to database connection resource/object
$name = "O'reilly"; // Contains a quote that will break the query

// MySQL via mysql_*
$safe = mysql_real_escape_string($name, $db);

// MySQL via MySQLi
$safe = $db->escape_string($name); // OOP Style
$safe = mysqli_real_escape_string($db, $name); // Procedural Style

// PostgreSQL
$safe = pg_escape_string($db, $name);

// Generic (last resourt)
$safe = addslashes($name);

4. Hide Your Errors

It's never a good idea to show the world your errors. Not only does it make you look bad, it also might give malicious users another clue to help them break your site. You should always have display_errors disabled in a production environment, but continue logging errors with log_errors for your own information.

These PHP configuration directives are suitable for a production server:

display_errors 0
log_errors 1

5. Use POST for Dangerous Actions

There are two common methods used to send data to a PHP application, GET and POST. GET works by adding variables to the end of URL's (eg. http://www.example.com/process.php?action=delete&id=123). POST works by sending variables in the body of the request (normal users will not see them). It is important to carefully consider which method to use for a certain task.

You should generally stick to POST when you are performing a potentially dangerous action (like deleting something). The reason is that is is much easier to trick a user into accessing a URL with GET parameters than it is to trick them into sending a POST request. Take this example:

<img src="http://www.example.com/process.php?action=delete&id=123" />

If a user with an active session on your site visits another web page with the above image tag, the user's browser will quietly send a request to your site telling it to delete record 123.

Keep in mind that other precautions should also be taken to ensure requests are legitimate under a secure session. It is also easily possible to create a form that does the same as above using a POST request, so don't assume that method is "safe" either. See sections 2 and 4 of the PHP Security Guide for more information on form and session security.

paragate
Master
Master
Posts: 151
Joined: Nov 13th, '14, 13:04
Location: Denmark, Odense

Re: PHP/DB and security

Postby paragate » Aug 19th, '16, 10:43

php Sanitize filters are quite useful
FILTER_SANITIZE_EMAIL
FILTER_SANITIZE_ENCODED
FILTER_SANITIZE_MAGIC_QUOTES
FILTER_SANITIZE_NUMBER_FLOAT
FILTER_SANITIZE_NUMBER_INT
FILTER_SANITIZE_SPECIAL_CHARS
FILTER_SANITIZE_FULL_SPECIAL_CHARS
and so..

use the following syntax:
filter.default = full_special_chars
filter.default_flags = 0


Return to “Snippets, Tutorials & Other Stuff”