Difference between revisions of "PHP Security Cheat Sheet"

From OWASP
Jump to: navigation, search
Line 3: Line 3:
 
This article is focused on providing PHP-specific guidance to securing web applications.
 
This article is focused on providing PHP-specific guidance to securing web applications.
  
= PHP Security General Guidelines  =
+
= PHP General Guidelines for Secure Web Applications =
  
== Don't use $_REQUEST - use $_GET or $_POST or $_SERVER instead ==
+
== PHP Version ==
 +
Use '''PHP 5.3.8'''. Stable versions are always safer then the beta ones.
  
== Use PDO with prepared statements or an ORM like Doctrine ==
+
== Framework==
 +
Use a framework like '''Zend''' or '''Symfony'''. Try not to re-write the code again and again. Also avoid dead codes.
  
== Use a framework like Zend or Symfony - Stop re-writing the same code again and again ==
+
== Directory==
 +
Code with most of your code outside of the webroot. This is automatic for Symfony and Zend. Stick to these frameworks.
  
== Input nput validation ==
+
== Hashing Extension ==
Use $_dirty['foo'] = $_GET['foo'] and then $foo = validate_foo($dirty['foo']);
+
Not every PHP installation has a working '''mhash''' extension, so if you need to do hashing, check it before using it. Otherwise you can't do SHA-256
  
== Output encoding is entirely up to you. Just do it, ESAPI for PHP is ready for this job. ==
+
== Cryptographic Extension ==
 +
Not every PHP installation has a working '''mcrypt''' extension, and without it you can't do AES. Do check if you need it.
  
== Not every PHP installation has a working mhash extension, so if you need to do hashing, check it before using it. Otherwise you can't do SHA-256 ==
+
== Authentication and Authorization ==
 +
There is no authentication or authorization classes in native PHP. Use '''ZF''' or '''Symfony''' instead.
  
== Not every PHP installation has a working mcrypt extension, and without it you can't do AES. Do check if you need it ==
+
== Input nput validation ==
 +
Use $_dirty['foo'] = $_GET['foo'] and then $foo = validate_foo($dirty['foo']);
  
== Code with most of your code outside of the webroot. This is automatic for Symfony and Zend. Stick to these frameworks ==
+
== Use PDO or ORM ==
 +
Use PDO with prepared statements or an ORM like Doctrine
  
== Use PHP 5.3.8. Anything less is unsafe ==
+
== Use PHP Unit and Jenkins ==
 +
When developing PHP code, make sure you develop with PHP Unit and Jenkins - see http://qualityassuranceinphpprojects.com/pages/tools.html for more details.
  
== There is no authentication or authorization classes in native PHP. Use ZF or Symfony instead ==
+
== Use Stefan Esser's Hardened PHP Patch ==
 
+
Consider using Stefan Esser's Hardened PHP patch - http://www.hardened-php.net/suhosin/index.html  
== When developing PHP code, make sure you develop with PHP Unit and Jenkins - see http://qualityassuranceinphpprojects.com/pages/tools.html for more details. ==
+
 
+
== Consider using Stefan Esser's Hardened PHP patch - http://www.hardened-php.net/suhosin/index.html ==
+
 
(not maintained now, but the concepts are very powerful)
 
(not maintained now, but the concepts are very powerful)
  
== In terms of secure coding with PHP, do not use globals unless absolutely necessary ==
+
== Avoid Global Variables==
 +
In terms of secure coding with PHP, do not use globals unless absolutely necessary  
 
Check your php.ini to ensure register_globals is off Do not run at all with this setting enabled It's extremely dangerous (register_globals has been disabled since 5.0 / 2006, but .... most PHP 4 code needs it, so many hosters have it turned on)
 
Check your php.ini to ensure register_globals is off Do not run at all with this setting enabled It's extremely dangerous (register_globals has been disabled since 5.0 / 2006, but .... most PHP 4 code needs it, so many hosters have it turned on)
 
== Ensure allow_url_fopen and allow_url_include are both disabled to protect against RFI ==
 
But don't cause issues by using the pattern include $user_supplied_data or require "base" + $user_supplied_data - it's just unsafe as you can input /etc/passwd and PHP will try to include it
 
  
 
== Avoid Eval() ==
 
== Avoid Eval() ==
It basically allows arbitrary PHP code execution, so do not evaluate user supplied input. and if you're not doing that, you can just use PHP directly. eval() is at least 10-100 times slower than native PHP
+
It basically allows arbitrary PHP code execution, so do not evaluate user supplied input. and if you're not doing that, you can just use PHP directly. eval() is at least 10-100 times slower than native PHP
  
== Watch for executable regexes (!) ==
+
== Don't use $_REQUEST  ==
== Session rotation is very easy - just after authentication, plonk in session_regenerate_id() and you're done. ==
+
Instead of $_REQUEST- use $_GET or $_POST or $_SERVER
== Set display_errors to 0, and set up logging to go to a file you control, or at least syslog. This is the most commonly neglected area of PHP configuration ==
+
 
 +
== Protection against RFI==
 +
Ensure allow_url_fopen and allow_url_include are both disabled to protect against RFI  But don't cause issues by using the pattern include $user_supplied_data or require "base" + $user_supplied_data - it's just unsafe as you can input /etc/passwd and PHP will try to include it
 +
 
 +
== Regexes (!)==
 +
Watch for executable regexes (!)  
 +
 
 +
== Session Rotation ==
 +
Session rotation is very easy - just after authentication, plonk in session_regenerate_id() and you're done.
  
 
== Be aware of PHP filters ==
 
== Be aware of PHP filters ==
 +
PHP filters can be tricky and complex. Be extra-conscious when using them.
 +
 +
== Logging ==
 +
Set display_errors to 0, and set up logging to go to a file you control, or at least syslog. This is the most commonly neglected area of PHP configuration
 +
 +
== Output encoding ==
 +
Output encoding is entirely up to you. Just do it, ESAPI for PHP is ready for this job.
  
 
These are transparent to you and you need to know about them. php://input: takes input from the console gzip: takes compressed input and might bypass input validation http://au2.php.net/manual/en/filters.php  
 
These are transparent to you and you need to know about them. php://input: takes input from the console gzip: takes compressed input and might bypass input validation http://au2.php.net/manual/en/filters.php  

Revision as of 00:15, 2 July 2012

DRAFT CHEAT SHEET - WORK IN PROGRESS

Introduction

This article is focused on providing PHP-specific guidance to securing web applications.

PHP General Guidelines for Secure Web Applications

PHP Version

Use PHP 5.3.8. Stable versions are always safer then the beta ones.

Framework

Use a framework like Zend or Symfony. Try not to re-write the code again and again. Also avoid dead codes.

Directory

Code with most of your code outside of the webroot. This is automatic for Symfony and Zend. Stick to these frameworks.

Hashing Extension

Not every PHP installation has a working mhash extension, so if you need to do hashing, check it before using it. Otherwise you can't do SHA-256

Cryptographic Extension

Not every PHP installation has a working mcrypt extension, and without it you can't do AES. Do check if you need it.

Authentication and Authorization

There is no authentication or authorization classes in native PHP. Use ZF or Symfony instead.

Input nput validation

Use $_dirty['foo'] = $_GET['foo'] and then $foo = validate_foo($dirty['foo']);

Use PDO or ORM

Use PDO with prepared statements or an ORM like Doctrine

Use PHP Unit and Jenkins

When developing PHP code, make sure you develop with PHP Unit and Jenkins - see http://qualityassuranceinphpprojects.com/pages/tools.html for more details.

Use Stefan Esser's Hardened PHP Patch

Consider using Stefan Esser's Hardened PHP patch - http://www.hardened-php.net/suhosin/index.html (not maintained now, but the concepts are very powerful)

Avoid Global Variables

In terms of secure coding with PHP, do not use globals unless absolutely necessary Check your php.ini to ensure register_globals is off Do not run at all with this setting enabled It's extremely dangerous (register_globals has been disabled since 5.0 / 2006, but .... most PHP 4 code needs it, so many hosters have it turned on)

Avoid Eval()

It basically allows arbitrary PHP code execution, so do not evaluate user supplied input. and if you're not doing that, you can just use PHP directly. eval() is at least 10-100 times slower than native PHP

Don't use $_REQUEST

Instead of $_REQUEST- use $_GET or $_POST or $_SERVER

Protection against RFI

Ensure allow_url_fopen and allow_url_include are both disabled to protect against RFI But don't cause issues by using the pattern include $user_supplied_data or require "base" + $user_supplied_data - it's just unsafe as you can input /etc/passwd and PHP will try to include it

Regexes (!)

Watch for executable regexes (!)

Session Rotation

Session rotation is very easy - just after authentication, plonk in session_regenerate_id() and you're done.

Be aware of PHP filters

PHP filters can be tricky and complex. Be extra-conscious when using them.

Logging

Set display_errors to 0, and set up logging to go to a file you control, or at least syslog. This is the most commonly neglected area of PHP configuration

Output encoding

Output encoding is entirely up to you. Just do it, ESAPI for PHP is ready for this job.

These are transparent to you and you need to know about them. php://input: takes input from the console gzip: takes compressed input and might bypass input validation http://au2.php.net/manual/en/filters.php

Related Cheat Sheets

OWASP Cheat Sheets Project Homepage

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets

Authors and Primary Editors

Andrew van der Stock