Android Secure Development Guide

Section 1. Input Data Validation and Representation

Accepting and using user input without proper validation exposes a system to numerous security threats. To prevent such vulnerabilities, it is recommended to code applications so that they only accept valid input data. In unavoidable cases, vulnerabilities should be eliminated by validating input values and allowing only verified data to be processed.

1. Relative Path Traversal

A. Definition

When an external input is used to generate a “directory path string,” failing to filter characters that can be used for path manipulation can lead to the creation of paths in unintended areas. This can result in system information leaks or service disruptions.

B. Secure Coding Techniques

Ensure that external input cannot be used directly to create file names. If direct use is unavoidable, implement a filter using methods such as replaceAll() to remove dangerous characters (e.g., “..”, “/”, “”) to prevent access to files in other directories.

C. Examples

Insecure Code Example – Java

1:......
2:public void f(Properties request) {
3:......
4:String name request.getProperty("filename");
5:if( name != null) {
6:File file = new File("/usr/local/tmp/" + name);
7:file.delete();
8:}
9:......
10:}

External input (name) is being used to set the path of a file to be deleted. If an attacker provides a value like ../../../rootFile.txt, unintended files could be deleted, adversely affecting the system.

1:......
2:public void f(Properties request) {
3:......
4:String name request.getProperty("User");
5:if( name != null && !"".equals(name) ) {
6:name = name.replaceAll("/","");
7:name = name.replaceAll(\\","");
8:name =name.replaceAll("."," ");
9:name = name.replaceAll("&"," ");
10:name = name + "-report" ;
11:File file = new File("/usr/local/tmp/" + name);
12:if (file != null) file.delete();
13:}
14:.......
15:}

The code checks for Null values in external input. It uses replaceAll to remove special characters (/, \, &, ., etc.) from the user-provided name to prevent the configuration of relative paths.

D. References

[1] CWE-23 Relative Path Traversal – http://cwe.mitre.org/data/definitions/23.html
[2] OWASP Top 10 2010 – (OWASP 2010) A4 Insecure Direct Object Reference
[3] SANS Top 25 2010 – (SANS 2010) Risky Resource Management, Rank 7 CWE ID 22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)

2. Absolute Path Traversal

A. Definition

It is dangerous if external input can directly control or influence the path used to manipulate the file system. Allowing user input to control the paths used in file system operations creates the possibility for an attacker to access or modify critical system files or general files within the application. In other words, through path manipulation, an attacker can obtain unauthorized privileges to change configuration-related files or execute them.

B. Secure Coding Techniques

It is advisable to write programs that prevent access to arbitrary directories by using the replaceAll method to remove dangerous characters from filenames or by checking whether the string contains an absolute path.

C. Examples

1:......
2:public void onCreate(Bundle savedInstanceState){ 
3:super.onCreate(savedInstanceState);
4:File file = new File(android.os.Environment.getExternalStorageDirectory(), "inputFile");
5:try {
6:InputStream is = new FileInputStream(file);
7:Properties props = new Properties();
8:props.load(is); 
9:String name = props.getProperty("filename"); 
10:file = new File("/usr/local/tmp/" + name);
11: file.delete();
12: is.close();
13: } catch (IOException e) {
14: Log.w("Error", "", e);
15: }
16: }

When a file is created directly from external input, arbitrary filenames can be entered, allowing access to other files and potentially exposing unintended information.

Secure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: super.onCreate(savedInstanceState);
4:
5: File file = new File(android.os.Environment.getExternalStorageDirectory(), "inputFile");
6: try {
7: InputStream is = new FileInputStream(file);
8: Properties props = new Properties();
9: props.load(is);
10: String name = props.getProperty("filename");
11: if (name.indexOf("/" ) <0) {
12: file = new File(name);
13: file.delete();
14: }
15: is.close();
16: } catch (IOException e) {
17: Log.w("Error", "", e);
18: }
19: }

When external input is used as a filename, it is preferable to reject the operation if the string contains “” or “/” or starts with those characters, ensuring that an absolute path cannot be used.

D. References

[1] CWE-36 Absolute Path Traversal – http://cwe.mitre.org/data/definitions/36.html
[2] OWASP Top 10 2010 – (OWASP 2010) A4 Insecure Direct Object Reference
[3] SANS Top 25 2010 – Risky Resource Management, Rank 7 CWE ID 22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)

Section 2. API Abuse

An Application Programming Interface (API) is a language, message format, or convention used for communication between an operating system and an application program. While APIs offer benefits such as development convenience and efficiency, misusing them or using APIs with known vulnerabilities can lead to decreased development efficiency, poor maintainability, and serious security threats.

1. Unchecked Null Parameters

A. Definition

According to Java standards, the implementations of Object.equals(), Comparable.compareTo(), and Comparator.compare() must return a specified value if a parameter is null. Failing to adhere to this convention can result in unexpected behavior during program execution.

B. Secure Coding Techniques

When implementing Object.equals(), Comparable.compareTo(), and Comparator.compare(), the code must explicitly compare the input parameter with null to handle it appropriately.

C. Examples

Insecure Code Example – Java

1: public void onCreate(Bundle savedInstanceState) {
2: super.onCreate(savedInstanceState);
3: }
4:
5: public boolean equals(Object object)
6: {
7: return (toString().equals(object.toString()));
8: }

In this example, the code fails to check whether the object parameter is null before accessing its methods.

Secure Code Example – Java

1: public void onCreate(Bundle savedInstanceState) {
2: super.onCreate(savedInstanceState);
3: }
4:
5: public boolean equals(Object object)
6: {
7: if(object != null)
8: return (toString().equals(object.toString()));
9: else return false ;
10: }

In this improved version, the parameter is first checked for a null value, ensuring the method returns false safely if the object is null.

D. References

[1] CWE-398: Indicator of Poor Code Quality – http://cwe.mitre.org/data/definitions/398.html

2. Defining Only One of equals() or hashCode()

A. Definition

According to Java standards, identical objects must have the same hash code. Specifically, if “a.equals(b) == true”, then “a.hashCode() == b.hashCode()” must also be true. Therefore, within a single class, both equals() and hashCode() should be implemented together, or neither should be implemented.

B. Secure Coding Techniques

If equals() is defined within a class, hashCode() must also be defined. Conversely, if hashCode() is defined, equals() must be defined as well.

C. Examples

Insecure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: super.onCreate(savedInstanceState);
4: }
5:
6: public boolean equals(Object obj) {
7: if (obj == null)
8: return false;
9: int i1 = this.hashCode();
10: int i2 = obj.hashCode();
11:
12: if (i1 == i2)
13: return true;
14: else
15: return false;
16: }

In this example, only one of equals() or hashCode() has been defined.

Secure Code Example – Java

1: ……
2: public boolean equals(Object obj) {
3: if (obj == null)
4: return false;
5: int i1 = this.hashCode();
6: int i2 = obj.hashCode();
7:
8: if (i1 == i2)
9: return true;
10: else
11: return false;
12: }
13: public int hashCode() {
14: return new HashCodeBuilder(17, 37).toHashCode();
15: }

Both equals() and hashCode() must be defined to maintain the object contract.

D. References

[1] CWE-581: Object Model Violation: Just One of equals and hashCode Defined – http://cwe.mitre.org/data/definitions/581.html

Section 3. Security Features

Great care must be taken when handling fundamental security functions. The improper use of security features can result in performance degradation or additional complications. Security features include authentication, access control, confidentiality, encryption, and privilege management.

1. Transmission of Sensitive Information in Plaintext

A. Definition

When software transmits sensitive security-related data in plaintext over a communication channel, it can be intercepted via sniffing by unauthorized entities.

B. Secure Coding Techniques

Sensitive information must always be encrypted before being transmitted over a communication channel.

C. Examples

Insecure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: int port = 443;
4: String hostname = "hostname";
5: Socket socket = new Socket(hostname, port);
6: InputStream in = socket.getInputStream();
7: OutputStream out = socket.getOutputStream();
8: // Read from in and write to out...
9: in.close();
10: out.close();
11: }

Using a standard socket to transmit data externally can lead to the exposure of data contents through packet sniffing.

Secure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: int port = 443;
4: String hostname = "hostname";
5: SocketFactory socketFactory = SSLSocketFactory.getDefault();
6: Socket socket = socketFactory.createSocket(hostname, , port);
7: InputStream in = socket.getInputStream();
8: OutputStream out = socket.getOutputStream();
9: // Read from in and write to out...
10: in.close();
11: out.close();
12: }

It is advisable to encrypt sensitive information using at least a 128-bit key before transmitting it to a server over a network.

D. References

[1] CWE-319: Cleartext Transmission of Sensitive Information
[2] OWASP Top 10 2007 – A9 Insecure Communications

2. Use of Broken or Risky Cryptographic Algorithms

A. Definition

Security-vulnerable or dangerous cryptographic algorithms must not be used. Using non-standardized algorithms increases the possibility of attackers analyzing and neutralizing them. Older algorithms like RC2, RC4, RC5, RC6, MD4, MD5, SHA1, and DES have become vulnerable as computing power increases.

B. Secure Coding Techniques

It is recommended to use stronger, standardized cryptographic algorithms such as AES.

C. Examples

Insecure Code Example – Java

1: ……
2: public byte[] encrypt(byte[] msg, Key k) {
3: byte[] rslt = null;
4:
5: try {
6: // DES등의 낮은 보안수준의 알고리즘을 사용하는 것은 안전하지 않다.
7: Cipher c = Cipher.getInstance("DES");
8: c.init(Cipher.ENCRYPT_MODE, k);
9: rslt = c.update(msg);
10: } catch (InvalidKeyException e) {
11: ……
12: }
13: return rslt;
14: }
15: }

Using the DES algorithm is considered unsafe for modern security requirements.

Secure Code Example – Java

1: ……
2: public byte[] encrypt(byte[] msg, Key k) {
3: byte[] rslt = null;
4:
5: try {
6: // 낮은 보안수준의 DES 알고리즘을 높은 보안수준의 AES 알고리즘으로 대체한다.
7: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
8: c.init(Cipher.ENCRYPT_MODE, k);
9: rslt = c.update(msg);
10: } catch (InvalidKeyException e) {
11: ……
12: }
13: return rslt;
14: }
15: }

Use the AES algorithm with at least a 128-bit key length instead of algorithms known to be weak.

D. References

[1] CWE-327: Use of a Broken or Risky Cryptographic Algorithm
[2] OWASP Top 10 2010 – A7 Insecure Cryptographic Storage

3. Use of Insufficiently Random Values

A. Definition

Using predictable random numbers causes vulnerabilities. Attackers can predict the next number generated by the software to compromise the system.

B. Secure Coding Techniques

When using a seed in a random number generator, it should be changed in a way that is difficult to predict.

C. Examples

Insecure Code Example – Java

1: ……
2: public double roledice() {
3: return Math.random();
4: }
5: }

Math.random() is risky because its seed cannot be reset.

Section 3. Security Features

Great care must be taken when handling fundamental security functions. The improper use of security features can result in performance degradation or additional complications. Security features include authentication, access control, confidentiality, encryption, and privilege management.


1. Transmission of Sensitive Information in Plaintext

A. Definition When software transmits sensitive security-related data in plaintext over a communication channel, it can be intercepted via sniffing by unauthorized entities.

B. Secure Coding Techniques Sensitive information must always be encrypted before being transmitted over a communication channel.

C. Examples

Insecure Code Example – Java

Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: int port = 443;
4: String hostname = "hostname";
5: Socket socket = new Socket(hostname, port); // Standard socket transmits in plaintext
6: InputStream in = socket.getInputStream();
7: OutputStream out = socket.getOutputStream();
8: // Read from in and write to out...
9: in.close();
10: out.close();
11: }

Using a standard socket to transmit data externally can lead to the exposure of data contents through packet sniffing.

Secure Code Example – Java

Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: int port = 443;
4: String hostname = "hostname";
5: SocketFactory socketFactory = SSLSocketFactory.getDefault(); // Use SSL/TLS
6: Socket socket = socketFactory.createSocket(hostname, port);
7: InputStream in = socket.getInputStream();
8: OutputStream out = socket.getOutputStream();
9: // Read from in and write to out...
10: in.close();
11: out.close();
12: }

It is advisable to encrypt sensitive information using at least a 128-bit key before transmitting it to a server over a network.

D. References

  • [1] CWE-319: Cleartext Transmission of Sensitive Information
  • [2] OWASP Top 10 2007 – A9 Insecure Communications

2. Use of Broken or Risky Cryptographic Algorithms

A. Definition Security-vulnerable or dangerous cryptographic algorithms must not be used. Using non-standardized algorithms increases the possibility of attackers analyzing and neutralizing them. Older algorithms like RC2, RC4, RC5, RC6, MD4, MD5, SHA1, and DES have become vulnerable as computing power increases.

B. Secure Coding Techniques It is recommended to use stronger, standardized cryptographic algorithms such as AES.

C. Examples

Insecure Code Example – Java

Java

7: Cipher c = Cipher.getInstance("DES"); // Vulnerable algorithm

Using the DES algorithm is considered unsafe for modern security requirements.

Secure Code Example – Java

Java

7: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Strong algorithm

Use the AES algorithm with at least a 128-bit key length instead of algorithms known to be weak.

D. References

  • [1] CWE-327: Use of a Broken or Risky Cryptographic Algorithm
  • [2] OWASP Top 10 2010 – A7 Insecure Cryptographic Storage

3. Use of Insufficiently Random Values

A. Definition Using predictable random numbers causes vulnerabilities. Attackers can predict the next number generated by the software to compromise the system.

B. Secure Coding Techniques When using a seed in a random number generator, it should be changed in a way that is difficult to predict.

C. Examples

Insecure Code Example – Java

Java

3: return Math.random(); // Predictable seed

Math.random() is risky because its seed cannot be reset.

Secure Code Example – Java

1: import java.util.Random;
2: import java.util.Date;
3: ……
4: public int roledice() {
5: Random r = new Random();
6: // setSeed() 메소드를 사용해서 r을 예측 불가능한 long타입으로 설정한다.
7: r.setSeed(new Date().getTime());
8: // 난수 생성
9: return (r.nextInt()%6) + 1;
10: }
11: }

java.util.Random generates different sequences and is safer when properly seeded.

D. References

[1] CWE-330: Use of Insufficiently Random Values
[2] SANS Top 25 2009 – CWE ID 330

4. Globally Accessible Files

A. Definition

Using arguments that allow other applications to access files (e.g., MODE_WORLD_READABLE, MODE_WORLD_WRITABLE) can compromise security and integrity.

B. Secure Coding Techniques

File access permissions should be kept to the absolute minimum required.

C. Examples

Insecure Code Example – Java

1: public void onCreate(Bundle savedInstanceState) {
2: super.onCreate(savedInstanceState);
3: try {
4: FileOutputStream fOut = openFileOutput("test", MODE_WORLD_READABLE);
5: OutputStreamWriter out1 = new OutputStreamWriter(fOut);
6: out1.write("Hello World");
7: out1.close();
8: fOut.close();
9: } catch (Throwable t) {
10: }
11: }

Setting the permission to MODE_WORLD_READABLE allows other applications to read the file.

Secure Code Example – Java

1: public void onCreate(Bundle savedInstanceState) {
2: super.onCreate(savedInstanceState);
3: try {
4: FileOutputStream fOut = openFileOutput("test", MODE_PRIVATE);
5: OutputStreamWriter out1 = new OutputStreamWriter(fOut);
6: out1.write("Hello World");
7: out1.close();
8: fOut.close();
9: } catch (Throwable t) {
10: }
11: }

Using MODE_PRIVATE ensures the file is inaccessible to external applications

D. References

[1] Android Developer Documentation
[2] KISA: Security Analysis of Android-based Mobile Operating Systems

5. Externally Accessible and Activatable Components

A. Definition

Components set to android:exported="true" in the AndroidManifest.xml can be activated by external intents. This can lead to security breaches by starting components in unintended states.

B. Secure Coding Techniques

It is preferable not to provide external access to internal components.

C. Examples

Insecure Code Example – XML

1: <?xml version="1.0" encoding="utf-8"?>
2: <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3: package="com.example.android.samplesync" android:versionCode="1" android:versionName="1.0">
4: ……
5: <application android:icon="@drawable/icon" android:label="@string/label">
6: <service android:name=".syncadapter.SyncService" android:exported=" true" >
7: <intent-filter>
8: <action android:name="android.content.SyncAdapter"/>
9: </intent-filter>
10: <meta-data android:name="android.content.SyncAdapter"
11: android:resource="@xml/syncadapter"/>
12: <meta-data android:name="android.provider.CONTACTS_STRUCTURE"
13: android:resource="@xml/contacts"/>
14: </service>
15: </application>
16: <uses-sdk android:minSdkVersion="5"/>
17: </manifest>

The android:exported="true" attribute for the SyncService is set to “true,” which allows external entities to trigger the component, potentially leading to security vulnerabilities.

Secure Code Example – XML

1: <?xml version="1.0" encoding="utf-8"?>
2: <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3: package="com.example.android.samplesync" android:versionCode="1" android:versionName="1.0">
4: ……
5: <application android:icon="@drawable/icon" android:label="@string/label">
6: <service android:name=".syncadapter.SyncService" android:exported=" false" >
7: <intent-filter>
8: <action android:name="android.content.SyncAdapter"/>
9: </intent-filter>
10: <meta-data android:name="android.content.SyncAdapter"
11: android:resource="@xml/syncadapter"/>
12: <meta-data android:name="android.provider.CONTACTS_STRUCTURE"
13: android:resource="@xml/contacts"/>
14: </service>
15: </application>
16: <uses-sdk android:minSdkVersion="5"/>
17: </manifest>

By setting the android:exported attribute to “false” or removing the setting entirely, the attribute defaults to “false,” thereby blocking activation from external sources.

D. References

[1] http://developer.android.com/index.html
[2] Security Analysis of Android-based Mobile Operating Systems, Korea Internet & Security Agency (KISA)

6. Access Control Bypass via Shared User ID

A. Definition

Setting the android:sharedUserId attribute allows different applications to access each other’s data if they share the same ID and signature, potentially compromising integrity

B. Secure Coding Techniques

It is advisable to avoid using shared user IDs.

C. Examples

Insecure Code Example – XML

1: ……
2: <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3: package="com.example.android.apis"
4: android:versionCode="1"
5: android:versionName="1.0"
6: android:sharedUserId="android.uid.developer1" >

By setting the android:sharedUserId attribute within the <manifest> tag of the AndroidManifest.xml file, other applications that possess the same sharedUserId value and application signature can gain access to all of this program’s data.

Secure Code Example – XML

1: ……
2: <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3: package="com.example.android.apis"
4: android:versionCode="1"
5: android:versionName="1.0">
6: <!-- android:sharedUserId=" android.uid.developer1" 삭제한다. -->

To prevent data leakage or the risk of unauthorized access due to ID sharing, the android:sharedUserId attribute should not be set within the <manifest> tag of the AndroidManifest.xml file.

라. 참고 문헌

[1] http://developer.android.com/index.html
[2] 안드로이드 기반 모바일 운영체제 보안기능 분석, 한국인터넷진흥원

Section 4. Time and State

Vulnerabilities related to time and state refer to weaknesses involving temporal concepts (such as processes or threads) or system state information (such as resource locking or session data) during program execution. Examples of such vulnerabilities include deadlocks, race conditions for resources, and session fixation.

Race Condition: Time-of-Check Time-of-Use (TOCTOU)

A. Definition

In a parallel execution environment, an application checks the state of a resource before using it. However, the state of that resource may change between the time of checking and the time of actual use. This can cause various issues in the program, such as deadlocks, race conditions, and other synchronization errors.

B. Secure Coding Techniques

When multiple threads access and use a shared resource (e.g., a file), the program should be written to ensure that only one thread can access it at a time by using synchronization blocks or statements.

C. Examples

Insecure Code Example – Java

1: public class UA367 extends Activity {
2: @override
3: public void onCreate(Bundle savedInstanceState) {
4: super.onCreate(savedInstanceState);
5: FileAccessThread fileAccessThread = new FileAccessThread();
6: FileDeleteThread fileDeleteThread = new FileDeleteThread();
7: fileAccessThread.start();
8: fileDeleteThread.start();
9: }
10: }
11:
12: class FileAccessThread extends Thread {
13: public void run() {
14: try {
15: File f = new File("Test_367.txt");
16: if (f.exists()) { // 만약 파일이 존재하면 파일내용을 읽음
17: BufferedReader br = new BufferedReader(new FileReader(f));
18: br.close();
19: }
20: } catch(FileNotFoundException e) {
21: System.out.println("Exception Occurred") ; // 예외처리
22: } catch(IOException e) {
23: System.out.println("Exception Occurred") ; //예외처리
24: }
25: }
26:
27: class FileDeleteThread extends Thread {
28: public void run() {
29: try {
30: File f = new File("Test_367.txt");
31: if (f.exists()) { // 만약 파일이 존재하면 파일을 삭제함
32: f.delete();
33: }
34: } catch(FileNotFoundException e) {
35: System.out.println("Exception Occurred") ; //예외처리
36: } catch(IOException e) {
37: System.out.println("Exception Occurred") ; //예외처리
38: }
39: }
40: }

In the example above, a time gap exists between checking for a file’s existence and actually using the file. If the file is deleted during this interval, the program may behave unexpectedly. Furthermore, this logic is vulnerable to attacks where a file is swapped or modified during that specific time gap.

Secure Code Example – Java

1: public class SA367 extends Activity {
2: public void onCreate(Bundle savedInstanceState) {
3: super.onCreate(savedInstanceState);
4:
5: FileAccessThread fileAccess = new FileAccessThread();
6: Thread first = new Thread(fileAccess);
7: Thread second = new Thread(fileAccess);
8: Thread third = new Thread(fileAccess);
9: Thread fourth = new Thread(fileAccess);
10: first.start();
11: second.start();
12: third.start();
13: fourth.start();
14: }
15: }
16:
17: class FileAccessThread implements Runnable {
18: public synchronized void run() {
19: try {
20: File f = new File("Test.txt");
21: if (f.exists()) { // 만약 파일이 존재하면 파일 내용을 읽음
22: Thread.sleep(100); // 시간이 소요되는 작업을 가정함
23: BufferedReader br = new BufferedReader(new FileReader(f));
24: System.out.println(br.readLine());
25: br.close(); // 파일 내용을 모두 읽은 후 삭제
26: f.delete();
27: }
28: } catch (IOException e) { // 예외처리
29: System.err.println("IOException occured");
30: }
31: }
32: }

When multiple threads access a shared resource, use synchronization constructs to ensure that only one thread can access the resource at a time.

D. References

[1] CWE-367: Time-of-Check Time-of-Use (TOCTOU) Race Condition – http://cwe.mitre.org/data/definitions/367.html

2. Improperly Controlled Recursion

A. Definition

It is dangerous to use excessive resources, such as allocated memory or the program stack, due to a failure to control the number of recursive cycles. In most cases, recursion without a proper base case results in infinite recursion.

B. Secure Coding Techniques

To prevent infinite recursion, all recursive calls must be executed only within conditional or loop blocks that ensure a termination point is reached.

C. Examples

Insecure Code Example – Java

1: ……
2: public int factorial(int n) {
3: // 재귀 호출이 조건문/반복문 블럭 외부에서 일어나면 대부분 무한 재귀를 유발한다.
4: return n * factorial(n - 1);
5: }

In recursively defined functions, if the recursive call occurs without a termination check outside of a conditional or loop block, it will likely lead to a stack overflow.

Secure Code Example – Java

1: ……
2: public int factorial(int n) {
3: int i;
4: // 모든 재귀 호출은 조건문이나 반복문 블럭 안에서 이루어져야한다.
5: if (n == 1) {
6: i = 1;
7: } else {
8: i = n * factorial(n - 1);
9: }
10: return i;
11: }

All recursive calls must be executed within a conditional or loop block.

D. References

[1] CWE-674: Uncontrolled Recursion – http://cwe.mitre.org/data/definitions/674.html

Section 5. Error Handling

Normal errors are predefined exceptions that occur under specific conditions, while abnormal errors are those that occur in situations that have not been predefined. By predefining and programming secure error-handling routines in preparation for both normal and abnormal errors, developers can prevent security threats that may arise during the error-handling process. Security vulnerabilities can occur when errors are handled insufficiently (or not handled at all), or when error messages contain excessive information that an attacker can exploit.

1. Information Exposure Through Error Messages

A. Definition

Software can leak internal program information such as the environment, users, and associated data through error messages. For example, printing the exception name or stack trace when an exception occurs makes it easy to understand the internal structure of the program.

B. Secure Coding Techniques

Software distributed to end-users should not output internal structures or sensitive information that could be utilized by an attacker in error messages.

C. Examples

Insecure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: super.onCreate(savedInstanceState);
4: try{ throw new IOException(); }
5: catch (IOException e) { e.printStackTrace(); }
6: }

Printing the exception name or stack trace leaks internal program information.

Secure Code Example – Java

1: ……
2: public void onCreate(Bundle savedInstanceState) {
3: super.onCreate(savedInstanceState);
4: try{
5: throw new IOException();
6: }
7: catch (IOException e) { System.out.println("예외발생" ); }
8: }

The exception name or stack trace is not printed.

D. References

[1] CWE-209 Information Exposure Through an Error Message – http://cwe.mitre.org/data/definitions/209.html

2. Improper Handling of Error Conditions

A. Definition

If an error is caught but no action is taken, the program continues to execute in that state, leading to consequences unintended by the developer.

B. Secure Coding Techniques

When an exception or error is caught, appropriate processing or handling for that error must be performed.

C. Examples

Insecure Code Example – Java

1: ……
2: private Connection conn;
3:
4: public Connection DBConnect(String url, String id, String password) {
5: try {
6: String CONNECT_STRING = url + ":" + id + ":" + password;
7: InitialContext ctx = new InitialContext();
8: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
9: conn = datasource.getConnection();
10: } catch (SQLException e) {
11: // catch 블록이 비어있음
12: } catch (NamingException e) {
13: // catch 블록이 비어있음
14: }
15: return conn;
16: }

In the example above, errors occurring in the try block are being caught, but no action is taken regarding those errors. Consequently, as the program continues to execute, it becomes impossible to know what occurred within the program.

Secure Code Example – Java

1: ……
2: private Connection conn;
3:
4: public Connection DBConnect(String url, String id, String password) {
5: try {
6: String CONNECT_STRING = url + ":" + id + ":" + password;
7: InitialContext ctx = new InitialContext();
8: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
9: conn = datasource.getConnection();
10: } catch (SQLException e) {
11: // Exception catch이후 Exception에 대한 적절한 처리를 해야 한다.
12: if ( conn != null ) {
13: try {
14: conn.close();
15: } catch (SQLException e1) {
16: conn = null;
17: }
18: }
19: } catch (NamingException e) {
20: // Exception catch이후 Exception에 대한 적절한 처리를 해야 한다.
21: if ( conn != null ) {
22: try {
23: conn.close();
24: } catch (SQLException e1) {
25: conn = null;
26: }
27: }
28: }
29: return conn;
30: }

After catching an exception, appropriate handling must be performed for each specific exception case.

D. References

[1] CWE-390: Detection of Error Condition Without Action – http://cwe.mitre.org/data/definitions/390.html
[2] OWASP Top Ten 2004 Category A7 – Improper Error Handling

Section 6. Code Quality

A completed program must maintain a certain level of code quality to satisfy functionality, reliability, usability, maintainability, efficiency, and portability. If program code is overly complex, it not only degrades manageability, maintainability, and readability but also makes it difficult to port to other systems. Furthermore, there is a possibility that vulnerabilities threatening safety may be hidden within such code.

1. Null Pointer Dereference

A. Definition

A null pointer dereference occurs when the assumption that “a specific object cannot be NULL” is violated. If an attacker intentionally triggers a NULL pointer dereference, they can use the resulting exception to plan further attacks.

B. Secure Coding Techniques

References that have the potential to be null must be checked for null values and used only when it is confirmed to be safe.

C. Examples

Insecure Code Example – Java

1: ……
2: public void f(boolean b) {
3: String cmd = System.getProperty("cmd");
4: //  cmd가 null인지 체크하지 않았다.
5: cmd = cmd.trim();
6: System.out.println(cmd);
7: ……

The example above assumes that the “cmd” property is always defined. However, if an attacker manipulates the “cmd” property, cmd becomes null, and a NullPointerException occurs when the trim() method is called.

Secure Code Example – Java

1: ……
2: public void f(boolean b) {
3: String cmd = System.getProperty("cmd");
4: // cmd가 null인지 체크하여야 한다.
5: if (cmd != null) { md = cmd.trim();
6: System.out.println(cmd);
7: } else System.out.println("null command");
8: …

Check if cmd is null first before using it.

D. References

[1] CWE-476: Null Pointer Dereference – http://cwe.mitre.org/data/definitions/476.html

Section 7. Encapsulation

When software insufficiently encapsulates important data or functionality, it fails to distinguish between authorized and unauthorized data, enabling data leakage among unauthorized users. Encapsulation is used not only to hide detailed implementation in general software development but also in a broader sense within the context of software security.

1. Private Array-Type Field Returned from a Public Method

A. Definition

If an array declared as private is returned through a public method, the reference to that array is exposed to the outside, allowing external entities to modify the array.

B. Secure Coding Techniques

Avoid returning arrays declared as private through public methods. If necessary, return a clone of the array or use separate public methods specifically designed to control modifications.

C. Examples

Insecure Code Example – Java

1: // private 인 배열을 public인 메소드가 return한다
2: private String[] colors;
3: public String[] getColors() { return colors; }

Although the member variable colors is declared as private, a reference to it can be obtained via the public getColors() method. This can lead to unintended modifications.

Secure Code Example – Java

1: private String[] colors;
2: // 메소드를 private으로 하거나, 복제본 반환, 수정하는 public 메소드를 별도로 만든다.
3: public void onCreate(Bundle savedInstanceState) {
4: super.onCreate(savedInstanceState);
5: String[] newColors = getColors();
6: }
7: public String[] getColors() {
8: String[] ret = null;
9: if ( this.colors != null ) {
10: ret = new String[colors.length];
11: for (int i = 0; i < colors.length; i++) { ret[i] = this.colors[i]; }
12: }
13: return ret;
14: }

By creating and returning a clone of the private array, unintended modifications to the original private array can be prevented.

D. References

[1] CWE-495: Private Array-Typed Field Returned From A Public Method – http://cwe.mitre.org/data/definitions/495.html

2. Assigning Public Data to a Private Array-Type Field

A. Definition

If data declared as public or an argument from a method is stored directly into a private array, the private array can be accessed and modified from the outside through the original reference.

B. Secure Coding Techniques

Ensure that public data is not directly stored in a private array.

C. Examples

Insecure Code Example – Java

1: ……
2: // userRoles 필드는 private이지만, public인 setUserRoles()를 통해 외부의 배열이 할당되면, 사실상 public 필드가 된다.
3: private String[] userRoles;
4:
5: public void setUserRoles(String[] userRoles) {
6: this.userRoles = userRoles;
7: }
8: ……

Even though the userRoles field is private, assigning an external array through the public setUserRoles() method essentially turns it into a public field due to the shared reference.

Secure Code Example – Java

1: ……
2: // 객체가 클래스의 private member를 수정하지 않도록 한다.
3: private String[] userRoles;
4:
5: public void setUserRoles(String[] userRoles) {
6: this.userRoles = new String[userRoles.length];
7: for (int i = 0; i < userRoles.length; ++i)
8: this.userRoles[i] = userRoles[i];
9: }
10: ……

By assigning the “values” of the array rather than the “reference” of the input array, the access rights of the private member are maintained.

D. References

[1] CWE-496: Public Data Assigned to Private Array-Typed Field – http://cwe.mitre.org/data/definitions/496.html

3. System Data Information Exposure

A. Definition

Exposing internal system data or debugging-related information provides attackers with insights and opportunities to plan further attacks.

B. Secure Coding Techniques

All code that outputs system information for debugging purposes must be removed.

C. Examples

Insecure Code Example – Java

1: ……
2: public void f() {
3: try { g(); }
4: catch (IOException e) {
5: // 예외 발생시 printf(e.getMessage())를 통해 오류 메시지 정보가 유출된다.
6: System.err.printf(e.getMessage());
7: }
8: }
9: private void g() throws IOException { …… }
10: ……

When an exception occurs, getMessage() can leak sensitive information, such as system error details related to the fault.

Secure Code Example – Java

1: ……
2: public void f() {
3: try { g(); }
4: catch (IOException e) {
5: // end user가 볼 수 있는 오류 메시지 정보를 생성하지 않아야 한다.
6: System.err.println(" IOException Occured" );
7: }
8: }
9: private void g() throws IOException { …… }
10: ……

Detailed information related to errors that could serve as a basis for an attack should not be exposed to end-users whenever possible.