Secure Code Review Java

83
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 20 th November 2009 Jaykishan Nirmal Consultant, Trainer and Forensic Investigator

Transcript of Secure Code Review Java

Page 1: 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

Page 2: Secure Code Review Java

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.

Page 3: Secure Code Review Java

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

Page 4: Secure Code Review Java

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”.

Page 5: Secure Code Review Java

Aujas Confidential

Sun Tzu

“如果你知道敌人知道,你不必担心的结

果,很多的 战役。如果你知道你自己而

不是敌人,取得的每一个胜利你同样会遭

受失败。如果你知道无论是敌人还是自己,

你会屈服于在每一个战役。 “

孙子兵法-孙子兵法

Page 6: Secure Code Review Java

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

Page 7: Secure Code Review Java

Aujas Confidential

Security

Page 8: Secure Code Review Java

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

Page 9: Secure Code Review Java

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.

Page 10: Secure Code Review Java

Aujas Confidential

Application Security

Page 11: Secure Code Review Java

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

Page 12: Secure Code Review Java

Aujas Confidential

SANS Common Coding Errors

Page 13: Secure Code Review Java

Aujas Confidential

Application Security Trends : Q3-Q4 2008

Source: Application Security Trends Report Q3-Q4 2008, Cenzic

Page 14: Secure Code Review Java

Aujas Confidential

Software Development – Perfect World

Page 15: Secure Code Review Java

Aujas Confidential

Software Development – Real World

Page 16: Secure Code Review Java

Aujas Confidential

Cost Matters!

Page 17: Secure Code Review Java

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

Page 18: Secure Code Review Java

Aujas Confidential

Case Study : CardSystems Inc.

Page 19: Secure Code Review Java

Aujas Confidential

Few Millions SQL Injection Attack

Page 20: Secure Code Review Java

Aujas Confidential

Application Security & CIA

Page 21: Secure Code Review Java

Aujas Confidential

Core Principles of Security

Confidentiality

IntegrityAvailability

Page 22: Secure Code Review Java

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.

Page 23: Secure Code Review Java

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.

Page 24: Secure Code Review Java

Aujas Confidential

Secure Code Review

Page 25: Secure Code Review Java

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

Page 26: Secure Code Review Java

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

Page 27: Secure Code Review Java

Aujas Confidential

Then Start !

Page 28: Secure Code Review Java

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

Page 29: Secure Code Review Java

Aujas Confidential

Page 30: Secure Code Review Java

Aujas Confidential

Page 31: Secure Code Review Java

Aujas Confidential

Page 32: Secure Code Review Java

Aujas Confidential

Methodology

Reporting

Gap Analysis

White Box Code Review

Threat Modeling

Application Understanding

Page 33: Secure Code Review Java

Aujas Confidential

Understand

Code

Context

Audience

Importance

Page 34: Secure Code Review Java

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

Page 35: Secure Code Review Java

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

Page 36: Secure Code Review Java

Aujas Confidential

Way Around + Checklist

• Multiple-Pass Approach

• Keyword Search Approach

Page 37: Secure Code Review Java

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

Page 38: Secure Code Review Java

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

Page 39: Secure Code Review Java

Aujas Confidential

catch{

Finally

Error Handling

Java.io

FileInputStream

ObjectInputStream

FilterInputStream

PipedInputStream

SequenceInputStream

StringBufferInputStream

BufferedReader

ByteArrayInputStream

CharArrayReader

Input Output Streams

Page 40: Secure Code Review Java

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

Page 41: Secure Code Review Java

Aujas Confidential

How to Do It -

Pair Programming

Team Review

Peer Review

Individual Review

Page 42: Secure Code Review Java

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.

Page 43: Secure Code Review Java

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

Page 44: Secure Code Review Java

Aujas Confidential

Focus is important!

Page 45: Secure Code Review Java

Aujas Confidential

Rapid Peer Reviews

• Developers sit together

• Each take turns in

questioning code written by

others

Page 46: Secure Code Review Java

Aujas Confidential

Individual Review

Try to look a code from an attacker perspective

May use automated tools

Page 47: Secure Code Review Java

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 !

Page 48: Secure Code Review Java

Aujas Confidential

How to Report

Description of Vulnerability

Severity

Complexity

Impact

Affected URL(s)/Page(s)

Line No. of Vulnerable Code

Recommendations

References

Page 49: Secure Code Review Java

Aujas Confidential

Page 50: Secure Code Review Java

Aujas Confidential

Spot the Bug!

Page 51: Secure Code Review Java

Aujas Confidential

Spot the Bug!

boolean theTruth = false;

if (theTruth = true)

{

System.out.println("theTruth is true");

}

else

{

System.out.println("theTruth is false;");

}

Page 52: Secure Code Review Java

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");

}

Page 53: Secure Code Review Java

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 ?

Page 54: Secure Code Review Java

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()));

}

Page 55: Secure Code Review Java

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;

}

}

Page 56: Secure Code Review Java

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();

Page 57: Secure Code Review Java

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);

}

Page 58: Secure Code Review Java

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;

}

Page 59: Secure Code Review Java

Aujas Confidential

Spot the Bug !

Iterator iter = request.getParameterNames ();

While (iter.hasNext ())

{

String paramName = (String) iter.next ();

out.println (paramName +request.getParameter (paramName));

}

Page 60: Secure Code Review Java

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();

}

}

}

Page 61: Secure Code Review Java

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

Page 62: Secure Code Review Java

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

Page 63: Secure Code Review Java

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

Page 64: Secure Code Review Java

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)

{

}

Page 65: Secure Code Review Java

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

Page 66: Secure Code Review Java

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);

}

Page 67: Secure Code Review Java

Aujas Confidential

Spot the Bug !

Try

{

ElevatePrivilege();

ReadSecretFile();

LowerPrivilege();

}

Catch (Exception e)

{

CatchException();

}

Page 68: Secure Code Review Java

Aujas Confidential

Is there anything wrong with error Msgs ?

“The password is Invalid”

“Username does not exist”

“bad admin password”

Page 69: Secure Code Review Java

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

Page 70: Secure Code Review Java

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 {}

Page 71: Secure Code Review Java

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>

Page 72: Secure Code Review Java

Aujas Confidential

Checklists

Page 73: Secure Code Review Java

Aujas Confidential

Authentication

Authorization

Cookie Management

Data Validation

Error Handling/Information Leakage

Note : visit references to download OWASP Code Review Guide

Page 74: Secure Code Review Java

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

Page 75: Secure Code Review Java

Aujas Confidential

Stastics

Source :“Secure Programming with Static Analysis”

Page 76: Secure Code Review Java

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

Page 77: Secure Code Review Java

Aujas Confidential

Best Hybrid Approach

Automated + Manual

Page 78: Secure Code Review Java

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.

Page 79: Secure Code Review Java

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

Page 80: Secure Code Review Java

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

Page 81: Secure Code Review Java

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

Page 82: Secure Code Review Java

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

Page 83: Secure Code Review Java

Aujas Confidential

Thanks

[email protected]