Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Security : Database Security

Chapter 6. Database Security

Nowadays, databases are cardinal components of any web based application by enabling websites to provide varying dynamic content. Since very sensitive or secret information can be stored in a database, you should strongly consider protecting your databases.

To retrieve or to store any information you need to connect to the database, send a legitimate query, fetch the result, and close the connection. Nowadays, the commonly used query language in this interaction is the Structured Query Language (SQL). See how an attacker can tamper with an SQL query.

As you can surmise, PHP cannot protect your database by itself. The following sections aim to be an introduction into the very basics of how to access and manipulate databases within PHP scripts.

Keep in mind this simple rule: defense in depth. The more places you take action to increase the protection of your database, the less probability of an attacker succeeding in exposing or abusing any stored information. Good design of the database schema and the application deals with your greatest fears.

Designing Databases

The first step is always to create the database, unless you want to use one from a third party. When a database is created, it is assigned to an owner, who executed the creation statement. Usually, only the owner (or a superuser) can do anything with the objects in that database, and in order to allow other users to use it, privileges must be granted.

Applications should never connect to the database as its owner or a superuser, because these users can execute any query at will, for example, modifying the schema (e.g. dropping tables) or deleting its entire content.

You may create different database users for every aspect of your application with very limited rights to database objects. The most required privileges should be granted only, and avoid that the same user can interact with the database in different use cases. This means that if intruders gain access to your database using your applications credentials, they can only effect as many changes as your application can.

You are encouraged not to implement all the business logic in the web application (i.e. your script), instead do it in the database schema using views, triggers or rules. If the system evolves, new ports will be intended to open to the database, and you have to re-implement the logic in each separate database client. Over and above, triggers can be used to transparently and automatically handle fields, which often provides insight when debugging problems with your application or tracing back transactions.

Code Examples / Notes » security.database

30-jun-2005 11:57

you can also chamge CHMOD for some file containing "user names" or "passwords"

queue

Unportable, but a quick guard against SQL injection with MySQL is to simply hex-encode:
$sql = "insert into foo select 'hello' , 0x68656c6c6f , 0x"
       . bin2hex($_REQUEST['bar'])
       . ";"
;
etc, etc.


dave martin

The posting below is at the very best extremely POV.
There is no more reason to assume you would want to change database vendor than there is to assume you might want to port your php code to Java for example. In either case, its going to be a matter of luck where your business rules sit.
Even if your business rules sit in your application, SQL is NOT portable. Oracle outer joins and pivot queries for example, can look completely different to those in other vendors software (particularly from 8i or lower). This fact alone means that changing your DB vendor requires work on your business rules either in the database or in the application.
Having your rules in the database and keeping the sql in application simple, will at least keep the work in the database if you need to change DB vendor. If you have the rules in the PHP, you'll have to change both.


webmaster

On a database design point of view, you should make sure that you design databases in a manor that any query run from them need minimal input from the user and if it requires user input, that you encrypt where possible.

jjahn

I would say one of the best ways to guard against SQL injection is to use the excellent PEAR DB package. If you prepare() and execute() your queries, PEAR will automagically addslashes and handle the query depending on your RDBMS. And of course, for repeatable queries prepare and execute will give you a bit of a readability and speed increase.

somebody

Encrypting user input doesn't do much to guard against SQL injection attacks.  Naturally, you want to encrypt sensitive information across the wire, but if a user puts in malicious data into an input field, any encryption scheme will just dutifully unpack it at the other and and still run the SQL injection hack if you haven't guarded against it.
Encryption is not magic pixie dust to sprinkle on things to make them more secure.


x12code

About offloading business logic to views and queries facilitated by the database engine, I seek to avoid this as much as possible, and only do so when such would drastically improve efficiency and user response time.
For instance, where I am there is database staff and application staff. Trying to do analysis on existent applications can easily become a snipe hunt.
The database should be kept discreet as much as possible from the application, such that any database or database provider can easily be substituted with a minimum of cognitive effort on the part of the one setting up a new database. If functionality has been offloaded to the database, additional testing is required to make sure triggers and views were done correctly, again, and that they work right.
Also, keeping all business logic with the application allows all functionality and documentation to be readable in one place, which is invaluable when doing subsequent analysis on an existing application. The worst thing is to have functionality scattered here and there.
Keeping everything with the application means one group of people is responsible, as in my case, application staff. Fewer requests go back and forth. Remember, anytime someone else is brought into the picture, such as asking a DBA to create a view or trigger for you, that DBA must take responsibility over his or her work, with whatever requirements, causing more bureaucracy and administrative complexity.


me

<?php
$getal1 = 5.5;
$getal2 = 2.0;

function printDeling() {
$resultaat = global $getal1 / global $getal2;
return $resultaat;
}
function printVermenigvuldiging() {
$resultaat = global $getal1 * global $getal2;
return $resultaat;
}
function printSom() {
$resultaat = global $getal1 + global $getal2;
return $resultaat;
}
function printAftrekking() {
$resultaat = global $getal1 - global $getal2;
return $resultaat;
}

(printDeling()>=7) ? print "<font color=\"green\"> printDeling()</font>" : print "<font color=\"red\"> printDeling()</font>" ;
?>


Change Language


Follow Navioo On Twitter
Introduction
General considerations
Installed as CGI binary
Installed as an Apache module
Filesystem Security
Database Security
Error Reporting
Using Register Globals
User Submitted Data
Magic Quotes
Hiding PHP
Keeping Current
eXTReMe Tracker