Your SlideShare is downloading. ×
0
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Eight simple rules to writing secure PHP programs
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Eight simple rules to writing secure PHP programs

4,911

Published on

Published in: Technology, Education
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,911
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Eight Simple Rules… for Writing Secure PHP Programs Aleksandr Yampolskiy
  • 2. Security: Bird’s Eye View ... Hash Key Management Signature Encryption Security Toolbox DL(g x ) Fact(p*q) Hard problems Prob[ Attack ] ≤ ɛ Proof of security
  • 3. Building Secure Systems … Looks safe to me
  • 4. Building Secure Systems <ul><li>All is well until it starts raining… </li></ul>
  • 5. This Talk <ul><li>Think of your software system as a “house” , and coding standards as the “glue” . </li></ul><ul><li>In this talk, we give eight rules for writing secure PHP programs </li></ul><ul><li>They are: </li></ul><ul><ul><li>A glue for building secure systems. </li></ul></ul><ul><ul><li>Practical and can be easily implemented! </li></ul></ul><ul><ul><li>Will prevent many of the security exploits. </li></ul></ul>vs.
  • 6. Rule 1: Use proper cryptography <ul><li>Do not use stream ciphers (such as RC4). Instead use block ciphers AES, 3DES . </li></ul><ul><li>For hashing, use SHA-2 (although SHA-1 is still ok). </li></ul><ul><li>Do not use a single master key for all encryption purposes. Use different keys . </li></ul><ul><li>Do not hard code key or passwords into your code. </li></ul><ul><li>For sensitive operations, use a secure random number generator instead of default rand(). </li></ul><ul><li>Do not invent your own cryptographic algorithm or download one from the web. Contact [email_address] for advice, first. </li></ul>
  • 7. Common mistakes <ul><li>Poor choice of algorithm </li></ul><ul><li>Attempting to develop an encryption scheme in house </li></ul><ul><li>Failure to change encryption keys </li></ul><ul><li>Insecure storage of passwords, keys, certs </li></ul><ul><li>Many attacks exploit poorly-developed random numbers that are used to generate session IDs. </li></ul><ul><ul><li>&lt;?php for ($i=0; $i&lt;6; $i++) { </li></ul></ul><ul><ul><li>$d=rand(1,30)%2; </li></ul></ul><ul><ul><li>echo $d ? chr(rand(65,90)) : chr(rand(48,57)); } ?&gt; </li></ul></ul>
  • 8. Randomness
  • 9. In Theory <ul><li>Cryptography is based on random numbers : </li></ul><ul><ul><li>Secret keys must be random </li></ul></ul><ul><ul><li>Random bits are needed for public-key encryption, signatures, SSL, etc. </li></ul></ul><ul><li>In theory, all parties have access to a perfect random source [BR93]. </li></ul><ul><li>Under this assumption, many crypto tools can be proven formally secure . </li></ul>
  • 10. Examples of Real Problems <ul><li>Earlier versions of Majordomo used a bad PRG. Could forge mailing list acceptance and subscribe an unknowing victim to thousands of lists. </li></ul><ul><li>Kerberos 4 used memset() to erase a seed before it was used. Seed was always zero and secret keys could be guessed in a few seconds . </li></ul><ul><li>Netscape 1.1 generated SSL keys using time and process ID as seed; easily guessable and breakable. </li></ul>Problem: Secret keys aren’t truly random!
  • 11. Lessons Learnt <ul><li>Seeds must be unpredictable </li></ul><ul><ul><li>128 bit sequences are sufficient </li></ul></ul><ul><ul><li>All possibilities equally likely </li></ul></ul><ul><ul><li>Best seeds are truly random </li></ul></ul><ul><li>PRG (pseudorandom number generator) must be secure </li></ul><ul><ul><li>No detectable pattern </li></ul></ul><ul><ul><li>Even if attacker guesses some pseudorandom bits, no correlation to other bits. </li></ul></ul>
  • 12. What is (Pseudo)-Random? PRG random seed pseudorandom string random string look indistinguishable to any efficient observer Definition [Blum-Micali-Yao]: PRG is a polytime function whose output is indistinguishable from random by any efficient observer 01010111001… 11010011010… 1001
  • 13. Implementation <ul><li>To generate cryptographically secure random numbers in PHP, use md5(mt_rand()) or better yet read from /dev/urandom </li></ul><ul><ul><li>better_token = md5 (uniqid( mt_rand() , true)); </li></ul></ul><ul><ul><li>$uniqueId = bin2hex(file_get_contents(&apos;/dev/urandom&apos;, 0, null, -1, 16)); </li></ul></ul><ul><li>Make sure not to use rand() for security-sensitive applications </li></ul>
  • 14. Rule 2 – Validate all input <ul><li>Input validation failures are behind most common security vulnerabilities (buffer overflows, XSS, log forging, etc.). </li></ul><ul><li>Source of confusion is that input can come from many sources (HTML forms, query strings, environment variables, data files, shared memory, etc.) </li></ul><ul><li>Always validate user input on the server-side before acting on it (even if it has been validated by the client) </li></ul>
  • 15. Rule 2 – Validate all input (cont.) <ul><li>Decode data into canonical representation before validation </li></ul><ul><li>Always establish length constraints </li></ul><ul><li>Canonicalize paths </li></ul><ul><ul><li>http://website/servlet/webacc?user.html=../../../../../../../ boot.ini%00 </li></ul></ul><ul><li>Use whitelists instead of blacklists </li></ul>
  • 16. Rule 2 – Validate all input (cont.) <ul><ul><li>Use regexps to validate strings </li></ul></ul><ul><ul><li>&lt;?php </li></ul></ul><ul><ul><li>if (ereg(&amp;quot;^[a-z]+.html$&amp;quot;, $id)) { </li></ul></ul><ul><ul><li>echo &amp;quot;Good!&amp;quot;; </li></ul></ul><ul><ul><li>} else { </li></ul></ul><ul><ul><li>die(&amp;quot;Try hacking somebody else&apos;s site.&amp;quot;); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>?&gt; </li></ul></ul>
  • 17. Tainted Variables <ul><li>Use Tainted Variables in PHP to eliminate opportunities for injection or hijacking before they’re exploited. </li></ul><ul><li>All external content marked as tainted and refuses to execute potentially insecure functions unless validated and sanitized. </li></ul>
  • 18. Rule 2 – Validate all input (cont.) <ul><li>Example –w/o taint, this will echo the contents inputfield, including malicious HTML script code. </li></ul><ul><li>$inputfield = $_GET[&apos;inputfield&apos;]; </li></ul><ul><li>echo &amp;quot;You entered: $inputfieldn&amp;quot;; </li></ul><ul><li>Modify php.ini to include – </li></ul><ul><li>taint_error_level=E_WARNING </li></ul><ul><li>And the code will execute, but also produce a warning </li></ul><ul><li>Warning: echo(): Argument contains data that is not converted with htmlspecialchars() or htmlentities() in /path/to/script on line 3 </li></ul>
  • 19. Rule 2 – Validate all input (cont.) <ul><li>Example cont. – Modify php.ini to include – </li></ul><ul><li>taint_error_level=E_ERROR </li></ul><ul><li>And the code will terminate before “echo” produces any </li></ul><ul><li>output. </li></ul><ul><li>If you convert $inputfield , the program becomes immune to HTML script injection and the warning disappears. </li></ul><ul><li>$inputfield = htmlspecialchars($_GET[&apos;inputfield&apos;]); </li></ul><ul><li>echo &amp;quot;You entered: $inputfieldn&amp;quot;; </li></ul>
  • 20. Example of Real Problem - XSS <ul><li>If we don’t limit username length, an attacker could create the following: </li></ul><ul><ul><li>Username&lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://www.website.com/malicious.js&amp;quot;&gt;&lt;/script&gt; </li></ul></ul><ul><ul><li>JS has been loaded from another site invisibly. </li></ul></ul><ul><ul><li>Combat by limiting the character set that can be used, and disallow special characters and HTML tags. </li></ul></ul>
  • 21. Rule 3 - Sanitize data sent to other systems <ul><li>Sanitize all data passed to complex subsystems such as command shells, relational databases, and vendor products.  </li></ul><ul><li>Not necessarily an input validation problem because the subsystem does not understand the context in which the call is made. </li></ul><ul><li>Attackers may be able to invoke unused functionality in these components through the use of SQL, command, or other injection attacks. </li></ul>
  • 22. SQL Injection <ul><li>SQL injection aims to influence database queries by manipulating input params. Very common in web apps! </li></ul><ul><li>Example: </li></ul><ul><ul><li>$check = mysql_query(&amp;quot;SELECT Username, Password, UserLevel FROM Users WHERE Username = &apos;&amp;quot;.$_POST[&apos;username&apos;].&amp;quot;&apos; and Password = &apos;&amp;quot;.$_POST[&apos;password&apos;].&amp;quot;&apos;&amp;quot;); </li></ul></ul><ul><ul><li>If a user enters ‘OR 1=1 #’ as the Username, this query will be executed: SELECT Username, Password FROM Users WHERE Username = &apos;&apos; OR 1=1 #&apos; and Password = &apos;&apos; </li></ul></ul>
  • 23. SQL Injection (cont.) <ul><li>Validate that data we enter/query against DB is “well formed”. </li></ul><ul><li>Instead of passing a string to the conditions option, you can pass an array to sanitize tainted strings </li></ul><ul><ul><li>function make_safe($variable) { $variable = sql_real_escape_string(trim($variable)); return $variable; } </li></ul></ul><ul><ul><li>Now run user data through make_safe: </li></ul></ul><ul><ul><li>$username = make_safe($_POST[&apos;username&apos;]); $password = make_safe($_POST[&apos;password&apos;]); $check = mysql_query(&amp;quot;SELECT Username, Password, UserLevel FROM Users WHERE Username = &apos;&amp;quot;.$username.&amp;quot;&apos; and Password = &apos;&amp;quot;.$password.&amp;quot;&apos;&amp;quot;); </li></ul></ul>
  • 24. Global Variables <ul><li>If register_globals is enabled, PHP will create global variables for each GET, POST, and cookie variable included in the HTTP request. </li></ul><ul><li>Disable register_globals in your php.ini file. Use the $HTTP_GET_VARS and $HTTP_POST_VARS to access GET and POST inputs instead of global variables. </li></ul><ul><li>Write code to initialize all global variables or to check that a global variable is not in the $HTTP_POST or $HTTP_GET . </li></ul><ul><li>Ensure session variables really do come from the session and not from a malicious user </li></ul>
  • 25. PHP.INI Security Settings <ul><li>The disable_functions line disables functions commonly used in attacks against PHP web applications and PHP backdoors. </li></ul><ul><li>Example: disable_functions=eval, dl, phpinfo, system, exec, passthru, shell_exec, proc_close, proc_terminate, popen </li></ul><ul><li>Disable the use of URLs to be in include() and fopen() functions to reduce the change of successful remote file inclusion attack. </li></ul><ul><li>Example: allow_url_include=0 and allow_url_fopen=0 </li></ul>
  • 26. PHP.INI Security Settings <ul><li>When safe_mode is turned on, you can specify which directories are searched for files and which are excluded using safe_mode_include_dir and safe_mode_exclude_dir. </li></ul><ul><li>Restrict the programs a PHP script can run with the exec() command by placing the binaries in a special directory and telling PHP about it using safe_mode_include_dir </li></ul><ul><li>Example: Only binaries in this directory will be accessible via exec() safe_mode_include_dir=/usr/local/lib/php/safe-include </li></ul><ul><li>safe_mode_exec_dir=/usr/local/lib/php/safe-bin </li></ul>
  • 27. PHP.INI Security Settings <ul><li>open_basedir will not allow files to be open by PHP scripts outside of the base directory, where you store your websites’ files. </li></ul><ul><li>Example: open_basedir = /var/www </li></ul><ul><li>Turn register_globals=off , so attackers cannot override variables in your scripts by specifying them in URL parameters. </li></ul><ul><li>Turn expose_php=off . An attacker may query an exploit database to find vulnerabilities in your application version. </li></ul>
  • 28. Rule 4 – Avoid information leakage <ul><li>Apps can accidentally leak info about their internal workings , config, etc. </li></ul><ul><li>Attackers can use this weakness to steal sensitive data. </li></ul><ul><li>Ensure sensitive responses with multiple outcomes return identical result . </li></ul><ul><li>Ensure error messages are returned in roughly the same time or impose a random wait time for all transactions </li></ul><ul><li>Don’t log sensitive data. </li></ul>
  • 29. Information Leakage - Example <ul><li>Sensitive information can be leaked very subtly. </li></ul><ul><li>Example 1 : Account Harvesting </li></ul><ul><ul><li>App responds differently to a valid username with invalid password, then it would to a invalid username. </li></ul></ul><ul><ul><li>App discloses which logins are valid vs. which are invalid, and allows accounts to be guessed and harvested. </li></ul></ul><ul><li>Example 2 : Production code comments . More innocuous. </li></ul>&lt;script type=&amp;quot;text/javascript&amp;quot;&gt; $(function() {$(&amp;quot;#19468751&amp;quot;).qtip({content: &apos;&lt;div class=&amp;quot;calendar_hover&amp;quot;&gt;&lt;div class=&amp;quot;title_bar&amp;quot;&gt;&lt;h2 class=&amp;quot;on&amp;quot; lang=&amp;quot;en&amp;quot;&gt;OGIO Bags&lt;/h2&gt;&lt;/div&gt;&lt;img oncontextmenu=&amp;quot;return false;&amp;quot; galleryimg=&amp;quot;no&amp;quot; src=&amp;quot;http://cdn1.gilt.com/images/share/uploads/0000/0000/1991/19911713/orig.jpg?43_1258590331&amp;quot; height=&amp;quot;207&amp;quot; border=&amp;quot;0&amp;quot; alt=&amp;quot;OGIO Bags&amp;quot; width=&amp;quot;303&amp;quot; /&gt;&lt;/div&gt;&apos;,style: {padding: 0,width: 303 + 2,border: {width: 0//color: &apos;#575757&apos;,//radius: 1}},position: {target: &apos;mouse&apos;,adjust: {mouse: true,screen: true,x: 30,y: 0 }}});// Last resort if Andy can&apos;t figure out how to style a border/*var api = $(&amp;quot;#19468751 &amp;quot;).qtip(&amp;quot;api&amp;quot;);api.beforeRender = function() {// Strip out the default styledelete this.options.style.background;delete this.options.style.color;delete this.options.style.textAlign;this.options.style.width = {};delete this.options.style.padding;this.options.style.border = {};this.options.style.title = {};};*/});&lt;/script&gt;
  • 30. Information Leakage - Logging <ul><li>Logging is great for debugging, performance monitoring, compliance, etc. </li></ul><ul><li>But… do not log sensitive data (passwords, SSO cookies, credit card numbers, cryptographic keys, etc.) </li></ul><ul><li>Don’t display detailed internal error messages including stack traces, messages with database or table names, protocols, and other error codes. (This can provide attackers clues as to potential flaws.) </li></ul><ul><li>In PROD, it’s a good idea to set the error_reporting to 0. Use error_log() to log errors to a file or e-mail alert. </li></ul>
  • 31. Information Leakage - Logging
  • 32. Rule 5 – Proper session management <ul><li>Session tracking answers the question: </li></ul><ul><ul><li>After a user authenticates how does server identify subsequent requests to the user? </li></ul></ul><ul><ul><li>Many web app vendors have built-in session tracking, which is good if used properly </li></ul></ul><ul><ul><li>Often done through cookies with session IDs </li></ul></ul><ul><ul><li>session[:user_id] = @current_user.id; User.find(session[:user_id]) </li></ul></ul><ul><li>Often developers will make the mistake of inventing their own session tracking. </li></ul><ul><li>If session tokens aren’t properly protected, attackers can steal them to assume user identities . </li></ul>
  • 33. Example 1 - Session Hijacking <ul><li>Session ID is disclosed or is guessed. </li></ul><ul><li>An attacker using the same session ID has the same privileges as the real user. </li></ul><ul><li>Allows initial access to the web application to be combined with other attacks. </li></ul><ul><li>Two ways: intercepting (steal session token by observing network traffic) or stealing (steal token by persuading user to execute malicious code). </li></ul>
  • 34. Example 2- CSRF Website Evil Doer <ul><li>Alice downloads webpage from Evil Doer’s website </li></ul><ul><li>Downloaded webpage accesses website (e.g. &lt;img src= http://www.site.com/withdraw?account=bob&amp;amount=1000 &gt; ) and performs a command without the user’s authorization </li></ul>1 2
  • 35. Example 2- CSRF (cont.) <ul><li>Also known as one click attack or session riding. </li></ul><ul><li>Transmits unauthorized commands from a user the website trusts. </li></ul><ul><li>To prevent, </li></ul><ul><ul><li>Require authn POST param, not only cookies </li></ul></ul><ul><ul><li>Use a form timeout – set min and max allowed time to filter automated CSRF attacks </li></ul></ul><ul><ul><li>Limit lifetime of authn cookies </li></ul></ul><ul><ul><li>Double-submit the security tokens </li></ul></ul>
  • 36. Proper session mgmt <ul><li>Enforce a limited lifetime on user sessions. </li></ul><ul><li>Validate a session ID before using it (current active session) </li></ul><ul><li>Do not use deterministic seeds to generate random numbers for session IDs (e.g. don’t use IP as a seed) </li></ul><ul><li>Redirect user to logon page if session is stale or logged out. </li></ul>
  • 37. Proper session mgmt (cont.) <ul><li>Use long complex random session ID that cannot be guessed. </li></ul><ul><li>Protect the transmission and storage of the Session ID to prevent disclosure and hijacking (transmit entire session over HTTPS). </li></ul><ul><li>A URL query string should not be used for Session ID or any User/Session information </li></ul><ul><ul><li>URL is stored in browser cache </li></ul></ul><ul><ul><li>Logged via Web proxies and stored in the proxy cache </li></ul></ul>
  • 38. Proper session mgmt (cont). <ul><li>Session ID should expire and/or time-out on the Server when idle or on logout (reset_session) </li></ul><ul><li>Client side cookie expirations useful, but should not be trusted. </li></ul><ul><li>Consider regenerating a new session upon successful authentication or privilege level change </li></ul>
  • 39. Rule 6 – Authentication &amp; Entitlements <ul><li>Authenticate first. Authorize second. </li></ul><ul><li>Use strong passwords. </li></ul><ul><li>Most developers understand authentication well. Many still make mistakes with authorization. </li></ul><ul><li>Authorization (aka entitlements) = the process of granting or denying access to something we are trying to protect. </li></ul>
  • 40. Authentication &amp; Entitlements (cont.) <ul><li>Pitfalls </li></ul><ul><ul><li>Over privileging users </li></ul></ul><ul><ul><li>Not performing authorization checks at all </li></ul></ul><ul><ul><li>Using default allow (instead of default deny, which is correct) </li></ul></ul><ul><li>Principle of  least privilege = give users least privilege required to perform their business duties. </li></ul>
  • 41. Authentication &amp; Entitlements (cont.) <ul><li>Fail securely </li></ul><ul><li>Applications regularly fail to process txns for many reasons. How they fail can determine if an application is secure or not. </li></ul><ul><li>For example see below: </li></ul><ul><ul><li>If either codeWhichMayFail() or isUserInRole fails or throws and exception, the user is an admin by default. This is obviously a security risk. </li></ul></ul><ul><ul><li>isAdmin = true; </li></ul></ul><ul><ul><li>try { </li></ul></ul><ul><ul><li>codeWhichMayFail(); </li></ul></ul><ul><ul><li>isAdmin = isUserInRole( “Administrator” ); </li></ul></ul><ul><ul><li>} catch (Exception ex) { </li></ul></ul><ul><ul><li>log.write(ex.toString()); </li></ul></ul><ul><ul><li>} </li></ul></ul>
  • 42. Rule 7 – Use Secure Communication Channels <ul><li>Failure to encrypt network traffic enables it to be sniffed from any compromised system/device on the network. </li></ul><ul><li>Use SSL/TLS for ALL connections that are authenticated or transmitting sensitive information (PII, user credentials, credit card data, etc.) </li></ul><ul><li>Use SSL/TLS for mid-tier and internal network communications between Web Server, Application and database. </li></ul><ul><li>Use only SSLv3 and TLSv1 with strong ciphers. </li></ul><ul><li>Use only valid trusted SSL/TLS certificates and train users to actually expect valid certificates to prevent MITM attacks. </li></ul>
  • 43. Rule 8 – Keep Security Simple <ul><li>Avoid security by obscurity </li></ul><ul><li>Kerchkoffs’ principle (1883) = “the enemy knows the system” </li></ul><ul><li>Linus Torvald’s law = ” many eyes make all bugs shallow”. </li></ul><ul><li>Better security for algorithms and protocols whose details are published.  </li></ul><ul><li>Examples of exploits: Diebold election systems , Skype, chessclub.com, etc. </li></ul>
  • 44. Recap : the 8 rules <ul><li>Use proper cryptography </li></ul><ul><li>Validate all input </li></ul><ul><li>Sanitize data sent to other systems </li></ul><ul><li>Avoid information leakage </li></ul><ul><li>Proper session management </li></ul><ul><li>Authentication and entitlements </li></ul><ul><li>Use secure communication channels </li></ul><ul><li>Keep security simple </li></ul>
  • 45. Often the easiest way to break security is to circumvent it rather than defeat it. Parting Thought

×