Secure Code Review Java
-
Upload
dheeraj-singh -
Category
Documents
-
view
112 -
download
3
Transcript of Secure Code Review Java
Aujas Confidential
Cert-In Training Program
for
Government, PSUs and Critical Infrastructure companies
Organized By: Data Security Council of India
Under the Project
Cyber-Security Awareness Program,
(A DIT-NASSCOM Project)
Secure Code Review for Java Applications
20th November 2009
Jaykishan Nirmal
Consultant, Trainer and Forensic Investigator
Aujas Confidential
Disclaimer
The aspects discussed in this presentation are purely my observations and opinions. They may not be necessarily correct, specially when generalization is used.
Incidents, examples, people, organizations etc. are used only to illustrate the points of discussion.
we do not claim any rights on any proprietary content used for illustrations.
Aujas Confidential
Agenda
09:30 Registration and Welcome10:00 Application Code Review Basics10:30 Secure handling of User input in Java based Applications11:15 Pause (15 Minutes)11:30 Session Management in Java based Applications13:00 Lunch Break14:00 Authentication & Authorization in Java web Applications15:30 Pause (15 Minutes)15:45 Secure code review techniques/Methodologies for Java based
Applications17:00 Q&A 17:15 Closing and End
Aujas Confidential
Disclaimer
Famous Buddha Quote-
“Believe nothing, no matter where you
read it, or who said it, no matter if I have
said it, unless it agrees with your own
reason and your own common sense.”
Hence, Whatever I say, may not be “right” but I think, it is “real” and “practical”.
Aujas Confidential
Sun Tzu
“如果你知道敌人知道,你不必担心的结
果,很多的 战役。如果你知道你自己而
不是敌人,取得的每一个胜利你同样会遭
受失败。如果你知道无论是敌人还是自己,
你会屈服于在每一个战役。 “
孙子兵法-孙子兵法
Aujas Confidential
Sun Tzu – Chinese Military General
“If you know the enemy and know yourself,
you need not fear the result of a hundred
battles. If you know yourself but not the
enemy, for every victory gained you will
also suffer a defeat. If you know neither the
enemy nor yourself, you will succumb in
every battle.”
Sun Tzu – The Art of War
Aujas Confidential
Security
Aujas Confidential
What is Security?
Freedom from risk or danger; safety
Freedom from doubt, anxiety, or fear; confidence
Something that gives or assures safety
In the computer industry, refers to techniques for ensuring that datastored in a computer cannot be read or compromised by any individualswithout authorization
A state of well-being of information and infrastructure
Aujas Confidential
Security Terminology
Asset – An asset is a resource of value
Threat – Any undesired event which might compromise the security of an asset.
Vulnerability – Inherent weakness or flaw in the system.
Attack/Exploit – Action that utilizes one or more vulnerabilities to realize athreat.
Adversary – Someone who offers opposition – Opponent
Countermeasure – defense put in place to minimize the impact of threats.
Aujas Confidential
Application Security
Aujas Confidential
Some Statistics
The security of a software-intensive system is directly related to the quality of its software1.
• Over 90% of software security incidents are caused by attackers exploiting known software defects.
• Analysis of 45 e-business applications showed that 70% of security defects were design defects.
• Experienced and capable software engineers unintentionally inject, on average, one defect every nine lines of code.
• A one million line of code systems typically contains 1,000-5,000 defects when shipped.
1 http://www.sei.cmu.edu/tsp/tsp-security.html
Aujas Confidential
SANS Common Coding Errors
Aujas Confidential
Application Security Trends : Q3-Q4 2008
Source: Application Security Trends Report Q3-Q4 2008, Cenzic
Aujas Confidential
Software Development – Perfect World
Aujas Confidential
Software Development – Real World
Aujas Confidential
Cost Matters!
Aujas Confidential
Why to Worry
Applications are protection layer for –
Intellectual Property
Customer/Partner/Employee Private Information
Internet Facing applications expose a greater “attack surface”
Impact/ Ramifications of breaches is high
Laws and Regulations such as HIPAA, SOX, GLBA, DPA, IPR etc.
Financial implications of unauthorized disclosure
Damage to business reputation
System down time
Lost Consumer Confidence
Cost
No Standard Patches Available for Customized Application
Aujas Confidential
Case Study : CardSystems Inc.
Aujas Confidential
Few Millions SQL Injection Attack
Aujas Confidential
Application Security & CIA
Aujas Confidential
Core Principles of Security
Confidentiality
IntegrityAvailability
Aujas Confidential
What is CIA?
• Confidentiality
Confidentiality means prevention of disclosure of information tounauthorized individuals or systems.
• Integrity
Integrity means data cannot be modified without authorization
• Availability
Availability means Information should be available whenever needed orrequested.
Aujas Confidential
• Authenticity
It is also important for authenticity to validate that both parties involved are who they claim they are
• Non-repudiation
In law, non-repudiation implies one's intention to fulfill their obligations to a contract.
It also implies that one party of a transaction can not deny having received a transaction nor can the other party deny having sent a transaction.
Aujas Confidential
Secure Code Review
Aujas Confidential
Definition
Secure code review is the process of auditing code for an application on a line by line basis for its security quality
It’s manual process
It’s labor intensive but accurate if performed by humans (and mixture of expensive and inexpensive tools)
Writing a code is easy, but secure code requires proper homework
Aujas Confidential
Secure Code Review Objectives
Idea is to uncover possible potential flaws early in software development life cycle
A general rule of thumb is that a Penetration Testing should not discover any additional application vulnerabilities relating to the developed code after the application has undergone a proper secure code review
Assures that Developers follow Secure Practices
Aujas Confidential
Then Start !
Aujas Confidential
Bug Vs. Flaw
• Bug – A implementation level software security Problem (e.g. SQL Injection)
• Flaw – A design level software security problem (e.g. Insecure Authorization Implementation)
• Bug is subset of Flaw
• A bug is error in Code, while Flaw is any defect in the Program
Aujas Confidential
Aujas Confidential
Aujas Confidential
Aujas Confidential
Methodology
Reporting
Gap Analysis
White Box Code Review
Threat Modeling
Application Understanding
Aujas Confidential
Understand
Code
Context
Audience
Importance
Aujas Confidential
Threat Modeling
STRIDE – classify threats
Spoofing Identity
Tampering with Data
Repudiation
Information Disclosure
Denial of Service
Elevation of Privilege
DREAD – rank vulnerabilities
Damage Potential
Reproducibility
Exploitability
Affected Users
Discoverability
Aujas Confidential
Known Vulnerabilities In Software
Injection Flaws
Cross Site Scripting
Malicious File Execution
Insecure Direct Object Reference
Cross Site Request Forgery (CSRF)
Information Leakage and Improper Error Handling
Broken Authentication and Session Management
Insecure Cryptographic Storage
Insecure Communications
Failure to restrict URL Access
Aujas Confidential
Way Around + Checklist
• Multiple-Pass Approach
• Keyword Search Approach
Aujas Confidential
Keyword Search Approach
Hack
Kludge
Bypass
Steal
Stolen
Divert
Broke
Trick
Fix
ToDo
Generic Keywords
Java.lang.runtime.exec
Legacy Interaction
invalidate
getId
getSession
Session Management
jdbc
executeQuery
Select
insert
update
delete
execute
executestatement
java.sql.ResultSet.getString
java.sql.ResultSet.getObject
java.sql.Statement.executeUpdate
java.sql.Statement.executeQuery
java.sql.Statement.execute
java.sql.Statement.addBatch
java.sql.Connection.prepareStatement
java.sql.Connection.prepareCall
SQL & Database
Aujas Confidential
javax.servlet.ServletOutputStream.print
javax.servlet.jsp.JspWriter.print
java.io.PrintWriter.print
Cross Site Scripting
ObjectInputStream
PipedInputStream
StreamTokenizer
getResourceAsStream
java.io.FileReader
java.io.FileWriter
java.io.RandomAccessFile
java.io.File
java.io.FileOutputStream
File
printf
strcpy
Legacy Methods
Aujas Confidential
catch{
Finally
Error Handling
Java.io
FileInputStream
ObjectInputStream
FilterInputStream
PipedInputStream
SequenceInputStream
StringBufferInputStream
BufferedReader
ByteArrayInputStream
CharArrayReader
Input Output Streams
Aujas Confidential
Javax.servlet.
getLocalName
getAttribute
getAttributeNames
getLocalAddr
getAuthType
getRemoteUser
getCookies
isSecure
HttpServletRequest
getQueryString
getHeader
getPrincipal
Javax.servlet.
isUserInRole
getOutputStream
getWriter
addCookie
addHeader
setHeader
javax.servlet.http.Cookie
getName
getPath
getDomain
getComment
getValue
Servlets
javax.servlet.
getParameterNames
getParameterValues
getParameter
getParameterMap
getScheme
getProtocol
getContentType
getServerName
getRemoteAddr
getRemoteHost
getRealPath
getRequestedSessionId
Servlets Servlets
Aujas Confidential
How to Do It -
Pair Programming
Team Review
Peer Review
Individual Review
Aujas Confidential
Pair Programming
Pair programming is a software development technique in which two programmers work together at one work station.
One types in code while the other reviews each line of code as it is typed in.
The person typing is called the driver.
The person reviewing the code is called the observer or navigator.
Aujas Confidential
Team Code Review – Formal Team
A team of at least 5 people in conference room with a whiteboard and a Projector
5 Roles should be –
Moderator
Narrator/Reader
Author
Subject Matter Expert
Recorder
Aujas Confidential
Focus is important!
Aujas Confidential
Rapid Peer Reviews
• Developers sit together
• Each take turns in
questioning code written by
others
Aujas Confidential
Individual Review
Try to look a code from an attacker perspective
May use automated tools
Aujas Confidential
Secure Code Review – How to Start with
Collect list of threats identified during Threat Modeling Phase – Prioritize which code to look first and deep
Formal Review Team should know what common security bugs look like
Decide on Approach to follow
Follow checklists to drive Code Review
Reporting format is important !
Aujas Confidential
How to Report
Description of Vulnerability
Severity
Complexity
Impact
Affected URL(s)/Page(s)
Line No. of Vulnerable Code
Recommendations
References
Aujas Confidential
Aujas Confidential
Spot the Bug!
Aujas Confidential
Spot the Bug!
boolean theTruth = false;
if (theTruth = true)
{
System.out.println("theTruth is true");
}
else
{
System.out.println("theTruth is false;");
}
Aujas Confidential
Spot the Bug!
int x = 3;
if (x==5) {}
else if (x<9)
{
System.out.println("x is less than 9");
}
else if (x<6)
{
System.out.println("x is less than 6");
}
else
{
System.out.println("else");
}
Aujas Confidential
Spot the Bug !
int x = 2, y = 3;
if (x == y)
if (y == 3)
x = 3;
else
x = 4;
What is the value of X ?
Aujas Confidential
Spot the Bug !
public static String hashMD5(String str)
{
byte[] b = str.getBytes();
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("MD5");
md.update(b);
} catch (NoSuchAlgorithmException e)
{
// it's got to be there
e.printStackTrace();
}
return (base64Encode(md.digest()));
}
Aujas Confidential
Spot the Bug !
public final class BrokenPerson
{
private String firstName;
private String lastName;
private Date dob;
public BrokenPerson( )
{
}
public String getFirstName()
{
return this.firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
}
Aujas Confidential
Spot the Bug !
HttpCookie cookie = Request.Cookies*“Login Attempts”+;
cookie.expires = now. addHours(10);
int logattemtps = convert.toInteger(cookie.value.toString());
cookieval=Integer.parse(cookie.value.toString());
if (cookieval >0)
cookieVal-=1;
HttpCookie attemptCookie = new HttpCookie (“Login Attempts”);
attemptCookie.value = cookieval.toString();
Aujas Confidential
Spot the Bug !
String Uname = request.getParameter (“User”);
String Pword =request.getParameter (Password”);
String s = “SELECT * FROM Table WHERE Username = ‘ “ + UName + “ “ AND Password = ‘ “ + Pword “ ‘ “;
Statement stmt = connection.createStatement ();
ResultSet rs = stmt.executeQuery (s);
If (rs.next ()) {
UID = rs.getInt (1)
User = rs.getString (2)
}
PrintWriter writer= response.getWriter ();
writer.println (“User Name: “+ User);
}
Aujas Confidential
Spot the Bug !
public ArrayList<HashMap<String, String>> searchItems(String productName)
{
ResultSet resultSet = null;
ArrayList<HashMap<String, String>> items = new ArrayList<HashMap<String,String>>();
HashMap<String, String> result = new HashMap<String, String>();
String query = "Select * from items where productName like '%"+ productName+"%' and forsale = 'Y' ";
try {
resultSet = getResultSet(query);
while(resultSet.next())
{
result.put("Id", Integer.toString(resultSet.getInt("id")));
result.put("Name", resultSet.getString("productName"));
result.put("Price", Integer.toString(resultSet.getInt("price")));
result.put("Desc", resultSet.getString("prodDesc"));
items.add(result);
result = new HashMap<String, String>();
}
closeConnection();
}
catch(Exception e)
{
System.out.println(e);
}
return items;
}
Aujas Confidential
Spot the Bug !
Iterator iter = request.getParameterNames ();
While (iter.hasNext ())
{
String paramName = (String) iter.next ();
out.println (paramName +request.getParameter (paramName));
}
Aujas Confidential
Spot the Bug !
public class DoStuff {
public string executeCommand(String userName)
{
try {
String myUid = userName;
Runtime rt = Runtime.getRuntime();
rt.exec("doStuff.exe " +”-“ +myUid); // Call exe with userID
} catch(Exception e) {
e.printStackTrace();
}
}
}
Aujas Confidential
Spot the Bug !
public void doPost(HttpServletRequest req,…) ,
String customerId = req.getParameter(“customerId”);
String productId= req.getParameter(“prodId”);
String Price = req.getParameter(“price”);
Integer price = Integer.valueOf(stringPrice);
// Order will be processed in SubmitOrder Function
orderManager.submitOrder(prodId,customerId,price);
} // end doPost
Aujas Confidential
Spot the Bug!
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 pageif (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/catchreturn (makeLogin(s));
} // end doPost
Aujas Confidential
Spot the Bug !
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
Aujas Confidential
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 = “ + username +
AND password = ” + password);ResultSet results = statement.executeQuery(query);if(results.next()){
successLogin();}
} // end results checkcatch (Exception e)
{
}
Aujas Confidential
Spot the Bug !
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("<TR><TD>“ + rset.getString(1) + “</TD>”);
out.println("<TD>“ + rset.getString(2) + “</TD>”);
} // end while
} catch (Exception e) {
// exception handling…
} // end catch
} // end doPost
Aujas Confidential
Spot the Bug !
if (session.getCurrentUser().isAdmin())
{
MenuList.add("View Profile ","/jsp/Profile.do?action=view&id=" + Id);
MenuList.add("Edit Profile","/jsp/Profile.do?action=edit&id=" + Id);
MenuList.add("Delete Profile","/jsp/Profile.do?action=delete&id=“ + Id);
}
else
{
MenuList.add("View Profile","/jsp/Profile.do?action=view&id=" + Id);
}
Aujas Confidential
Spot the Bug !
Try
{
ElevatePrivilege();
ReadSecretFile();
LowerPrivilege();
}
Catch (Exception e)
{
CatchException();
}
Aujas Confidential
Is there anything wrong with error Msgs ?
“The password is Invalid”
“Username does not exist”
“bad admin password”
Aujas Confidential
Spot the Bug!
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("<TR><TD>“ + rset.getString(1) + “</TD>”);
out.println("<TD>“ + rset.getString(2) + “</TD>”);
} // end while
} catch (Exception e) {
e.printStackTrace(out);
} // end catch
} // end doPost
Aujas Confidential
Spot the Bug!
Private void Log_Function (DataObject obj, System.EventArgs exp)
{
LogData (“User ” + obj.txtUserName + “ with Password ” + obj.txtPassword+ “ Logged in at “ + getCurrentDate&Time();
}
try {
DataObject data = GetLoginDetails();
//..
if(data.success())
Log_Function(data);
}
Catch {}
Aujas Confidential
Spot the Bug ! – FinalPayment.jsp
<html>
<script>
function purchase(ids, price) {
if(validate())
{
document.forms['payment'].ids.value = ids;
document.forms['payment'].price.value = price;
document.forms['payment'].submit();
} }
</script>
<form method="post" action="http://www.shoppingcart.com/process">
………………………………
…………………………………
………………………………..
<input type="hidden" name="ids" value="1,23,2">
<input type="hidden" name="describe" value="Some Book Name">
<input type="hidden" name="Qty" value="3">
<input type="hidden" name="Price" value="200.00">
</html>
Aujas Confidential
Checklists
Aujas Confidential
Authentication
Authorization
Cookie Management
Data Validation
Error Handling/Information Leakage
Note : visit references to download OWASP Code Review Guide
Aujas Confidential
Static Code Analysis
Static code analysis is the analysis of computer software that is performed without actually executing programs built from that software.
Findbugs
FlawFinder
CheckStyle
OWASPCodeCrawler
PMD
Hammurapi
ITS4
RATS
….
Open Source Tools
CodeSecure
Coverity
Fortify
CodeScan
Klockwork
…
Commercial Tools
Aujas Confidential
Stastics
Source :“Secure Programming with Static Analysis”
Aujas Confidential
Static Analysis Tools
Advantages -
Can scan large amount of code
Results are consistent
Identify common security mistakes
Coverage is possible maximum
Disadvantages-
Do not find all security flaws
So many False Positives
Sometime may provide false sense of security
Aujas Confidential
Best Hybrid Approach
Automated + Manual
Aujas Confidential
Dynamic Code Analysis
Dynamic analysis is the analysis of computer software that is performed by executing programs built from that software system on a real or virtual processor
Reduce Debugging Time
Pinpoint error as and when it occurs
Tools like –
Coverity etc.
Aujas Confidential
Dynamic Code Analysis
Advantages
Runtime Defect Detection
Improve Security of Multi-Threaded Applications
Control Multi-core Complexity
Disadvantages
Much more complex to work with
Cannot guarantee the full coverage of the source code, as is runs based on user interaction or automatic tests
Aujas Confidential
Automated Vs. Manual Review Approach
Much Faster
Can not detect semantic/logic flaws
Need human intervention to remove false positives
Have list of standard solutions embedded into it
Very easily deal with large amount of code
Maintains consistency of the Review
Improves coverage/accuracy of the review
Tools do not understand Context
Slower
Can understand code and detect semantic/logic flaws
Can recommend best solution for the problem
Fails when no of lines of code
Consistency can not be guaranteed
Coverage depends on reviewer
Human do understand context
Automated Review Manual Review
Aujas Confidential
References
• OSSTMM
http://www.osstmm.org
• OWASP
http://www.owasp.org
• OSVDB
http://osvdb.org/
•
• CVE
http://cve.mitre.org/
• Secunia
http://www.secunia.com
Aujas Confidential
References
OWASP Code Crawler Project
http://www.owasp.org/index.php/Category:OWASP_Code_Crawler
OWASP Code Review
http://www.owasp.org/index.php/OWASP_Code_Review_Guide_Table_of_
Contents
OWASP Code Review Guide
http://www.lulu.com/content/5678680