dqs_backend-code-scan-v1.0.0 26NOV2024 DeveloperWorkbook
dqs_backend-code-scan-v1.0.0 26NOV2024 DeveloperWorkbook
Developer Workbook
dqs_backend-code-scan-v1.0.0
Table of Contents
Executive Summary
Project Description
Issue Breakdown by Fortify Categories
Results Outline
Description of Key Terminology
About Fortify Solutions
Likelihood
SCA
Date of Last Analysis: Nov 26, 2024 11:22AM Engine Version: 24.2.0.0150
Host Name: MacBook-Pro-3.local Certification: VALID
Number of Files: 129 Lines of Code: 8,758
Rulepack Name Rulepack Version
Fortify Secure Coding Rules, Community, Cloud 2024.4.0.0009
Fortify Secure Coding Rules, Community, Universal 2024.4.0.0009
Fortify Secure Coding Rules, Core, Android 2024.4.0.0009
Fortify Secure Coding Rules, Core, Annotations 2024.4.0.0009
Fortify Secure Coding Rules, Core, Cloud 2024.4.0.0009
Fortify Secure Coding Rules, Core, Java 2024.4.0.0009
Fortify Secure Coding Rules, Core, SQL 2024.4.0.0009
Fortify Secure Coding Rules, Core, Universal 2024.4.0.0009
Fortify Secure Coding Rules, Extended, Configuration 2024.4.0.0009
Fortify Secure Coding Rules, Extended, Content 2024.4.0.0009
Fortify Secure Coding Rules, Extended, Java 2024.4.0.0009
Fortify Secure Coding Rules, Extended, JSP 2024.4.0.0009
Fortify Secure Coding Rules, Extended, SQL 2024.4.0.0009
Abstract
This maven build script relies on external sources, which could allow an attacker to insert malicious code into the
final product or to take control of the build machine.
Explanation
Several tools exist within the Java development world to aid in dependency management: both Apache Ant and
Apache Maven build systems include functionality specifically designed to help manage dependencies and Apache
Ivy is developed explicitly as a dependency manager. Although there are differences in their behavior, these tools
share the common functionality that they automatically download external dependencies specified in the build process
at build time. This makes it much easier for developer B to build software in the same manner as developer A.
Developers just store dependency information in the build file, which means that each developer and build engineer
has a consistent way to obtain dependencies, compile the code, and deploy without the dependency management
hassles involved in manual dependency management. The following examples illustrate how Ivy, Ant, and Maven can
be used to manage external dependencies as part of a build process. Under Maven, instead of listing explicit URLs
from which to retrieve the dependencies, developers specify the dependency names and versions and Maven relies on
its underlying configuration to identify the server(s) from which to retrieve the dependencies. For commonly used
components this saves the developer from having to researching dependency locations. Example 1: The following
excerpt from a Maven pom.xml file shows how a developer can specify multiple external dependencies using their
name and version:
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
...
</dependencies>
Two distinct types of attack scenarios affect these systems: An attacker could either compromise the server hosting
the dependency or compromise the DNS server the build machine uses to redirect requests for hostname of the server
hosting the dependency to a machine controlled by the attacker. Both scenarios result in the attacker gaining the
ability to inject a malicious version of a dependency into a build running on an otherwise uncompromised machine.
Regardless of the attack vector used to deliver the Trojan dependency, these scenarios share the common element that
the build system blindly accepts the malicious binary and includes it in the build. Because the build system has no
recourse for rejecting the malicious binary and existing security mechanisms, such as code review, typically focus on
internally-developed code rather than external dependencies, this type of attack has a strong potential to go unnoticed
as it spreads through the development environment and potentially into production. Although there is some risk of a
compromised dependency being introduced into a manual build process, by the tendency of automated build systems
to retrieve the dependency from an external source each time the build system is run in a new environment greatly
increases the window of opportunity for an attacker. An attacker need only compromise the dependency server or the
DNS server during one of the many times the dependency is retrieved in order to compromise the machine on which
the build is occurring.
Issue Summary
Sink Details
Sink: //project/repositories
File: pom.xml:3
Taint Flags:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7
Abstract
Constructing a dynamic LDAP filter with user input could allow an attacker to modify the statement's meaning.
Explanation
LDAP injection errors occur when: 1. Data enters a program from an untrusted source. In this case, Fortify Static
Code Analyzer could not determine that the source of the data is trusted. 2. The data is used to dynamically construct
an LDAP filter. Note: The LDAP Injection issue might still be reported (with a reduced priority value) even after
remediation efforts. When Fortify Static Code Analyzer finds clear dataflow evidence of user-controlled input being
used to construct LDAP statements, a high/critical priority dataflow issue is reported. When Fortify SCA cannot
determine the source of the data but it can be dynamically changed, a low/medium priority semantic issue is reported.
This strategy is adopted in a few select vulnerability categories such as LDAP Injection where the potential impact of
exploitation outweighs the inconvenience of auditing false positive issues. Example 1: The following code
dynamically constructs and executes an LDAP query that retrieves records for all the employees who report to a given
manager. The manager's name is read from an HTTP request, and is therefore untrusted.
...
DirContext ctx = new InitialDirContext(env);
Recommendation
The root cause of LDAP injection vulnerabilities is the ability of an attacker to supply LDAP metacharacters that
change the meaning of the LDAP query. When an LDAP filter is constructed, the programmer knows what should be
interpreted as part of the command and what should be interpreted as data. To prevent an attacker from violating the
programmer's expectations, use an allow list to ensure that user-controlled values used in an LDAP query are
composed from only the expected set of characters and do not contain any LDAP metacharacters given the context in
which they are used. If the domain of a user-controlled value requires that it contain LDAP metacharacters, use an
appropriate encoding mechanism to remove their significance within the LDAP query. Example 2: The previous
example can be rewritten to use the Spring framework EqualsFilter class to construct a properly encoded filter
string that preserves that statement's command structure, regardless of any LDAP metacharacters present in the
Issue Summary
Engine Breakdown
Sink Details
Sink: search()
Enclosing Method: searchUser()
File: src/main/java/com/salixspace/dqs/utils/ActiveDirectory.java:104
Taint Flags:
101 String filter = getFilter(searchValue, searchBy);
102 String base = (null == searchBase) ? domainBase : getDomainBase(searchBase); // for eg.: "DC=myjeeva,DC=com";
103
Abstract
Using System.out or System.err rather than a dedicated logging facility makes it difficult to monitor the
program behavior.
Explanation
Example 1: The first Java program that a developer learns to write is the following:
public class MyClass
...
System.out.println("hello world");
...
}
While most programmers go on to learn many nuances and subtleties about Java, a surprising number hang on to this
first lesson and never give up on writing messages to standard output using System.out.println(). The
problem is that writing directly to standard output or standard error is often used as an unstructured form of logging.
Structured logging facilities provide features like logging levels, uniform formatting, a logger identifier, timestamps,
and, perhaps most critically, the ability to direct the log messages to the right place. When the use of system output
streams is jumbled together with the code that uses loggers properly, the result is often a well-kept log that is missing
critical information. Developers widely accept the need for structured logging, but many continue to use system
output streams in their "pre-production" development. If the code you are reviewing is past the initial phases of
development, use of System.out or System.err may indicate an oversight in the move to a structured logging
system.
Recommendation
Use a Java logging facility rather than System.out or System.err. Example 2: For example, you can rewrite
the "hello world" program in Example 1 using log4j as follows:
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
...
BasicConfigurator.configure();
logger.info("hello world");
...
}
Issue Summary
Sink Details
Sink: FunctionCall: println
Enclosing Method: userPrincipal()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:107
Taint Flags:
104 // You can access other claims or information as needed
105
106 // Print the decoded information
107 System.out.println("Decoded JWT Token:");
108 System.out.println("User ID: " + userId);
109 System.out.println("account: " + account);
110 System.out.println("divisionCode: " + divisionCode);
Sink Details
Sink: FunctionCall: println
Sink Details
Sink: FunctionCall: println
Enclosing Method: userPrincipal()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:109
Taint Flags:
106 // Print the decoded information
107 System.out.println("Decoded JWT Token:");
108 System.out.println("User ID: " + userId);
109 System.out.println("account: " + account);
110 System.out.println("divisionCode: " + divisionCode);
111 System.out.println("costCenterCode: " + costCenterCode);
112 UserPrincipal userPrincipal = new UserPrincipal();
Sink Details
Sink: FunctionCall: println
Enclosing Method: userPrincipal()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:108
Taint Flags:
105
106 // Print the decoded information
107 System.out.println("Decoded JWT Token:");
108 System.out.println("User ID: " + userId);
109 System.out.println("account: " + account);
110 System.out.println("divisionCode: " + divisionCode);
111 System.out.println("costCenterCode: " + costCenterCode);
Sink Details
Sink: FunctionCall: println
Enclosing Method: userPrincipal()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:110
Taint Flags:
107 System.out.println("Decoded JWT Token:");
108 System.out.println("User ID: " + userId);
109 System.out.println("account: " + account);
110 System.out.println("divisionCode: " + divisionCode);
111 System.out.println("costCenterCode: " + costCenterCode);
112 UserPrincipal userPrincipal = new UserPrincipal();
113 userPrincipal.setUserId(userId);
Package: com.salixspace.dqs.utils
src/main/java/com/salixspace/dqs/utils/AppDateUtil.java, line 34 (Poor Logging Practice:
Use of a System Output Stream)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Structural)
Sink Details
Sink: FunctionCall: println
Enclosing Method: getCurrentTimeZone()
File: src/main/java/com/salixspace/dqs/utils/AppDateUtil.java:34
Taint Flags:
31
32 public static String getCurrentTimeZone() {
Abstract
Mishandling private information, such as customer passwords or social security numbers, can compromise user
privacy and is often illegal.
Explanation
Privacy violations occur when: 1. Private user information enters the program. 2. The data is written to an external
location, such as the console, file system, or network. Example 1: The following code contains a logging statement
that tracks the records added to a database by storing the contents in a log file.
pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
The code in Example 1 logs a plain text password to the file system. Although many developers trust the file
system as a safe storage location for data, it should not be trusted implicitly, particularly when privacy is a concern.
Privacy is one of the biggest concerns in the mobile world for a couple of reasons. One of them is a much higher
chance of device loss. The other has to do with inter-process communication between mobile applications. With
mobile platforms, applications are downloaded from various sources and are run alongside each other on the same
device. The likelihood of running a piece of malware next to a banking application is high, which is why application
authors need to be careful about what information they include in messages addressed to other applications running on
the device. Sensitive information should never be part of inter-process communication between mobile applications.
Example 2: The following code reads username and password for a given site from an Android WebView store and
broadcasts them to all the registered receivers.
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = credentials[0];
String password = credentials[1];
Intent i = new Intent();
i.setAction("SEND_CREDENTIALS");
i.putExtra("username", username);
i.putExtra("password", password);
view.getContext().sendBroadcast(i);
}
});
...
This example demonstrates several problems. First of all, by default, WebView credentials are stored in plain text and
are not hashed. If a user has a rooted device (or uses an emulator), they can read stored passwords for given sites.
Second, plain text credentials are broadcast to all the registered receivers, which means that any receiver registered to
listen to intents with the SEND_CREDENTIALS action will receive the message. The broadcast is not even protected
with a permission to limit the number of recipients, although in this case we do not recommend using permissions as a
fix. Private data can enter a program in a variety of ways: - Directly from the user in the form of a password or
personal information - Accessed from a database or other data store by the application - Indirectly from a partner or
other third party Typically, in the context of the mobile environment, this private information includes (along with
passwords, SSNs, and other general personal information): - Location - Cell phone number - Serial numbers and
device IDs - Network Operator information - Voicemail information Sometimes data that is not labeled as private can
have a privacy implication in a different context. For example, student identification numbers are usually not
considered private because there is no explicit and publicly-available mapping to an individual student's personal
information. However, if a school generates identification numbers based on student social security numbers, then the
identification numbers should be considered private. Security and privacy concerns often seem to compete with each
other. From a security perspective, you should record all important operations so that any anomalous activity can later
Recommendation
When security and privacy demands clash, privacy should usually be given the higher priority. To accomplish this and
still maintain required security information, cleanse any private information before it exits the program. To enforce
good privacy management, develop and strictly adhere to internal privacy guidelines. The guidelines should
specifically describe how an application should handle private data. If your organization is regulated by federal or
state law, ensure that your privacy guidelines are sufficiently strenuous to meet the legal requirements. Even if your
organization is not regulated, you must protect private information or risk losing customer confidence. The best policy
with respect to private data is to minimize its exposure. Applications, processes, and employees should not be granted
access to any private data unless the access is required for the tasks that they are to perform. Just as the principle of
least privilege dictates that no operation should be performed with more than the necessary privileges, access to
private data should be restricted to the smallest possible group. For mobile applications, make sure they never
communicate any sensitive data to other applications running on the device. When private data needs to be stored, it
should always be encrypted. For Android, as well as any other platform that uses SQLite database, SQLCipher is a
good alternative. SQLCipher is an extension to the SQLite database that provides transparent 256-bit AES encryption
of database files. Thus, credentials can be stored in an encrypted database. Example 3: The following code
demonstrates how to integrate SQLCipher into an Android application after downloading the necessary binaries, and
store credentials into the database file.
import net.sqlcipher.database.SQLiteDatabase;
...
SQLiteDatabase.loadLibs(this);
File dbFile = getDatabasePath("credentials.db");
dbFile.mkdirs();
dbFile.delete();
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile,
"credentials", null);
db.execSQL("create table credentials(u, p)");
db.execSQL("insert into credentials(u, p) values(?, ?)", new Object[]
{username, password});
...
Note that references to android.database.sqlite.SQLiteDatabase are substituted with those of
net.sqlcipher.database.SQLiteDatabase. To enable encryption on the WebView store, you must
recompile WebKit with the sqlcipher.so library. Example 4: The following code reads username and password
for a given site from an Android WebView store and instead of broadcasting them to all the registered receivers, it
only broadcasts internally so that the broadcast is only seen by other parts of the same application.
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = credentials[0];
String password = credentials[1];
Intent i = new Intent();
i.setAction("SEND_CREDENTIALS");
Issue Summary
Engine Breakdown
Source Details
Source: Read this.password
From: com.salixspace.dqs.data.primary.domain.User.toString
File: src/main/java/com/salixspace/dqs/data/primary/domain/User.java:49
46 "username='" + username + '\'' +
47 ", firstName='" + firstName + '\'' +
48 ", lastName='" + lastName + '\'' +
49 ", password='" + password + '\'' +
50 ", isActivated=" + activated +
51 ", userOU='" + userOU + '\'' +
52 ", costCenterCode='" + costCenterCode + '\'' +
Sink Details
Sink: org.apache.logging.log4j.Logger.info()
Enclosing Method: login()
File: src/main/java/com/salixspace/dqs/service/UserService.java:229
Taint Flags: PRIVATE
226 } else { // filter only admin
227
228 User user = opt.get();
229 log.info("login opt " + user);
230 String userRoleOU = user.getUserOU();
231 if (!user.isActivated()) {
232 throw UserException.userInActive();
Source Details
Source: Read this.password
From: com.salixspace.dqs.data.primary.domain.User.toString
File: src/main/java/com/salixspace/dqs/data/primary/domain/User.java:49
46 "username='" + username + '\'' +
47 ", firstName='" + firstName + '\'' +
48 ", lastName='" + lastName + '\'' +
49 ", password='" + password + '\'' +
50 ", isActivated=" + activated +
51 ", userOU='" + userOU + '\'' +
52 ", costCenterCode='" + costCenterCode + '\'' +
Sink Details
Sink: org.apache.logging.log4j.Logger.info()
Enclosing Method: tokenize()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:34
Taint Flags: PRIVATE
31 private int expiredAdminAt;
32
33 public String tokenize(User user) {
34 log.info("tokenize " + user.toString());
35 int expireTime = expiredAt;
36 if (user.getUserOU().equalsIgnoreCase(Constant.ROLE_ADMIN) ||
user.getUserOU().equalsIgnoreCase(Constant.ROLE_ADMINISTRATOR)) {
37 expireTime = expiredAdminAt;
Abstract
Storing sensitive data in a String object makes it impossible to reliably purge the data from memory.
Explanation
Sensitive data (such as passwords, social security numbers, credit card numbers, and so on) stored in memory can be
leaked if memory is not cleared after use. Often, Strings are used to store sensitive data, however, becauseString
objects are immutable, only the JVM garbage collector can remove the value of a String from memory can only be
done by the JVM garbage collector. The garbage collector is not required to run unless the JVM is low on memory, so
there is no guarantee as to when garbage collection will take place. In the event of an application crash, a memory
dump of the application might reveal sensitive data. Example 1: The following code converts a password from a
character array to a String.
private JPasswordField pf;
...
final char[] password = pf.getPassword();
...
String passwordAsString = new String(password);
This category was derived from the Cigital Java Rulepack.
Recommendation
Always clear sensitive data that is no longer needed. Instead of storing sensitive data in immutable objects such as
Strings, use byte arrays or character arrays that you can clear programmatically. Example 2: The following code
clears memory after a password is used.
private JPasswordField pf;
...
final char[] password = pf.getPassword();
// use the password
...
// erase when finished
Arrays.fill(password, ' ');
Issue Summary
Source Details
Source: Read this.password
From: com.salixspace.dqs.model.request.MLoginRequest.getPassword
File: src/main/java/com/salixspace/dqs/model/request/MLoginRequest.java:8
5 @Data
6 public class MLoginRequest {
7 private String username;
8 private String password;
9}
10
11 undefined
Sink Details
Sink: java.lang.String.String()
Enclosing Method: login()
File: src/main/java/com/salixspace/dqs/service/UserService.java:176
Taint Flags: PRIVATE, WEAKCRYPTO
173
174 String password = StringUtils.removeChar(endCodePwd, endCodePwd.length() - 5);
175 byte[] decodedBytes = Base64.getDecoder().decode(password);
176 password = new String(decodedBytes);
177
178 if (Objects.isNull(password)) {
179 throw UserException.passwordNull();
Sink Details
Sink: java.lang.String.String()
Enclosing Method: login()
File: src/main/java/com/salixspace/dqs/service/UserService.java:176
Taint Flags: PRIVATE, WEAKCRYPTO
173
174 String password = StringUtils.removeChar(endCodePwd, endCodePwd.length() - 5);
175 byte[] decodedBytes = Base64.getDecoder().decode(password);
176 password = new String(decodedBytes);
177
178 if (Objects.isNull(password)) {
179 throw UserException.passwordNull();
Abstract
The Spring Boot application is configured in developer mode.
Explanation
The Spring Boot application has DevTools enabled. DevTools include an additional set of tools which can make the
application development experience a little more pleasant, but DevTools are not recommended to use on applications
in a production environment. As stated in the official Spring Boot documentation: "Enabling spring-boot-
devtools on a remote application is a security risk. You should never enable support on a production deployment."
Recommendation
Remove spring-boot-devtools dependency on production deployments.
Issue Summary
Engine Breakdown
Sink Details
Sink:
File: pom.xml:41
Taint Flags:
38 </dependency>
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 debug information leaves the program through an output stream or
logging function. Example 1: The following code writes an exception to the standard error stream:
try {
...
} catch (Exception e) {
e.printStackTrace();
}
Depending on the system configuration, this information can be dumped to a console, written to a log file, or exposed
to a remote user. For example, with scripting mechanisms it is trivial to redirect output information from "Standard
error" or "Standard output" into a file or another program. Alternatively, the system that the program runs on could
have a remote logging mechanism such as a "syslog" server that sends the logs to a remote device. During
development, you have no way of knowing where this information might end up being displayed. In some cases, the
error message provides the attacker with the precise type of attack to which the system is vulnerable. For example, a
database error message can reveal that the application is vulnerable to a SQL injection attack. Other error messages
can reveal more oblique clues about the system. In Example 1, the leaked information could imply information
about the type of operating system, the applications installed on the system, and the amount of care that the
administrators have put into configuring the program. Information leaks are also a concern in a mobile computing
environment. With mobile platforms, applications are downloaded from various sources and are run alongside each
other on the same device. The likelihood of running a piece of malware next to a banking application is high, which is
why application authors need to be careful about what information they include in messages addressed to other
applications running on the device. Example 2: The following code broadcasts the stack trace of a caught exception
to all the registered Android receivers.
...
try {
...
} catch (Exception e) {
String exception = Log.getStackTraceString(e);
Intent i = new Intent();
i.setAction("SEND_EXCEPTION");
i.putExtra("exception", exception);
view.getContext().sendBroadcast(i);
}
...
This is another scenario specific to the mobile environment. Most mobile devices now implement a Near-Field
Communication (NFC) protocol for quickly sharing information between devices using radio communication. It
works by bringing devices in close proximity or having the devices touch each other. Even though the communication
range of NFC is limited to just a few centimeters, eavesdropping, data modification and various other types of attacks
are possible, because NFC alone does not ensure secure communication. Example 3: The Android platform provides
support for NFC. The following code creates a message that gets pushed to the other device within range.
...
public static final String TAG = "NfcActivity";
private static final String DATA_SPLITTER = "__:DATA:__";
private static final String MIME_TYPE = "application/my.applications.mimetype";
...
TelephonyManager tm =
(TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE);
String VERSION = tm.getDeviceSoftwareVersion();
Recommendation
Write error messages with security in mind. In production environments, turn off detailed error information in favor of
brief messages. Restrict the generation and storage of detailed output that can help administrators and programmers
diagnose problems. Debug traces can sometimes appear in non-obvious places (embedded in comments in the HTML
for an 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. Because of this, never send information to a resource directly outside the program. Example 4: The following
code broadcasts the stack trace of a caught exception within your application only, so that it cannot be leaked to other
apps on the system. Additionally, this technique is more efficient than globally broadcasting through the system.
...
try {
...
} catch (Exception e) {
String exception = Log.getStackTraceString(e);
Intent i = new Intent();
i.setAction("SEND_EXCEPTION");
i.putExtra("exception", exception);
LocalBroadcastManager.getInstance(view.getContext()).sendBroadcast(i);
}
...
If you are concerned about leaking system data via NFC on an Android device, you could do one of the following
three things. Do not include system data in the messages pushed to other devices in range, encrypt the payload of the
message, or establish a secure communication channel at a higher layer.
Issue Summary
Sink Details
Sink: printStackTrace()
Enclosing Method: run()
File: src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java:116
Taint Flags:
113 log.info("init default menu successfully");
114 }
115 } catch (Exception e) {
116 e.printStackTrace();
117 log.error("can not init menu root", e.getLocalizedMessage());
118 }
119 }
src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java, line 99
(System Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Sink Details
Sink: printStackTrace()
Enclosing Method: run()
File: src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java:99
Taint Flags:
96 log.info("init default user successfully");
97 }
98 } catch (Exception e) {
99 e.printStackTrace();
100 log.error("can not init user admin ", e);
101 }
102 try {
Sink Details
Sink: printStackTrace()
Enclosing Method: run()
File: src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java:81
Taint Flags:
78 log.info("init default user successfully");
79 }
80 } catch (Exception e) {
81 e.printStackTrace();
82 log.error("can not init user administrator ", e);
83 }
84 try {
src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java, line 63
(System Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Sink Details
Sink: printStackTrace()
Enclosing Method: run()
File: src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java:63
Taint Flags:
60 log.info("init default administrator successfully");
61 }
62 } catch (Exception e) {
63 e.printStackTrace();
64 log.error("can not init user admin ", e);
65 }
66 try {
src/main/java/com/salixspace/dqs/config/CommandLineAppStartupRunner.java, line 49
(System Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Package: com.salixspace.dqs.controller
src/main/java/com/salixspace/dqs/controller/AuthorityController.java, line 160 (System
Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Sink Details
Sink: printStackTrace()
Enclosing Method: uploadAuthorities()
File: src/main/java/com/salixspace/dqs/controller/AuthorityController.java:160
Taint Flags:
157 .body(result);
158 } else return ResponseEntity.notFound().build();
159 } catch (IOException e) {
160 e.printStackTrace();
161 throw UserException.uploadFail();
162 }
163 }
Package: com.salixspace.dqs.data.primary.domain
src/main/java/com/salixspace/dqs/data/primary/domain/Authority.java, line 74 (System
Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Sink Details
Sink: printStackTrace()
Enclosing Method: merge()
File: src/main/java/com/salixspace/dqs/data/primary/domain/Authority.java:74
Taint Flags:
71 newAuth.getMenus().addAll(a.getMenus());
72 }
73 } catch (Exception e) {
74 e.printStackTrace();
75 }
76 return newAuth;
77 }
Package: com.salixspace.dqs.service
src/main/java/com/salixspace/dqs/service/ActiveDirectoryService.java, line 47 (System
Information Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Data Flow)
Source Details
Source: java.lang.Throwable.getMessage()
From: com.salixspace.dqs.service.ActiveDirectoryService.authenticate
File: src/main/java/com/salixspace/dqs/service/ActiveDirectoryService.java:47
44 return false; // Invalid credentials
45 } catch (NamingException e) {
46 // e.printStackTrace();
47 log.info("authed ad naming exception fail " + e.getMessage());
48 return false; // Other error occurred
49 }
50 }
Sink Details
Sink: org.apache.logging.log4j.Logger.info()
Enclosing Method: authenticate()
File: src/main/java/com/salixspace/dqs/service/ActiveDirectoryService.java:47
Taint Flags: EXCEPTIONINFO, SYSTEMINFO
44 return false; // Invalid credentials
45 } catch (NamingException e) {
46 // e.printStackTrace();
47 log.info("authed ad naming exception fail " + e.getMessage());
Sink Details
Sink: printStackTrace()
Enclosing Method: userPrincipal()
File: src/main/java/com/salixspace/dqs/service/TokenService.java:121
Taint Flags:
118
119 } catch (Exception e) {
120 // Handle decoding exceptions
121 e.printStackTrace();
122
123 return null;
124 }
Package: com.salixspace.dqs.utils
src/main/java/com/salixspace/dqs/utils/AppDateUtil.java, line 26 (System Information
Leak)
Issue Details
Kingdom: Encapsulation
Scan Engine: SCA (Semantic)
Sink Details
Sink: printStackTrace()
Enclosing Method: convertToCurrentTimeZone()
File: src/main/java/com/salixspace/dqs/utils/AppDateUtil.java:26
Taint Flags:
23 currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone()));
24 converted_date = currentTFormat.format(date);
25 } catch (Exception e) {
26 e.printStackTrace();
27 }
28
Abstract
Ignoring a method's return value can cause the program to overlook unexpected states and conditions.
Explanation
It is not uncommon for Java programmers to misunderstand read() and related methods that are part of many
java.io classes. Most errors and unusual events in Java result in an exception being thrown. (This is one of the
advantages that Java has over languages like C: Exceptions make it easier for programmers to think about what can go
wrong.) But the stream and reader classes do not consider it unusual or exceptional if only a small amount of data
becomes available. These classes simply add the small amount of data to the return buffer, and set the return value to
the number of bytes or characters read. There is no guarantee that the amount of data returned is equal to the amount
of data requested. This behavior makes it important for programmers to examine the return value from read() and
other IO methods to ensure that they receive the amount of data they expect. Example 1: The following code loops
through a set of users, reading a private data file for each user. The programmer assumes that the files are always
exactly 1 kilobyte in size and therefore ignores the return value from read(). If an attacker can create a smaller file,
the program will recycle the remainder of the data from the previous user and handle it as though it belongs to the
attacker.
FileInputStream fis;
byte[] byteArray = new byte[1024];
for (Iterator i=users.iterator(); i.hasNext();) {
String userName = (String) i.next();
String pFileName = PFILE_ROOT + "/" + userName;
FileInputStream fis = new FileInputStream(pFileName);
fis.read(byteArray); // the file is always 1k bytes
fis.close();
processPFile(userName, byteArray);
}
Recommendation
FileInputStream fis;
byte[] byteArray = new byte[1024];
for (Iterator i=users.iterator(); i.hasNext();) {
String userName = (String) i.next();
String pFileName = PFILE_ROOT + "/" + userName;
fis = new FileInputStream(pFileName);
int bRead = 0;
while (bRead < 1024) {
int rd = fis.read(byteArray, bRead, 1024 - bRead);
if (rd == -1) {
throw new IOException("file is unusually small");
}
bRead += rd;
}
// could add check to see if file is too large here
fis.close();
processPFile(userName, byteArray);
}
Note: Because the fix for this problem is relatively complicated, you might be tempted to use a simpler approach, such
as checking the size of the file before you begin reading. Such an approach would render the application vulnerable to
a file system race condition, whereby an attacker could replace a well-formed file with a malicious file between the
file size check and the call to read data from the file.
Engine Breakdown
Sink Details
Sink: mkdirs()
Enclosing Method: historyLogsDownload()
File: src/main/java/com/salixspace/dqs/controller/LogController.java:107
Taint Flags:
104 ByteArrayInputStream excel = ExcelGenerator.logInHistoryADExcelGenerator(data);
105 File folder = new File(DOWNLOAD_FOLDER);
106 if (!folder.exists()) {
107 folder.mkdirs();
108 }
109 String encodedString = new SimpleDateFormat("yyyyMMdd").format(new Date());
110 String filename = "RP006_AD_" + Math.abs(encodedString.hashCode()) + ".xlsx";
Impact
Impact is the potential damage an attacker could do to assets by successfully exploiting a vulnerability. This damage can
be in the form of, but not limited to, financial loss, compliance violation, loss of brand reputation, and negative publicity.
High
High-priority issues have high impact and low likelihood. High-priority issues are often difficult to detect and exploit,
but can result in large asset damage. These issues represent a high security risk to the application. High-priority issues
should be remediated in the next scheduled patch release.
Medium
Medium-priority issues have low impact and high likelihood. Medium-priority issues are easy to detect and exploit, but
typically result in small asset damage. These issues represent a moderate security risk to the application. Medium-
priority issues should be remediated in the next scheduled product update.
Low
Low-priority issues have low impact and low likelihood. Low-priority issues can be difficult to detect and exploit and
typically result in small asset damage. These issues represent a minor security risk to the application. Low-priority
issues should be remediated as time allows.