Common Web Security Issues and Tips on How to Overcome Them

Common Web Security Issues and Tips on How to Overcome Them

When we are talking about web, security is not for granted. Every day we read about (or worse: experience) systems getting compromised or data being lost as a result of attacks or negligence.With theses slides I try to alert about some of the most common or dangerous problems I could think of.

5733fd332f2a0da11931e0e73ddfb20d?s=128

Henrique Vicente

July 31, 2012
Tweet

Transcript

  1. Common Web Security Issues and Tips on How to Overcome

    Them When we are talking about web, security is not for granted. Every day we read about (or worse: experience) systems getting compromised or data being lost as a result of attacks or negligence. With theses slides I try to alert about some of the most common or dangerous problems I could think of. Henrique Vicente de Oliveira Pinto Tuesday, July 31, 2012 Recife, Brazil https://github.com/henvic/ http://twitter.com/henriquev henriquevicente@gmail.com 1 Tuesday, July 31, 12
  2. First web server 2 Tuesday, July 31, 12

  3. HTTP • stateless protocol • each request is unique -

    even for persistence connections - even for different hosts on the same IP 3 Tuesday, July 31, 12
  4. Cookies 4 Tuesday, July 31, 12

  5. HTTP Cookie • small piece of persistent data shared between

    client and server • reliable mechanism to track the user (i.e., authentication) • but... 5 Tuesday, July 31, 12
  6. 6 Tuesday, July 31, 12

  7. Security concerns • The HTTP Cookie architecture is “not designed

    for security” • You have to take proper care about securing your system 7 Tuesday, July 31, 12
  8. Bad Cookie Example • sensitive consumer data (credit card) on

    store.product.com • blog powered on product.com, by Wordpress - Wordpress is not designed to be PCI DSS compliant - risk: example.com can read/write cookies for store.example.com 8 Tuesday, July 31, 12
  9. Content Delivery Network • A content delivery network (CDN) is

    a collection of web servers distributed across multiple locations to deliver content more efficiently to users (low latency, high data transfer speeds, reliability). 9 Tuesday, July 31, 12
  10. Some popular CDNs • a*.twimg.com for twitter.com • th*.deviantart.net for

    deviantart.com • farm*.staticflickr.com for flickr.com 10 Tuesday, July 31, 12
  11. Principle of least privilege • *.fbcdn.net for twitter.com Notice the

    different domain. Most browsers limit the amount of connections per domain. The trade-off is just a additional DNS-lookup. • You can set cookies for your *.domain (subdomains) and still your cookies doesn’t get sent to your CDN 11 Tuesday, July 31, 12
  12. Herd of elePHPants 12 Tuesday, July 31, 12

  13. Sessions • Way to store certain client data on the

    server-side across multiple requests • Uniquely identified by some form or another: - cookies - URL params (come again?) 13 Tuesday, July 31, 12
  14. http://pa.ge/?SID=aa7d8abb7 • URI params are evil: - Prone to unintentional

    disclosure, injection, etc. - If you see anything like SID= or session_id= on the URI params chances are the page you’re accessing is compromised • POST-based sessions is not a solution & breaks the REST paradigm. • You must only accept cookies-based sessions. 14 Tuesday, July 31, 12
  15. Security tips for PHP • Make sure session.use_trans_sid is disabled

    • Make sure session.use_cookies is enabled (if you want it) • Use the least release of PHP (that means 5.4 as of July 2012) - if you use must use earlier versions, make sure register_globals is turned off and (of course) safe_mode is on. 15 Tuesday, July 31, 12
  16. eval() is evil (in any language) • If you are

    using eval() there is almost certainly a better approach • If eval() is the response, you’re almost certainly making the wrong question • eval() is slow • eval() is dangerous - real-life example I’ve seen: routing system - “hey, why can’t I have a page called /exit?”: (exit = reserved word) 16 Tuesday, July 31, 12
  17. Securing your sessions • Session fixation issue: 1. user sets

    a cookie with the fake session id for someone else 2. the victim access the website with that given cookie, which is accepted, and his account is taken over remotely. • Solution: Only accept session IDs created by yourself (i.e., initialize it with a custom data: if someone doesn’t have it, destroy the cookie and create a new session for the user) 17 Tuesday, July 31, 12
  18. Prevent session fixation • Don’t reuse sessions. After any significant

    change (such as login or logout), generate a new session id: i.e., session_regenerate_id(); Otherwise, a user might use a computer and note down the current session, then go away and keep testing until someone else has logged in and hijack the account. 18 Tuesday, July 31, 12
  19. More on session hijacking • Set-Cookie with the HttpOnly flag

    might help you with avoiding script kiddies trying XSS attacks to hijack your cookies due to a bad implemented HTML sanitizer or something. It tells (some modern browsers which implements it) that the cookie should be accessed only by the server, not by the client. Might help, but it gives you a false sense of security. 19 Tuesday, July 31, 12
  20. Supercookie 20 Tuesday, July 31, 12

  21. Supercookie • If a www.example.com or store.product.com can read/write a

    cookie for example.com, why can’t it write for .com? Or... Can it? 21 Tuesday, July 31, 12
  22. Supercookie • Not tasty • Public Suffix List saves the

    day by letting browsers know if someone is trying to set a super-cookie or not. - A "public suffix" is one under which Internet users can directly register names: i.e., .com, .co.uk, and .com.br http://publicsuffix.org/ 22 Tuesday, July 31, 12
  23. Zombie cookie 23 Tuesday, July 31, 12

  24. Zombie cookie • A cookie that comes back 1. its

    data is also stored with localStorage or another way 2. when erased, it is recreated • Please, don’t use it. 24 Tuesday, July 31, 12
  25. How the DNS works • Solving a name to a

    IP(s) may involve: - desired service (HTTP, mail server, samba, etc) - geolocation - available resources - load balancing - etc 25 Tuesday, July 31, 12
  26. How the DNS works • Shared nothing architecture - it

    is not centralized. Instead, several it’s a network of several servers world-wide working together, alone. There is not a single point of failure so it is fast and reliable. 26 Tuesday, July 31, 12
  27. DNS cache poisoning • A “rogue” DNS server may contain

    wrong information - this may help either by configuration problem or intentionally • So a compromised DNS server may, for example, make your connection to a website fail or... Someone might route your traffic trough a proxy and listen to your traffic, hijacking your session ids, etc. 27 Tuesday, July 31, 12
  28. Sniffing: eavesdropping • Unencrypted data (such as regular HTTP) can

    be easily listened to. • In physical connected network: might be expensive, work intensive, might leave traces and be more complicated. • But what about the wi-fi hotspot on your preferred café? 28 Tuesday, July 31, 12
  29. Sniffing: eavesdropping • Wi-fi is not secure by design. Encrypted

    network? Good. But if your passphrase is know by the attacker, you’re compromised. • A weak passphrase may also be easily discovered by eavesdropping. 29 Tuesday, July 31, 12
  30. How to fix it? • Encrypted traffic is the way.

    • You can tunnel YOUR data to a secure tunnel at home. - Make sure your tunnel is secure - is your home a safe heaven? - what about the data that goes beyond it? - it fixes the problem of wi-fi eavesdropping, but is not good enough for everything. • What about your users and sensitive info? 30 Tuesday, July 31, 12
  31. HTTPS = HTTP + SSL/TLS • A combination of protocols

    • Reduces the points of failure • Renders the man-in-the-middle attacks inefficient • Renders DNS poisoning attacks (alone) inefficient • TLS = evolution of SSL • Limitation: no more than one validly certified secure web site on a IP due to the HTTPS protocol design. 31 Tuesday, July 31, 12
  32. HTTPS = HTTP + SSL/TLS • Keep in mind: you

    are using a secure protocol for a reason • This means: your JavaScript, CSS, and images should also use HTTPS • At least your JS (given that’s a programming client-side script) and private images or files associated with your system (not part of the layout). 32 Tuesday, July 31, 12
  33. Secure cookie • Set-Cookie with the Secure flag (over the

    HTTPS, of course) • So it is not sent over a insecure (regular HTTP) connection. • Otherwise if your user connect over regular HTTP the cookie data is compromised. 33 Tuesday, July 31, 12
  34. How the HTTPS protocol works • We have Certificate Authorities

    (CAs): - VeriSign - Thawte - RSA Security - Cisco - AOL Time Warner - (many others...) 34 Tuesday, July 31, 12
  35. About certificates • A Certificate Authority is a entity that

    issues digital certificates • Most browsers have the root certificate of a dozen of CAs • A certificate is a document which can be used to verify that a public key belongs to an individual 35 Tuesday, July 31, 12
  36. About certificates • Not every certificate is the same. There

    are different levels of certificates. • A certificate is (hopefully) signed by a recognized CA root certificate and checked against its invalidation list • A certificate can be self-signed (stupid, not recommended, and useful) • They have expiration dates 36 Tuesday, July 31, 12
  37. Extended Validation (EV) Certificate • Extensive verification of identity before

    emitting the certificate to the requester • No more secure than a non-EV certificate • Might make part of your address bar green, etc. 37 Tuesday, July 31, 12
  38. Certificates • Software vendors (like Apple or Ubuntu) trusts the

    most appreciated CAs and embed their public keys in their systems. If you are a incompetent CA you’re out of the market (hopefully). • You trust your browser & operational system • You check the identity to whom the certificate belongs to (don’t you?) 38 Tuesday, July 31, 12
  39. Certificates for intranet • If you have a certificate for

    http://secret-docs.intranet/ you’re doing it wrong: - There might be others secret-docs.intranet on others intranets, including the one from the bad guy wanting to steal your data • Sadly, some CAs does emit certificates for them • You’d have to read the certificate document each time before allowing your browser to send sensitive data (session IDs, anyone?) to the requesting server: not gonna happen. 39 Tuesday, July 31, 12
  40. Fixing your intranet server security • http://secret-docs.intranet.your-domain.example.com/ • You can

    still restrict it to be accessible only inside the intranet, but now it is now safer (just be aware of wildcard SSL certificates which you don’t want to trust). 40 Tuesday, July 31, 12
  41. Deploying your website or app • Are you still using

    FTP? - Don’t. 41 Tuesday, July 31, 12
  42. FTP is... • really slow • insecure • complicated, prone

    to errors 42 Tuesday, July 31, 12
  43. Great deployment tools • WebDAV over HTTPS (great native support

    in modern machines) • SFTP (based on SSH; and is NOT ‘secure FTP’) • git push • torrent (if you are Facebook, Twitter, and the like - and know what you’re doing this is almost certainly the best option) 43 Tuesday, July 31, 12
  44. Sending email • Does your mail sender have proper permission?

    Like... MX records for the domain you are sending? SPF1, SPF2 maybe? • If you don’t, it may end up as Spam. 44 Tuesday, July 31, 12
  45. Sending email • Don’t keep the user waiting: - Queue

    the message with a local relay • Using PHP? Do yourself a favor and avoid mail(); - for security, simplicity, and performance - use PEAR Mail_Mime or Zend_mail 45 Tuesday, July 31, 12
  46. Text Encoding • UTF-8 is here to stay • you

    must adopt UTF-8 or you lose consumers • however... 46 Tuesday, July 31, 12
  47. Intelligent UTF-8 • Adopt with care: • you don’t want

    two usernames like: “frédéric” and “frederic” - (just the second if you don’t mind, please). • But you want different passwords to be different: “n” is not “ñ” - (ok, don’t use single-letters for passwords) 47 Tuesday, July 31, 12
  48. txt.evihcra.exe = exe.archive.txt? • UTF-8 has tricky control characters like

    one which shows the text inverted • for example: it might make someone execute a file thinking it is just a text file, when it actually is a binary one 48 Tuesday, July 31, 12
  49. UTF-8 is tricky • bad encoded UTF-8 with invalid byte

    sequences is also a headache • Byte order mark (“”) on top of your PHP files makes you insane: - “how come the headers are already sent?” or - “why is this JSON invalid in this browser and not in that one?” anyone...? 49 Tuesday, July 31, 12
  50. UTF-8 is tricky • There is more than half a

    dozen reasons why you use a IDE, or a great text editor. • Don’t use Wordpad or Notepad to make a quick change on your code, please. BOM (0xEF, 0xBB, 0xBF) will happen. • And check what you commit (you do versioning right, don’t you?) and if you see something weird or unexpected... Do something about it. 50 Tuesday, July 31, 12
  51. User input data • On PHP: - Zend_Form, Zend_Filter, and

    Zend_Validate forms a great toolkit (a loosely coupled one) • Always filter and validate each data entry 51 Tuesday, July 31, 12
  52. What a filter should do • Filtering in action: -

    telephone: input: "700-7202222", output: "+1-700-720-2222" - name: input: " Henrique Pinto ", output: "Henrique Pinto" - price: input: "0.51 ", output: "$0.51 USD" • Filter might strip whitespaces, normalize input, etc. 52 Tuesday, July 31, 12
  53. What a validator should do • Checks if the given

    data (post-filtered) is valid • If not valid: - give feedback telling why it didn’t pass • Examples: - telephone: "+1" (error: incomplete phone number) - price: "" (error: price is required, price can not be empty) - price: "0" (not a error: product is free) 53 Tuesday, July 31, 12
  54. Don’t mix unfiltered with filtered data • $result = array(

    "filtered" => array( "name" => "Nick", "seat" => "4H" ), "unfiltered" => array( "name" => "Nick\n", "seat" => "4 h" ), "validate" => array( "name" => true, "seat" => array("errors" => array("invalid-seat")) ) ); • Keep them explicitly apart. 54 Tuesday, July 31, 12
  55. Filtered data != escaped data • NOT 55 Tuesday, July

    31, 12
  56. Sanitize on input, escape on output • Take a whitelist

    approach (rather than a blacklist one): - parsing HTML is more complicated than what seems. - HtmlPurifier is a great (the best?) HTML parser library for PHP Just make sure to cache it. Sadly it is a little bit complicated and not good with internationalized URIs. - don’t build your own parser (unless the parser itself is your goal) • i.e., phone number - first character may be “+”, others are digits (and no more than ~20) • escape at each step: SQL, HTML, JSON, BASH, Regex, XML, etc. - escaping isn’t magic, each step requires different types of escaping 56 Tuesday, July 31, 12
  57. Sanitize on input, escape on output • know your tools

    - MySQL is way more permissive (in the bad sense) than Postgresql - try to add “test” to a char(2) field on a MySQL DB: - it will save “te”, Postgresql would fail emitting a notice that the data is larger than the space of the field. • Don’t take external APIs data for granted, take the same care with them as you would with user input data 57 Tuesday, July 31, 12
  58. User input data: Null-Byte Attack • PHP uses C functions

    for FS calls for which null-byte = end of string • http://example.com/place?inc=../../../etc/passwd%00ignored if we try to read a file with the inc param, we read: "../../../etc/passwd" instead of "../../../etc/passwd/%00ignored". Fix: remove the null-byte: str_replace(chr(0), "", $param); Checking for "../" might seem “good enough”, but defense in depth >> “good enough”. • Note: in my tests if the %00 was in path part Apache and nginx returned a Bad Request page, but if you have this issue, fix it anyways. More on https://github.com/henvic/MediaLab/issues/9 58 Tuesday, July 31, 12
  59. Common problem with PHP + MySQL • Problematic: "SELECT *

    WHERE user = " . addslashes($username); addslashes() is useless. Use the proper functions available for the database adaptor you are currently using. • Fixing with PDO: $sth = $dbh->prepare("SELECT * WHERE user = :username"); $sth->bindParam(":username", $username, PDO::PARAM_STR, 10); * last argument is length 59 Tuesday, July 31, 12
  60. memcached caveats • It doesn’t carry the concept of different

    databases. A prefix in the key part will suffice to fix this limitation: - e.g., keys: session_S929JDLRJ223, cache_page_index, profile_henvic • By default, it allows connection from any client with no authentication. SASL might be used. Strict firewall rules are advised. Sadly many memcached installs on production environments are unprotected. • Same should apply for the fork Twemcache 60 Tuesday, July 31, 12
  61. A safe example • $sth = $dbh->prepare("SELECT * from fruits

    WHERE calories < :calories AND color = :color"); • $sth->bindValue(":calories", $calories, PDO::PARAM_INT); • $sth->bindParam(":color", $color, PDO::PARAM_STR, 10); • $sth->execute(); 61 Tuesday, July 31, 12
  62. Storing passwords: don’t 62 Tuesday, July 31, 12

  63. Storing passwords: don’t • Breaking passwords is each day more

    easily done • Rainbow Tables out there helps cracking passwords easily • Adding a salt helps, but that alone isn’t enough & time-proven • If you are just hashing with MD5, SHA1, SHA256, SHA512, etc you’re doing it wrong. • Even if your system is just a game, remember users are lazy and reuse their passwords from games to banking accounts, so be responsible 63 Tuesday, July 31, 12
  64. Solution • Generic algorithm - that can not be optimized

    with dedicated hardware • Adaptive - as hardware increases you can make it harder / slower with more iterations than before 64 Tuesday, July 31, 12
  65. A Future-Adaptable Password Scheme 65 Tuesday, July 31, 12

  66. bcrypt The original implementation was for OpenBSD 66 Tuesday, July

    31, 12
  67. bcrypt • You can increase the iterations needed to calculate

    if a password matches with a given hash • Rainbow tables are impossible • Implementation for PHP: http://www.openwall.com/phpass/ 67 Tuesday, July 31, 12
  68. Password • Alternatives to bcrypt: - scrypt: slightly more secure,

    seems to be less supported - PBKDF2: less secure • Read about the subject - https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet 68 Tuesday, July 31, 12
  69. Brute-force attacks • Doors to Denial-of-service - compute-intensive password hashing

    methods - compute-intensive actions triggered by the final users - ... • Doors to security compromise - dictionary attacks to your login form - ... • Limit requests at the front-end servers or the application level - i.e., HttpLimitReqModule on nginx, captchas (tip: reCAPTCHA) 69 Tuesday, July 31, 12
  70. Two-factor authentication • Extra protection against unauthorized access • Various

    technologies: - SMS one-time password - Time-based One-time Password Algorithm - Hardware-based (i.e., RSA tokens) - Software-based (i.e., Google Authenticator) • Various implementations, services, and APIs for using with SSH, HTTP(S), etc are available. 70 Tuesday, July 31, 12
  71. Captcha • Completely Automated Public Turing test to tell Computers

    and Humans Apart • It’s intrusive (you don’t want to use everywhere, every single time): - i.e., use [after 3 or 4] failed authentication attempts (even have the great side-effect of throttling down the attack) • A bad implementation might make experience for people with disabilities or accessing via mobile a very bad thing 71 Tuesday, July 31, 12
  72. • Originally developed at Carnegie Mellon University • Acquired by

    Google • Web service for free • Support for blind (with audio), etc • Constantly up-to-date • Use it instead of implementing your own 72 Tuesday, July 31, 12
  73. Panopticlick • How Unique - and Trackable - Is Your

    Browser? • https://panopticlick.eff.org • As it turns out our browsers gives up too much information - even in private mode 73 Tuesday, July 31, 12
  74. HTTP is all about being RESTful • REpresentational State Transfer

    (REST) >> SOAP > WSDL • In theory: HEAD, GET, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH. • In practice: GET and POST are the most popular. • Keep in mind: the standard is all about SHOULD, not MUST. Refer to: “Key words for use in RFCs to Indicate Requirement Levels” http://tools.ietf.org/html/rfc2119 74 Tuesday, July 31, 12
  75. Powerful GET? • GET SHOULD NOT be used for transformation

    / destructive actions. • Why? - It should be used to... get content. - It can be easily forged. - It can be unintentionally / automatically retrieved. • Must use? Add token (hash) + check origin (referrer) + hide link from user + rel="nofollow" + find another way to do so + etc • Really? Isn’t the case for a hidden field in a form or something better? 75 Tuesday, July 31, 12
  76. A word on XML • Prefer JSON over XML -

    Why? - Because is simpler - Less complicated - Easer to parse Only major drawback: - More hard on the human eyes (subjective) 76 Tuesday, July 31, 12
  77. Another word on XML • Forget <![CDATA[ ]]> - Why

    complicate things? Just escape your message the right way. • Use libraries instead of trying to write XML by hand: - PHP: SimpleXML - Not as powerful as DOM, but maybe good enough - Abstraction, easer code, less headaches 77 Tuesday, July 31, 12
  78. Apache and .htaccess • .htaccess is evil - slow -

    reduced I/O + bottleneck on the disk - even insecure - invite for adopting bad practices • A problem: server-side executables / code on the public area - public_html/<project> /index.php /.htaccess /lib/.htaccess ... 78 Tuesday, July 31, 12
  79. PHP(?), Apache and .htaccess • You don’t want your application

    and credentials accessible for the external world: what if Apache is bad configured and doesn’t process your .htaccess or .php (or what else) scripts and gives up your database passwords, APIs keys, etc? • It’s not a safe approach to security • Solution: public/ with only a index.php requiring the application outside of the root public directory. 79 Tuesday, July 31, 12
  80. php.ini + production environment • error_reporting = E_ALL; Caveat: for

    PHP < 5.4 use E_ALL | E_STRICT instead (or: upgrade!) • log_errors = 1; • display_errors = 0; • Important: for development, you almost certainly want: display_errors = 1; unless you’re being a smart guy listening to the error log (i.e., with tail) 80 Tuesday, July 31, 12
  81. Deploying on the shared hosting • Common issues & disturbances:

    - Low performance - Security holes • PHP Suhosin (hardened php project) may be in use • Cheap & Dirty • You decide: it might be worth it 81 Tuesday, July 31, 12
  82. Deploying on the shared hosting • Sessions - storing on

    files? Don’t store on a public place like /tmp • A instance (“virtual machine”) on Amazon Web Services, Slicehost, Rackspace, or Linode is not that expensive and might be a better fit. 82 Tuesday, July 31, 12
  83. Fail-safe systems • failures will happen someday (it’s a fact)

    • graciously fail is less damaging than disasters • shared nothing architecture is a good approach • Minimize the number of single points of failure 83 Tuesday, July 31, 12
  84. What can cause a failure • Configuration • Database •

    Filesystem • APIs • Email systems • Sockets • Software • Releases • Hardware • Power outage • Network outage • ... 84 Tuesday, July 31, 12
  85. a:link, a:visited, etc. • Remember that, by default (HTML with

    no styling), a visited link gets a different color on most browsers? • Now what if you check if someone visited a given address? - this is a privacy breach - modern browsers are starting to work on fixing this • https://developer.mozilla.org/en/CSS/ Privacy_and_the_:visited_selector 85 Tuesday, July 31, 12
  86. On Quality Assurance (QA) • It should be the goal

    of the developer that the QA find nothing wrong • The developer should deliver high quality work. The following helps: - Test-Driven Development (TDD) - Behavior-Driven Development (BDD) - Continuous Integration (CI) - unit tests, behavior testes, unit tests, integration tests - code versioning (git is the most prominent) - issues & bug tracking (i.e., JIRA, GitHub Issue Tracker, etc) 86 Tuesday, July 31, 12
  87. Physical security: not for granted • Lest We Remember: Cold

    Boot Attacks on Encryption Keys https://citp.princeton.edu/research/memory/ http://www.youtube.com/watch?v=6EuUwDvlHz8 • Payment Card Industry Data Security Standard (PCI DSS) https://www.pcisecuritystandards.org/security_standards/ • Adventures with Daisy in Thunderbolt-DMA-land: Hacking Macs through the Thunderbolt interface http://www.breaknenter.org/2012/02/adventures-with-daisy-in- thunderbolt-dma-land-hacking-macs-through-the-thunderbolt- interface/ 87 Tuesday, July 31, 12
  88. Never stop learning • The best way to build rock-solid

    secure apps • Read research papers • Be part of your local user group • Get involved with open source projects: push code on GitHub 88 Tuesday, July 31, 12
  89. Some good resources • Common Vulnerabilities and Exposureses (CVE) http://cve.mitre.org/

    The Open Web Application Security Project https://www.owasp.org/ • Joind.in http://joind.in/ (talks organized by events, very useful) • Voices of the ElePHPant http://voicesoftheelephpant.com/ 89 Tuesday, July 31, 12
  90. Some Images are from • http://www.flickr.com/photos/big-pao/186885653/ • http://windowboyman.deviantart.com/art/Dangerous-cookies-163434282 • http://www.flickr.com/photos/neldorling/2630809618/

    • http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html • http://anenglishwomaninsalem.com/2012/03/15/when-socially-awkward-people-get-invited-to-company-meetings/ • http://www.flickr.com/photos/cookiecanvas/6662258619/ 90 Tuesday, July 31, 12