[Zend PHP5 Cerification] Lectures -- 7. Security

Defense inDepth
.When you plan with defensein depth, you plan for failure. Rather than internal functionsassuming the data they receive is already validated or escaped, theywill check and confirm.
.Applications that demonstrate defense indepth are not only more resistant to attack when they are developed,they also remain more resistant over time as new attacks aredeveloped, and as more code is added to them.
 

 Principleof Least Privilege
.Your PHPapplications by default has a lot of power, they execute as the webuser (often apache or www-data) with all the rights and privilegesthereof.
.If an attacker gains control of PHP through anapplication vulnerability this can be used and abused.
 

 Terms:Validation vs Escaping
.Theseterms are often confused, or used interchangeably
.Validation orFiltering is the process by which you subject data to a series ofrules, either it passes (validates) or does not.
.Escaping is theprocess by which you prepare data for a specific resource by“escaping” certain portions of the data to avoid confusion ofinstruction and data.

ValidateInput
Whenever you receive dataone of three things can be said about it:
.It is valid, the userentered the data you want, in the format you desire.
.It isinvalid because the user either did not comply or did not understandthe rules on the data you requested (eg. Poorly formatted phonenumber).
.It is invalid because the user is attempting tocompromise your system.
Data from the end user can not be trusted,it must be validated before it can be used.
 -How does userdata get into your PHP application?
.Validate data first don’tsave it for last.
.Fail early, tell the user what wentwrong.

 

.All Input Is Tainted
If the data originatesfrom a foreign source such as user form input, the query string, oreven an RSS feed, it cannot be trusted. It is tainted data.
As ageneral rule of thumb, the data in all of PHP’s superglobals arraysshould be considered tainted. The one exception to this rule is the$_SESSION superglobal array, which is persisted on the server andnever over the Internet.

.Whitelistvs. Blacklist Filtering
Blacklistsmust be modified continually, and expanded as new attack vectorsbecome apparent.
For this reason, whitelists afford strongerprotection against attacks than blacklists.
.There are two majorapproaches to data validation, the whitelist and blacklistapproach.
.Under the whitelist approach you select a series ofvalid characteristics (frequently characters) only data that followsthese rules is accepted as valid.
.Under the blacklist approachyou select a series of invalid characteristics, any data thatcontains these characteristics is considered invalid.
.Which doyou prefer?


Functionsto examine

. ctype_alnum-- Check for alphanumeric character(s)
. ctype_alpha -- Check foralphabetic character(s)
. ctype_cntrl -- Check for controlcharacter(s)
. ctype_digit -- Check for numeric character(s)
.ctype_graph -- Check for any printable character(s) except space
.ctype_lower -- Check for lowercase character(s)
. ctype_print --Check for printable character(s)
. ctype_punct -- Check for anyprintable character which is not whitespace or an
alphanumericcharacter
. ctype_space -- Check for whitespace character(s)
.ctype_upper -- Check for uppercase character(s)
. ctype_xdigit --Check for character(s) representing a hexadecimal digit
.preg_match – Apply regular expression rules to data
. is_array –Check to see if variable is an array

 

 

 

FilterInput
It is possible to implementsome client-side validation code using JavaScript to enforce theserules, but, it is not always possible to force users to use only yourform and, thus, your client-side rules. Therefore, server-sidefiltering is important for security, while client-side validation isimportant for usability.
e.g.

$clean = array();
if(ctype_alpha($_POST[’username’]))
{
$clean[’username’]= $_POST[’username’];
}
if(ctype_alnum($_POST[’password’]))
{
$clean[’password’]= $_POST[’password’];
}
$colours = array(’Red’, ’Blue’,’Yellow’, ’Green’);
if (in_array($_POST[’colour’],$colours))
{
$clean[’colour’] = $_POST[’colour’];
}

Youshould force the user to provide correct information rather thantrying to clean and sanitize it on your own. If you attempt tosanitize the data, you may end up with bad data, and you’ll runinto the same problems that result with the use ofblacklists.


Escape Output
Output is anything that leavesyour application, bound for a client. The client, in this case, isanything from a Web browser to a database server.
Whereasfiltering input protects your application from bad or harmful data,escaping output protects the client and user from potentiallydamaging commands.

When you send data to a resource (database,web browser, etc.) that resource likely interprets certain charactersas having a specific meaning, by escaping the output you tell theresource to ignore the meaning for that character.


.Filteringvs Escaping
Filtering ensures the validity of data coming into theapplication; escaping protects you and your users from potentiallyharmful attacks. Output must be escaped because clients—Webbrowsers, database servers, and so on—often take action whenencountering special characters. For Web browsers, these specialcharacters form HTML tags; for database servers, they may includequotation marks and SQL keywords. Therefore, it is necessary to knowthe intended destination of output and to escapeaccordingly.
Escaping output intended for a database will notsuffice when sending that same output to a Web browser—data must beescaped according to its destination.


EscapingOutput – Web Page
.strip_tags()– Remove anything that looks like an HTML tag from astring.
.htmlentities() – Convert any character that has aspecific HTML entity into it.
.Htmlspecialchars() – Convert &,“, ‘, <, > into their entities
htmlspecialchars() and htmlentities() the latter beingthe most exhaustive and, therefore, recommended function forescaping.


Escaping Output- SQL
You have two choices,escape your data or use prepared statements.
To escape your datause a database specific function, the newest oneavailable.
mysql_real_escape_string()

Preparedstatements are preferred as they offer perfect separation.

Escapeoutput intended for a database server, such as in an SQL statement,with the database-driver-specific *_escape_string() function; whenpossible, use prepared statements. Since PHP 5.1 includes PHP DataObjects (PDO), you may use prepared statements for all databaseengines for which there is a PDO driver. If the database engine doesnot natively support prepared statements, then PDO emulates thisfeature transparently for you. The database engine (or PDO, ifemulating prepared statements) performs the hard work of actuallyescaping the values for use in the statement.

e.g.

//First, filter the input
$clean = array();
if(ctype_alpha($_POST[’username’]))
{
$clean[’username’]= $_POST[’username’];
}
// Set a named placeholder in theSQL statement for username
$sql = ’SELECT * FROM users WHEREusername = :username’;
// Assume the database handler exists;prepare the statement
$stmt = $dbh->prepare($sql);
// Bind avalue to the parameter
$stmt->bindParam(’:username’,$clean[’username’]);
// Execute and fetchresults
$stmt->execute();
$results =$stmt->fetchAll();


RegisterGlobals
When set to On, theregister_globals configuration directive automatically injectsvariables into scripts. That is, all variables from the query string,posted forms, session store, cookies, and so on are available in whatappear to be locally-named variables. Thus, if variables are notinitialized before use, it is possible for a malicious user to setscript variables and compromise an application.
Note that aby-product of having register_globals turned on is that it isimpossible to determine the origin of input.A best practice formaintainable and manageable code is to use the appropriatesuperglobal array for the location from which you expect the data tooriginate.

.With register globals enabled PHP automaticallycreates global variables for all variables received.
.Registerglobals was great, when you were learning, and no one else saw yourapplications.
.Register globals on it’s own is not a securityrisk, register globals combined with sloppy coding is theproblem.

.To write secure codethat remains secure in an environment with register globals enabledyou must pre-initilize all your variables.

.Codewith E_STRICT enabled, it will warn you of variables that are usedbefore initialization.

 


WebsiteSecurity
.SpoofedForms
e.g.
Reproduce a form at another location and submit itby modifying the action to use an absolute URL.

.Cross-SiteScripting  XSS

.Undera cross site scripting attack an attacker injects code into your page(forum post, shout box, etc) that contains code that re-writes thepage to do something nefarious.

 

.Cross-Site RequestForgeries
.Under a cross site request forgery attack a siteexploits another sites persistent user trust relationship to makesomething happen.
.<img src=
http://www.amazon.com/buy/my/bookheight=“1” width=“1”>
.
iFramesare another common tool leveraged in this technique.

 


Across-site request forgery (CSRF) is an attack that attempts to causea victim to unknowingly send arbitrary HTTP requests, usually to URLsrequiring privileged access and using the existing session of thevictim to determine access.
While proper escaping of output willprevent your application from being used as the vehicle for a CSRFattack, it will not prevent your application from receiving forgedrequests. Thus, your application needs the ability to determinewhether the request was intentional and legitimate or possibly forgedand malicious.

.Forum Token
The token method involves theuse of a randomly generated token that is stored in the user’ssession when the user accesses the form page and is also placed in ahidden field on the form. The processing script checks the tokenvalue from the posted form against the value in the user’s session.If it matches, then the request is valid. If not, then it is suspectand the script should not process the input and, instead, shoulddisplay an error to the user.

DatabaseSecurity
.SQLinjection
MagicQuotes
.Magic Quotesautomatically escapes quote characters, backslash and null to make itsafer to send data to databases.
.This isn’t really a goodthing, data goes places other than databases, database accept metacharacters other than the ones magic quotes deals with
.Gonecompletely in PHP6
.Disabled by default in PHP5
.A pain in theneck, you end up with code like this:
     if(get_magic_quotes_gpc())
    {
   $string = stripslashes($string);
   }

 

 



SessionSecurity
Sessionsprovide safer state, it may not nesesarily be safe.
Basically,sessions combine cookies containing a session ID with a local(ish)data store corresponding to that session id.
If the session id iscompromised, or the data store is not secure (/tmp on a sharedmachine) sessions are still vulnerable to attack.


.sessionfixation
This attack has two sides, either an attacker tricksanother user into clicking on a link providing a session id, or aninnocent user pastes a link containing their session id to someonethey shouldn’t have.
To defend against this type of attack don’tallow session IDs to come in over GET, and regenerate session idswhen a user authenticates themselves.


It is possible,however, to set the session identifier manually through the querystring, forcing the use of a particular session. This simple attackis called session fixation because the attacker fixes the session.
Ifthe user logs in while using the provided session identifier, theattacker may be able to “ride” on the same session and gainaccess to the user’s account. This is why session fixation issometimes referred to as “session riding.” Since the purpose ofthe attack is to gain a higher level of privilege, the points atwhich the attack should be blocked are clear: every time a user’saccess level changes, it is necessary to regenerate the sessionidentifier. PHP makes this a simple task withsession_regenerate_id().
If the user login is successful,regenerate the session ID.

 

.session hijacking
SessionIDs are very random.
Predicting them is hard, it’s much easierto:
– Check out /tmp on a shared server, see what people have
–Intercept communications
– Implement session fixation
Todefend, implement some browser fingerprinting

One way toidentify the user in addition to the session identifier is to checkvarious request headers sent by the client. One request header thatis particularly helpful and does not change between requests is theUser-Agent header. Since it is unlikely (at least in most legitimatecases) that a user will change from one browser to another whileusing the same session, this header can be used to determine apossible session hijacking attempt.

After a successful loginattempt, store the User-Agent into thesession:

$_SESSION[’user_agent’] =$_SERVER[’HTTP_USER_AGENT’];

Then, on subsequent pageloads, check to ensure that the User-Agent has not changed. If it haschanged, then that is cause for concern, and the user should log inagain.

if ($_SESSION[’user_agent’] !=$_SERVER[’HTTP_USER_AGENT’])
{
// Force user to log inagain
exit;
}

 


Whereas most of the otherattacks can be prevented by filtering input and escaping output,session attacks cannot. Instead, it is necessary to plan for them andidentify potential problemareas of your application.

When auser first encounters a page in your application that callssession_start(), a session is created for the user. PHP generates arandom session identifier to identify the user, and then it sends aSet-Cookie header to the client. By default, the name of this cookieis PHPSESSID, but it is possible to change the cookie name in php.inior by using the session_name() function.

 

FilesystemSecurity
.open_basedir– Restricts PHP’s file acces to one or more specified directores– Relatively quick and easy
.safe_mode– limits file access based on uid/ gid of running script and fileto be accessed – Slower, doesn’t work well with uploadedfiles 

 .RemoteCode Injection
A remote code injection attack occurs when anattacker is able to cause your application to execute PHP code oftheir choosing. This can have devastating consequences
for bothyour application and system. When including files with include andrequire, pay careful attention when using possibly tainted data tocreate a dynamic include based on client input.
While this attackis very powerful, effectively granting the attacker all the sameprivileges enjoyed by the Web server, it is easy to protect againstit by filtering all input and never using tainted data in an includeor require statement.

The allow_url_fopen directive in PHPprovides the feature by which PHP can access URLs, treating them likeregular files—thus making an attack such as the one described herepossible. By default, allow_url_fopen is set to On; however, it ispossible to disable it in php.ini, setting it to Off, which willprevent your applications from including or opening remote URL as files (as well as effectively disallowing many of the cool streamfeatures described in the Files and Streams).

CommandInjection
WhilePHP provides great power with the exec(), system() and passthru()functions, aswell as the ‘ (backtick) operator, thesemust not beused lightly, and it is important to take great care to ensure thatattackers cannot inject and execute arbitrary systemcommands.

escapeshellcmd() and escapeshellarg()

 Whenpossible, avoid the use of shell commands. If they are necessary,avoid the use of client input to construct dynamic shellcommands.


SharedHosting
SafeMode
There are three php.ini directives that remain important in ashared hosting environment: open_basedir, disable_functions, anddisable_classes.

You may set the open_basedir directive inphp.ini or on a per-virtual-host basis in httpd.conf.

Thedisable_functions and disable_classes directives work similarly,allowing you to disable certain native PHP functions and classes forsecurity reasons. Any functions or classes listed in these directiveswill not be available to PHP applications running on the system. Youmay only set these in php.ini.

posted @ 2010-06-29 17:28  DavidHHuan  阅读(529)  评论(0编辑  收藏  举报