PHP and SQL Security
An anonymous reader writes "PHP and SQL
Security are being proven more weak every day. Uberhacker.Com is running a PHP
and SQL security research
project to raise awareness of secure scripting. The site hosts guides
to secure PHP programming, forums, and scripting
challenges to see who can create the most secure scripts."
Other than the scripting challenge, what's on this site? I've read the guides to hacking, but it's all a bunch of kindergarden material. Seems if you follow the guides you'll certainly have insecure PHP scripts with all kinds of SQL injection. How about posting some real articles on secure PHP scripting...
AFAIK SQL injection can be prevented by binding the parameters to the SQL statement and not putting them within SQL.
...) using bind_param.
Why is this? Performance? Keeping the code short and simple?
An example:
It's easy to inject some malicious SQL when using the following PHP code:
mysql_query("INSERT INTO FOO('Bar') VALUES('$some_post_param');");
But if you prepare the SQL statement with parameters and bind the variable $some_post_param to the statement, it will be secure.
see mysql manual for mysqli_stmt_bind_param() aka bind_param
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); $stmt->bind_param('sssd', $code, $language, $official, $percent);
I know this concept from Perl DBI, but in PHP I haven't seen anyone (phpBB,
As for general webserver security: use PHP and perl as cgi, use suEXEC, run the webserver as nobody/www, put the users into chroot jails, but by all means, don't use PHP safe_mode On.
- David A. Wheeler (see my Secure Programming HOWTO)
I've got a couple of rules I try to abide by - can anyone confirm if they're good programming practice? If they are, then they might prove useful to other people.
not only purification but treat all incoming data as hostile.
every thing that comes from the user needs to be scrubbed, bleached, hammered and then finally used when you know it is 100% safe. and it must be used in a safe manner.
what blows my mind is those that use the DB column name in a webform to be passed.. Oh nice. select from that drop down item_number and simply change it to start playing corrupt the database games.
Nothing that is ever given to the user, or recieved from the user should be trusted... EVER. that is the first rule and needs to be pounded into everyone in every book about any programming language for the first 5 chapters.
start there and you will heve very little security issues.
Do not look at laser with remaining good eye.
Good. You are off to the right start, but with better function programming, you will find yourself writing more feature code than purification code.
Things to look for:
Protects against SELECT SQL injection attacks.
> becomes >
< becomes <
$data = base64_encode(gzdeflate($data));
This will prevent the problems with escaping quotes and apostrophes for SQL, and it will kill any SQL injections in your data.
if($this) {perform action}... will limit your chances of having to cope with scipt injections because you are only testing for the existence of a condition, and not the value of the data.
> Always escape text which is going into an SQL query
/tmp/, because that narrows down hack attempts, making it all the more harder to compromise the system.
I prefer to write my own SQL text, based on input values. That way you are never using data submitted for the SQL query. The only time they would really submit values would be when they are sending in a username and password, but in that case, you should be extremely stringent in purification by only accepting alphanumeric usernames and passwords (ie: run the alphabet function above, but erase all non-alphanumeric chars from the $ALPHABET var).
> Use htmlspecialchars() on any text that's being output, to stop users putting rogue HTML
htmlspecialchars() doesn't always work. I prefer using the example above, by limiting the characters allowed and disallowing HTML in the form of post body/subject data. Converting everything to base64 will make it nearly impossible to script attack the database, too.
> Put database usernames, passwords, pathnames and other similarly important but site-specific data in a define()
I disagree, because I use the $_SESSION array instead, which can not be changed by a user if the session cookie is server-side. Sessions can be scooped by sniffers, but that can be managed by your host's security, to prevent it. Certainly change the locale for session data from
> Never include() or require() something that isn't a hard-coded string
To me, this isn't totally required if you have suitable purification, but that extra bit of paranoia is welcomed, because it shows true fear and that is acceptable in any kind of programming. That sort of humility is welcomed because it demonstrates a compassion for the task at hand.
> Be hugely care
The dangers of knowledge trigger emotional distress in human beings.