Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Session Number Presentation_ID Secure Web Coding w/Java Martin Nystrom, CISSP Security Architect Cisco Systems, Inc.

Similar presentations


Presentation on theme: "1 Session Number Presentation_ID Secure Web Coding w/Java Martin Nystrom, CISSP Security Architect Cisco Systems, Inc."— Presentation transcript:

1 1 Session Number Presentation_ID Secure Web Coding w/Java Martin Nystrom, CISSP Security Architect Cisco Systems, Inc. mnystrom@cisco.com

2 222

3 333 Who am I? Security Architect in Cisco’s InfoSec Responsible for consulting with application teams to secure their architecture Monitor for infrastructure vulnerabilities Infrastructure security architect 12 years developing application architectures Java programmer Master of Engineering – NC State University (2003) Bachelor’s - Iowa State University – (1990)

4 444 Outline Introduction to web hacking Web architecture Principles of secure programming Top 10 web vulnerabilities from OWASP

5 555 Secure development stats Research conducted by MIT and @stake Fixing defects during testing is 7 times cheaper than during development ROI of fixing bugs Testing: 12% ROI Implementation: 15% ROI Design: 21% ROI

6 666 95% of web apps have vulnerabilities Cross-site scripting (80 per cent) SQL injection (62 per cent) Parameter tampering (60 per cent) Cookie poisoning (37 per cent) Database server (33 per cent) Web server (23 per cent) Buffer overflow (19 per cent)

7 777 Why worry? Net worm using Google to spread “…uses a flaw in the widely used community forum software known as the PHP Bulletin Board (phpBB) to spread…” California reports massive data breach “…The compromised system had the names, addresses, phone numbers, social security numbers, and dates of birth of everyone who provided or received care.” Google bug exposes e-mail to hackers “…By altering the "From" address field of an e-mail sent to the service, hackers could potentially find out a user's personal information, including passwords....'' truckstop.com web application stolen by competitor “…Getloaded's officers also hacked into the code Creative used to operate its website.”

8 888 Web server attack Discover Examine the environment Identify open ports Discover types/versions of apps running Banner grabbing Extensions (.jhtml,.jsp, etc.) and directory structures Generate and examine errors Submit ridiculous input to provoke errors (fuzzing) Database errors, stack traces very helpful Find info left behind (source code, comments, hidden fields) Target Login mechanism Input fields Session mgmt Infrastructure

9 999 A word of warning These tools and techniques can be dangerous The difference between a hacker and a cracker is…permission Admins will see strange activity in logs, and come looking for you Authorities are prosecuting even the “good guys” for using these tools

10 10 Security principles of web architecture Practice defense-in-depth Separate services Web server, app server, db server on separate hosts Limit privileges of application user File system (chroot or limit privs to read-only) Database system (limit privileges on tables, schemas, etc.) Privileges of running user (xxtomcat, apache, kobayashi, etc.) Hide secrets Database account passwords Encryption keys Use standard, vetted components, libraries Keep them patched Log, and watch logs for unusual activity Load-test and tune accordingly

11 11 Example web environment Web server Web app transport DB App server (optional) Web client: IE, Mozilla, etc. HTTP reply (HTML, JavaScript, VBScript, etc.) HTTP request Clear- text or SSL Apache IIS Netscape etc. J2EE server ColdFusion Oracle 9iAS etc. Perl C++ CGI Java ASP PHP etc. ADO ODBC JDBC etc. Oracle SQL Server etc. InternetDMZProtected network Internal network AJP IIOP T9 etc.

12 12 Web Application Security database firewall Securing the application Input validationSession mgmtAuthentication AuthorizationConfig mgmtError handling Secure storageAuditing/logging host apps firewall Securing the network Router Firewall Switch host apps host Web server App serverDB server Securing the host Patches/updatesAccountsPorts ServicesFiles/directoriesRegistry ProtocolsSharesAuditing/logging

13 13 OWASP Top 10 Web Application Security Vulnerabilities 1.Unvalidated input 2.Broken access control 3.Broken account/session management 4.Cross-site scripting (XSS) flaws 5.Buffer overflows 6.Injection flaws 7.Improper error handling 8.Insecure storage 9.Denial-of-service 10.Insecure configuration management http://www.owasp.org

14 14 Principles for secure coding Don’t trust input from user Watch for logic holes Leverage common, vetted resources Only give information needed Leverage vetted infrastructure & components Build/test to withstand load Expected load Potential DOS attack

15 15 #1: Unvalidated Input Attacker can easily change any part of the HTTP request before submitting URL Cookies Form fields Hidden fields Headers Input must be validated on the server (not just the client). CoolCarts: http://www.extremelasers.com Countermeasures Code reviews (check variable against list of allowed values, not vice-versa) Don’t accept unnecessary input from user Store in session or trusted back-end store Sanitize input with regex

16 16 #1: Unvalidated input (example) public void doPost(HttpServletRequest req,…) { String customerId = req.getParameter(“customerId”); String sku = req.getParameter(“sku”); String stringPrice = req.getParameter(“price”); Integer price = Integer.valueOf(stringPrice); // Store in the database orderManager.submitOrder(sku,customerId,price); } // end doPost

17 17 #1: Unvalidated input (corrected) public void doPost(HttpServletRequest req,…) { // Get customer data String customerId = req.getParameter(“customerId”); String sku = req.getParameter(“sku”); // Get price from database Integer price = skuManager.getPrice(sku); // Store in the database orderManager.submitOrder(sku,customerId,price); } // end doPost

18 18 #2: Broken access control Usually inconsistently defined/applied Examples Path traversal Forced browsing past access control checks File permissions – may allow access to config/password files Logic flaws Client-side caching Countermeasures Use non-programmatic controls Access control via central container Code reviews

19 19 #2: Broken access control (example) protected void doPost(HttpServletRequest req, HttpServletResponse res) { try { String username = req.getParameter(“USERNAME”); String password = req.getParameter(“PASSWORD”); try { Connection connection = DatabaseUtilities.makeConnection(); PreparedStatement statement = connection.prepareStatement ("SELECT * FROM user_system_data WHERE user_name = ? AND password = ?”); statement.setString(1,username); statement.setString(2,password); ResultSet results = statement.executeQuery(query); results.first(); if (results.getString(1).equals(“”)) { s.setMessage("Invalid username and password entered."); return (makeLogin(s)); } // end results check } catch (Exception e) {} // continue and display the page if (username != null && username.length() > 0) { return (makeUser(s, username, "PARAMETERS")); } // end username test } catch (Exception e) { s.setMessage("Error generating " + this.getClass().getName()); } // end try/catch return (makeLogin(s)); } // end doPost

20 20 #2: Broken access control (solution) How to set up basic authentication on CCX Admin /jsp/admin/* (accessLevel=4) BASIC CCO

21 21 #2: Broken access control (solution) How to set up form authentication on CCX FORM CCO login.jsp error.jsp web.xml file login.jsp

22 22 #3: Broken Account and Session Management Weak user authentication Password-only Easily guessable usernames (admin, etc.) Poorly implemented single sign-on (SSO) Weak resource authentication How are database passwords stored? Review trust relationships between hosts IP address can be spoofed, etc. Countermeasures Use vetted single sign-on and session mgmt solution Netegrity SiteMinder RSA ClearTrust Strong passwords Remove default user names Protect sensitive files

23 23 #3: Broken account/session management (client example - SSO) public void doGet(HttpServletRequest req,…) { // Get user name String userId = req.getRemoteUser(); Cookie ssoCookie = new Cookie(“userid”,userId); ssoCookie.setPath(“/”); ssoCookie.setDomain(“cisco.com”); response.addCookie(ssoCookie); … }

24 24 #3: Broken account/session management (server example - SSO) public void doGet(HttpServletRequest req,…) { // Get user name Cookie[] cookies = req.Cookies(); for (i=0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals(“ssoCookie”)) { String userId = cookie.getValue(); HttpSession session = req.getSession(); session.setAttribute(“userId”,userId); } // end if } // end for } // end doGet

25 25 #3: Broken account/session management (client solution - SSO) public void doGet(HttpServletRequest req,…) { // Get user name String userId = req.getRemoteUser(); encryptedUserId = Encrypter.encrypt(userId); Cookie ssoCookie = new Cookie(“userid”,encrypteduserId); ssoCookie.setPath(“/”); ssoCookie.setDomain(“cisco.com”); response.addCookie(ssoCookie); … }

26 26 #3: Broken account/session management (server solution - SSO) public void doGet(HttpServletRequest req,…) { // Get user name Cookie[] cookies = req.Cookies(); for (i=0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals(“ssoCookie”)) { String encryptedUserId = cookie.getValue(); String userId = Encrypter.decrypt(encryptedUserId); if (isValid(userId)) { HttpSession session = req.getSession(); session.setAttribute(“userId”,userId); } } // end if } // end for } // end doGet

27 27 #4: Cross-Site Scripting (XSS) Attacker… Inject code into web page that is then displayed to user in the browser Uses trusted application/company to reflect malicious code to end-user Can “hide” the malicious code w/unicode Vulnerable anywhere user-supplied data is redisplayed w/out input validation or output encoding 2 types of attacks: stored & reflected Can steal cookies, especially vulnerable on apps with form-based authentication Countermeasures Input validation White-listing: a-z, A-Z, 0-9, etc.) Black-listing: “ ( ) # &” Don’t forget these: “< > ( ) # &” Output encoding (htmlEncode output) Truncate input fields to reasonable length

28 28 #4: Cross-site scripting (flaw) protected void doPost(HttpServletRequest req, HttpServletResponse res) { String title = req.getParameter(“TITLE”); String message = req.getParameter(“MESSAGE”); try { connection = DatabaseUtilities.makeConnection(s); PreparedStatement statement = connection.prepareStatement (“INSERT INTO messages VALUES(?,?)”); statement.setString(1,title); statement.setString(2,message); statement.executeUpdate(); } catch (Exception e) { … } // end catch } // end doPost

29 29 #4: Cross-site scripting (solution) private static String stripEvilChars(String evilInput) { Pattern evilChars = Pattern.compile(“[^a-zA-Z0-9]”); return evilChars.matcher(evilInput).replaceAll(“”); } protected void doPost(HttpServletRequest req, HttpServletResponse res) { String title = stripEvilChars(req.getParameter(“TITLE”)); String message = stripEvilChars(req.getParameter(“MESSAGE”)); try { connection = DatabaseUtilities.makeConnection(s); PreparedStatement statement = connection.prepareStatement (“INSERT INTO messages VALUES(?,?)”); statement.setString(1,title); statement.setString(2,message); statement.executeUpdate(); } catch (Exception e) { … } // end catch } // end doPost

30 30 #5 Buffer overflow errors Not generally an issue with Java apps Avoid use of native methods Especially from untrusted sources

31 31 #6: Injection flaws Allows attacker to relay malicious code in form variables or URL System commands SQL Typical dangers Runtime.exec() to external programs (like sendmail) Dynamically concatenated SQL statements Examples Path traversal: “../ ” Add more commands: “ ; rm –r * ” SQL injection: “ ’ OR 1=1 ” Countermeasures Use PreparedStatements in SQL Avoid Runtime.exec() calls (use libraries instead) Run with limited privileges Filter/validate input

32 32 #6: SQL injection (flaw) protected void doPost(HttpServletRequest req, HttpServletResponse res) { String query = "SELECT userid, name FROM user_data WHERE accountnum = '" + req.getParameter(“ACCT_NUM”) + “’”; PrintWriter out = res.getWriter(); // HTML stuff to out.println… try { connection = DatabaseUtilities.makeConnection(s); Statement statement = connection.createStatement(); ResultSet results = statement.executeQuery(query); while (results.next ()) { out.println(" “ + rset.getString(1) + “ ”); out.println(" “ + rset.getString(2) + “ ”); } // end while } catch (Exception e) { // exception handling… } // end catch } // end doPost

33 33 #6: SQL injection (fix) protected void doPost(HttpServletRequest req, HttpServletResponse res) { PrintWriter out = res.getWriter(); // HTML stuff to out.println… try { connection = DatabaseUtilities.makeConnection(s); PreparedStatement statement = connection.prepareStatement ("SELECT userid, name FROM user_data WHERE accountnum = ?“); statement.setString(1,req.getParameter(“ACCT_NUM”); ResultSet results = statement.executeQuery(query); while (results.next ()) { out.println(" “ + rset.getString(1) + “ ”); out.println(" “ + rset.getString(2) + “ ”); } // end while } catch (Exception e) { // exception handling… } // end catch } // end doPost

34 34 #7: Improper error handling Examples: stack traces, DB dumps Helps attacker know how to target the app Often left behind during programmer debugging Inconsistencies can be revealing “File not found” vs. “Access denied” Gives insight into source code Logic flaws Default accounts, etc. Good messages give enough info to user w/o giving too much info to attacker Countermeasures Code review Modify default error pages (404, 401, etc.) Log details to log files, not returned in HTTP request

35 35 Error messages example

36 36 #7: Improper error handling (flaw) protected void doPost(HttpServletRequest req, HttpServletResponse res) { String query = "SELECT userid, name FROM user_data WHERE accountnum = '" + req.getParameter(“ACCT_NUM”) + “’”; PrintWriter out = res.getWriter(); // HTML stuff to out.println… try { connection = DatabaseUtilities.makeConnection(s); Statement statement = connection.createStatement(); ResultSet results = statement.executeQuery(query); while (results.next ()) { out.println(" “ + rset.getString(1) + “ ”); out.println(" “ + rset.getString(2) + “ ”); } // end while } catch (Exception e) { e.printStackTrace(out); } // end catch } // end doPost

37 37 #7: Improper error handling (solution) protected void doPost(HttpServletRequest req, HttpServletResponse res) { String query = "SELECT userid, name FROM user_data WHERE accountnum = '" + req.getParameter(“ACCT_NUM”) + “’”; PrintWriter out = res.getWriter(); // HTML stuff to out.println… try { connection = DatabaseUtilities.makeConnection(s); Statement statement = connection.createStatement(); ResultSet results = statement.executeQuery(query); while (results.next ()) { out.println(" “ + rset.getString(1) + “ ”); out.println(" “ + rset.getString(2) + “ ”); } // end while } catch (Exception e) { Logger logger = Logger.getLogger(); logger.log(Level.SEVERE,”Error retrieving account number”,e); out.println(“Sorry, but we are unable to retrieve this account”); } // end catch } // end doPost

38 38 #8: Insecure storage Sensitive data such as credit cards, passwords, etc. must be protected Examples of bad crypto Poor choice of algorithm Poor randomness in sessions/tokens Storage locations must be protected Database Files Memory Countermeasures Store only what you must Store a hash instead of the full value if you can (SHA-1, for example) Use only vetted, public cryptography

39 39 #8: Insecure storage – bad example public String encrypt(String plainText) { plainText = plainText.replace(“a”,”z”); plainText = plainText.replace(“b”,”y”); … return Base64Encoder.encode(plainText); }

40 40 #8: Insecure storage – fixed example public String encrypt(String plainText) { // Read encryptKey as a byte array from a file DESKeySpec keySpec = new DESKeySpec(encryptKey); SecretKeyFactory factory = new SecretKeyFactory.getInstance(“DES”); SecretKey key = factory.generateSecret(keySpec); Cipher cipher = Cipher.getInstance(“DES”); cipher.init(Cipher.ENCRYPT_MODE,key); byte[] utf8text = plainText.getBytes(“UTF8”); byte[] enryptedText = ecipher.doFinal(utf8text); return Base64Encoder.encode(encryptedText); }

41 41 #9: Denial-of-service (DoS) Examples that may provoke DoS Heavy object allocation/reclamation Overuse of logging Unhandled exceptions Unresolved dependencies on other systems Web services Databases May impact other applications, hosts, databases, or network itself Countermeasures Load testing Code review

42 42 #10: Insecure configuration management Tension between “work out of the box” and “use only what you need” Developers ≠ web masters Examples Unpatched security flaws (BID example) Misconfigurations that allow directory traversal Administrative services accessible Default accounts/passwords Countermeasures Create and use hardening guides Turn off all unused services Set up and audit roles, permissions, and accounts Set up logging and alerts

43 43 Principles for secure coding Don’t trust input from user Watch for logic holes Leverage common, vetted resources Only give information needed Leverage vetted infrastructure & components Build/test to withstand load Expected load Potential DOS attack

44 44 Tools used in this preso WebGoat –vulnerable web applications for demonstrationWebGoat VMWare – runs Linux & Windows 2000 virtual machines on demo laptop.VMWare nmap –host/port scanning to find vulnerable hostsnmap Mozilla Firefox – browser that supports plug-ins for proxied HTTP, source browsing SwitchProxy plug-in lets you quickly switch your proxies WebDeveloper plug-in lets you easily clear HTTP auth WebScarab – HTTP proxy

45 45 Backup slides & old slides

46 46 #9: Remote Administration Flaws Problems Weak authentication (username=“admin”) Weak encryption Countermeasures Don’t place admin interface on same server Use strong authentication: certificates, tokens, strong passwords, etc. Encrypt entire session (VPN or SSL) Control who has accounts IP restrictions

47 47 #7: Fail open authentication – code fix protected void doPost(HttpServletRequest req, HttpServletResponse res) { try { String username = req.getParameter(“USERNAME”); String password = req.getParameter(“PASSWORD”); try { Connection connection = DatabaseUtilities.makeConnection(); PreparedStatement statement = connection.prepareStatement ("SELECT * FROM user_system_data WHERE user_name = ? AND password = ?”); statement.setString(1,username); statement.setString(2,password); ResultSet results = statement.executeQuery(query); if (results == null || !results.first()) { s.setMessage("Invalid username and password entered."); return (makeLogin(s)); } // end results check } catch (Exception e) {} // continue and display the page if (username != null && username.length() > 0) { return (makeUser(s, username, "PARAMETERS")); } // end username test } catch (Exception e) { s.setMessage("Error generating " + this.getClass().getName()); } // end try/catch return (makeLogin(s)); } // end doPost

48 48 #10: Insecure configuration management Tension between “work out of the box” and “use only what you need” Developers ≠ web masters Examples Unpatched security flaws (BID example) Misconfigurations that allow directory traversal Administrative services accessible Default accounts/passwords Countermeasures Create and use hardening guides Turn off all unused services Set up and audit roles, permissions, and accounts Set up logging and alerts

49 49 #3 bad example of session id generation // Tomcat version 1 (JServ) // public class SessionIdGenerator { private static int counter = 1010; public static synchronized String generateId() { Integer i = new Integer(counter++); StringBuffer buf = new StringBuffer(); String dString = Double.toString(Math.abs(Math.random())); buf.append("To"); buf.append(i); buf.append("mC"); buf.append(dString.substring(2, dString.length())); buf.append("At"); return buf.toString(); } }

50 50 #3 fixed example session id generation public class SessionIdGenerator { static private int session_count = 0; static private long lastTimeVal = 0; static private java.util.Random randomSource = new java.security.SecureRandom(); // MAX_RADIX is 36 public final static long maxRandomLen = 2176782336L; // 36 ** 6 public final static long maxSessionLifespanTics = 46656; // 36 ** 3 public final static long ticDifference = 2000; static synchronized public String getIdentifier (String jsIdent) { StringBuffer sessionId = new StringBuffer(); // random value.. long n = randomSource.nextLong(); if (n < 0) n = -n; n %= maxRandomLen; n += maxRandomLen; sessionId.append (Long.toString(n, Character.MAX_RADIX).substring(1)); long timeVal = (System.currentTimeMillis() / ticDifference); // cut.. timeVal %= maxSessionLifespanTics; // padding, see above timeVal += maxSessionLifespanTics; sessionId.append (Long.toString (timeVal, Character.MAX_RADIX).substring(1)); if (lastTimeVal != timeVal) { lastTimeVal = timeVal; session_count = 0; } sessionId.append (Long.toString (++session_count, Character.MAX_RADIX)); if (jsIdent != null && jsIdent.length() > 0) { return sessionId.toString()+"."+jsIdent; } return sessionId.toString(); } public static synchronized String generateId() { return getIdentifier(null); } }

51 51 #4: Bad example – output vuln to XSS protected void doGet(HttpServletRequest req, HttpServletResponse res) { int messageNum = Integer(res.getParameter(NUMBER)).intValue(); String title, message; try { PreparedStatement statement = connection.prepareStatement ("SELECT title,message FROM messages WHERE num = ?“); statement.setInt(1,messageNum); ResultSet results = statement.executeQuery(query); title = results.getString(1); message = results.getString(2); } catch(Exception e) { // exception handling } PrintWriter out = response.printWriter(); res.setContentType(“text/html”); PrintWriter out = res.getWriter(); // HTML page formatting out.println(title + “ - “ + message); }

52 52 #4: Good example – output vuln to XSS protected void doGet(HttpServletRequest req, HttpServletResponse res) { int messageNum = Integer(res.getParameter(NUMBER)).intValue(); String title, message; try { PreparedStatement statement = connection.prepareStatement ("SELECT title,message FROM messages WHERE num = ?“); statement.setInt(1,messageNum); ResultSet results = statement.executeQuery(query); title = results.getString(1); message = results.getString(2); } catch(Exception e) { // exception handling } PrintWriter out = response.printWriter(); res.setContentType(“text/html”); PrintWriter out = res.getWriter(); // HTML page formatting out.println(htmlEncode(title + “ - “ + message)); }


Download ppt "1 Session Number Presentation_ID Secure Web Coding w/Java Martin Nystrom, CISSP Security Architect Cisco Systems, Inc."

Similar presentations


Ads by Google