code review for secure web applications
TRANSCRIPT
Code Review for Secure Web Applications
With java samples
Bibliography
• OWASP – Open web applications security projects – www.owasp.org
• OWASP Code review guide
Introduction
• Code reviews:– Ad hoc reviews– Pair programming– Walkthrough– Team review– Inspection
• Purpose – security
Code review strategies
• Automatic• Manual – use checklists– Risk based– Most encountered programming mistakes– Mitigation of most encountered vulnerabilities
exploited in the world– Security best practices
Checklist based on best practices
• Authentication• Authorization• Session management• Input validation and output sanitization
Checklist based on best practicesTo be presented next meeting
• Prevent Cross Site Request Forgery• Cryptographic controls• Error handling• Logging• Prevent Race conditions
Authentication
• Check user is not allowed to choose weak passwords
Bad:String password = request.getParameter("Password"); if (password == Null) {throw InvalidPasswordException()
}
Authentication• Check user is not allowed to choose weak
passwordsOK:if password.RegEx([a-z])
and password.RegEx([A-Z]) and password.RegEx([0-9]) and password.RegEx({8-30}) and password.RexEX([!"£$%^&*()])
return true;elsereturn false;
Authentication
• Password storage strategy: hashing using a one-way hash algorithm + salting
OK hashing:import java.security.MessageDigest; public byte[] getHash(String password) throws
NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); byte[] input = digest.digest(password.getBytes("UTF-8"));
}
Authentication• Password storage strategy: hashing using a one-way
hash algorithm + saltingOK salting:import java.security.MessageDigest; public byte[] getHash(String password, byte[] salt) throws
NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset(); digest.update(salt); return digest.digest(password.getBytes("UTF-8"));
}
Authorization
• Check the access roles matrix and make sure it is created respecting the need-to-know and least-privilege principle
• Check the business logic for errorsBad:if user.equals("NormalUser")
{ grantUser(Normal_Permissions); } else{ //user must be admin/super
grantUser("Super_Permissions); }
Authorization• Check if security by obscurity is used• Check if authorization is verified for every requestGood:String action = request.getParameter("action"); if (action.equals("doStuff")) boolean permit = session.authTable.isAuthorised(action); if (permit) doStuff(); else{
throw new (InvalidRequestException("Unauthorised request"); session.invalidate();
}
Session Management
• Check if only framework’s session manager is used
• Check the cryptographic strength, the length of the sessions and character pool
• Check that sessionIds coming from clients are validated
• Check there is a timeout implemented for idle sessions
• Check session is destroyed on logout
Input validation and output sanitization
• Ensure 2 separate validations occur: first a security validation, then a business validation
• Ensure in the security validation, data are canonicalized first
public static void main(String[] args) { File x = new File("/cmd/" + args[1]); String absPath = x.getAbsolutePath(); String canonicalPath = x.getCanonicalPath();}
Input validation and output sanitization
• Check that all input that traversed untrusted zones is validated, not only user input
• Check that validators or sanitizers are adapted for the modules that receives/uses data – encode, escape, etc
• Check validators are applied in a safe side (never client side)
Input validation and output sanitization
public class DoStuff { public String executeCommand(String userName) { try {
String myUid = userName; Runtime rt = Runtime.getRuntime(); rt.exec("cmd.exe /C doStuff.exe " +”-“ +myUid);
}catch(Exception e) { e.printStackTrace(); } } }
Input validation and output sanitization
String myQuery = “select food from foods where name=?”;
String sortOrder=request.getParameter(“order”);myQuery+=sortOrder;PreparedStatement preparedStatement =
connection.prepareStatement(myQuery);preparedStatement.setString(1, “Shaorma”);ResultSet resultSet =
preparedStatement.executeQuery();
Input validation and output sanitization
import java.io.*;import javax.servlet.http.*;import javax.servlet.*; public class HelloServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse
res) throws ServletException, IOException { String input = req.getHeader(“USERINPUT”); PrintWriter out = res.getWriter(); out.println(Server.HTMLEncode(input)); out.close();
}}
Thank you for the interest
Questions?
Prevent Cross Site Script Forgery
Cryptographic controls
Error handling
Logging
Prevent Race Conditions