Notes on PHP Security "literature search" by Mary Ann - Fall 2012
Legend:
- System Issue
- Site-wide Issue
- Application Issue
This is the most recent and most definitive offering from Ron. It certainly gives us more than enough to get going with.
It is very complete - no need to read others if you've digested this one.
It discusses "Network-level filtering" (pg. 42) - support for the .htaccess restrictions.
Very generic - doesn't focus on any one platform or language. Contains site-wide recommendations as well as code-specific.
CPNI = Centre for the Protection of National Infrastructure - gov.uk
This document is written by one
of the author's of the O-Reilly "PHP Cookbook" book.
- Unvalidated
Parameters
- turn off
register_globals
- access values
from URLs, forms and cookies through superglobal arrays $_GET, $_POST
and $_COOKIE
- validate values
from superglobal arrays before using
- make sure data
in cookies and hidden form fields has not been tampered with by sending
a hash of the data and a secret word along with the data
- Broken
Access Control
- use PEAR
modules, instead of rolling your own access control solution (Auth,
Auth_HTTP)
- ie. if not using sessions??
- Broken
Account and Session Management
- use
PHP built-in session management
- be careful how
session information is stored - in database or protected part of file
system rather than /tmp
- use SSL
- Cross-Site Scripting (XSS) Flaws
- never display
any external information without filtering it;
- filter
variables before including them in hidden form fields, query strings or
any page output
- tools:
htmspecialchars(); strtr(); strip_tags(); utf8_decode()
- eg. $safer =
strtr($untrusted, array('(' => '(', ')' =>
')')); #convert to entity equivs.
- Buffer Overflows
- not a code issue - a problem with PHP and extensions itself
- subscribe to
php-announce mailing list to stay on top of patches and new releases
- Command Injection Flaws
- Cross-Site
Scripting Flaws = displaying unfiltered, unescaped malicious content to
user's browser
- Command
injection Flaws = passing unfiltered, unescaped malicious commands to
an external process or database
- in addition to
validating input, always escape input before passing to external
process or database
- if you really
must: tools for passing to shell (eg. via exec() or system()) -
escapeshellcmd(); escapeshellarg().
- use realpath()
to canonicalize all pathnames before executing an external program or
opening an external file
- escape SQL
queries (eg. mysql_escape_string)
- Error Handling Problems
- configure PHP
to log errors rather than display them
- Insecure Use of Cryptography
- use mcrypt
instead of rolling your own encryption scheme
- Remote Administration Flaws
- run remote
admin. tools over SSL
- change any 3rd
party default admin. usernames/passwords (and URL if possible)
- run admin.
tools on a different server
- Web and Application Server
Misconfiguration
- keep on top of
PHP patches and security problems (php-announce)
- stay away from
the automatic PHP source display handler (AddType
application/x-httpd-php-source .phps)
- use
php.ini-recommended instead of php.ini-dist
This document has
some very detailed examples about how various exploits work. I
have highlighted only new information/suggestions.
- if nothing else, FILTER ALL
EXTERNAL DATA
- make sure register_globals is
disabled
- data filtering techniques:
- Dispatch Method
- ie. use a "controller"
- Include Method
- ie. auth.php
- "clean" all data using whitelist
- error reporting (?)
- Form Processing:
- spoofed form submissions - can't use select options in place
of data validation
- spoofed HTTP requests - another reason to always do
server-side data filtering
- Cross-Site
Scripting (XSS) - exploits browser trust in server (steals
cookie)
- Filter all external data - ie. anything not actually in the
code
- Use existing functions - eg. htmlentities, strip_tags,
utf8_decode
- Use a whitelist approach
- Use a strict
naming convention - to help distinguish between filtered and unfiltered
data - eg. $clean['fn']=$_POST['fn']
- Cross-Site
Request Forgeries (CSRF) - exploits applications trust in
knowing the identity of the user
- eg. replacing an img tag with a rogue URL to steal a cookie
- use POST instead of GET in forms
- use $_POST instead of register globals
- do not focus on convenience (ie. the user's convenience)
- force the use of your own forms - session management?
- Databases and SQL
- Exposed Access Credentials
- place all modules outside
document root (esp. database username/password)
- configure Apache to dissallow .inc files (?)
- set credentials via "SetEnv" in a file only root can read
- SQL Injection
- Filter your data
- Quote your data (single quotes)
- Escape your data (eg.
mysql_escape_string (best) or addslashes
- Session Hijacking- don't rely on
cookies!
- Exposed Session Data
- make sure in safe_mode;
- don't use /tmp to store
cookies (use a database instead)
- Browsing the Filesystem
Most of this is a repeat of
previous things, but the article has some nice detailed examples.
- Validate input
- Guard your file system
- Guard your database
- Guard your session data
- Guard against Cross-Site Scripting (XSS) vulnerabilities
- Verify form posts
- Protect against Cross-Site Request Forgeries (CSRF)
Entertaining - includes the following 4 links to other phpmaster.com
articles.
Discussion of transitioning from mysql -> mysqli(mproved) ->
PhpDataObjects.
Stuck with mysql on PHP4.3 (gamma). Here's a good example of
using it "securely":
01
<?php
02 // Step 1: Establish a connection
03 $db = mysql_connect("localhost", "testusr",
"secretpass");
04 mysql_select_db("testdb", $db);
05
06 // Step 2: Construct a query
07 $query = "SELECT * FROM foo WHERE bar = '" .
mysql_real_escape_string($zip) . "'";
08
09 // Step 3: Send the query
10 $result = mysql_query($query, $db);
11
12 // Step 4: Iterate over the results
13 while($row = myql_fetch_assoc($result)) {
14 print_r($row);
15 }
16
17 // Step 5: Free used resources
18 mysql_free_result($result);
19 mysql_close($db);
Note: following sentence outlines 3 separate issues:
"In order to implement solid security measures which prevents XSS
attacks, we should be mindful of data validation, data sanitization,
and output escaping."
- Data Validation - whitelisting allowed input (eg. preg_match)
- Data Sanitization - removing suspicious buts (eg. strip_tags,
preg_replace)
- Output Escaping - before presenting to user (eg. htmlspecialchars)
Eg.
<?php
// validate comment
$comment = trim($_POST["comment"]);
if (empty($comment)) {
exit("must provide a comment");
}
// sanitize comment
$comment = strip_tags($comment);
// comment is now safe for storage
file_put_contents("comments.txt", $comment, FILE_APPEND);
// escape comments before display
$comments = file_get_contents("comments.txt");
echo htmlspecialchars($comments);
Talks about 2 functions available as of PHP 5.2:
- $value = filter_input(INPUT_GET, "value",
FILTER_VALIDATE_INT,
array("options" => array("min_range" => 15, "max_range" =>
20)));
- $email = filter_var($email,
FILTER_VALIDATE_EMAIL);
Actually I don't understand this one. He seems to be suggesting
that a security code should be included on all forms to verify that the
request isn't coming from a bad hat site.
(explained in more detail in CPNI doc)