INTRODUCTION CURRENT STATUS ICTS2005 The Proceeding

Information and Communication Technology Seminar, Vol. 1 No. 1, August 2005 ISSN 1858-1633 2005 ICTS 94 SECURITY CONCERN REFACTORING Putu Ashintya Widhiartha 1 and Katsuhisa Maruyama 2 1 Graduate School of Science and Engineering, Ritsumeikan University 2 Department of Computer Science, Ritsumeikan University 1-1-1 Noji-higashi Kusatsu Shiga 525-8577, Japan widhifse.is.ritsumei.ac.jp and marucs.ritsumei.ac.jp ABSTRACT Computer security recently becomes a serious issue. However, it is still difficult to build secure software. This paper proposes a method of increasing security level of software in the coding phase by using software refactoring. Refactoring is the process of improving the internal structure of existing code without changing its external behavior. In this paper, seven refactorings concerning security and transformations toward their automation are presented. An automated security refactoring tool makes it easier to improve security level of existing software. Keywords : software development, refactoring, software restructuring, security, software design

1. INTRODUCTION

In the recent era when computers are connected each others, they become vulnerable to an attack. There are many reasons for the attackers to attack a system such as business competition, data manipulating, bandwidth stealing, or even just for their fun. On the contrary, for the developers an attack could cause serious issue especially for the large developer due to the reliability of their systems or software would be questionable by their customers. The best manner to avoid an attack to our software is to increase its security level. Certainly the security level of software depends on each phase of software development such as requirement analysis, design, coding, testing, and maintenance. Increasing security level of each phase will guide entire software to be more secure. This paper proposes a method of increasing security level of software in the coding phase by using software refactoring [1]. Refactoring is originally the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is proper to be applied in design and coding phase of software development [2]. The contribution of this paper is to collect several code transformations with respect to security level improvement under the framework of refactoings and show the possibility of automating those transformations. An automated refactoring tool supporting such transformations makes existing code more secure without changing its observable behavior. Our proposed refactorings can improve security level of software while traditional refactoring aims at making existing software easier to understand or modify. We first describe traditional techniques on secure programming. Next we present the design of some security concern refactoings. Then we explain a refactoring tool that has been and will be developed. Finally, we conclude a summary.

2. SECURE PROGRAMMING

There are many ways to help programmer for increasing the security level of their code. In CC++ platform we could consider CryptoAPI as a reliable tool for protecting secret data. In Java we know the Java Authentication and Authorization Service JAAS for securely determine who has the authorization to execute a Java code. However, it will give more benefit to the developer if there are many alternatives for creating secure code and in this paper we propose an alternative way by using refactoring in Java platform. Since the numbers of the flaws to software are unlimited, it will be difficult to determine the most important factor in secure programming. However from several references such as [3] and [4] we try to determine the factors which are important to be applied in a source code for increasing its security level. Although some of the aspects has been tackled by existing tools now, but we will explain briefly about them.

2.1. Buffer Overrun

When the size of an array input is not verified, it is possible to write outside the allocated buffer. If such an action takes place in memory addresses higher than the buffer, it is called a buffer overrun [5]. By entering a hostile input, the attacker will read an address of the input character in the memory if buffer overrun happens. Consequently, the validation of input string is an important factor in order to avoid buffer overrun. Actually, this flaw is not a big issue in Java since Java has input validation tool, called a bytecode verifier. Security Concern Refactoring – Putu Ashintya Widhiartha Katsuhisa Maruyama ISSN 1858-1633 2005 ICTS 95

2.2. Cryptography

According to [4], strong cryptography is a critical piece of information security that can be applied at many levels from data storage to network communication. People always think that cryptography is important to protect data from attacking. However, people usually are not realizing that the misapplication of cryptography commonly leads to the security problem. The ability to protect and secure information is vital to the growth of internet especially electronic commerce. We can imagine a bank which is giving service to the customer via internet, absolutely the bank should provide a secure method for the customer for accessing their account. Thus, the bank will need a cryptography method which is able to protect data sending from and to its server. Mostly Java programmers write code at a higher level, dealing mostly with the APIs, in other word they have no strong connection with the principles and algorithm behind cryptographic. Although Java provides two APIs, JCA Java Cryptography Architecture and JCE Java Cryptography Extension, but still there are opportunities to improve the quality of code security by learn more about cryptography principles and implement it into our code.

2.3. Random Numbers

Random numbers is often required in order to provide a key in cryptography. Although random numbers seem as unimportant factor but it could guide to a problem in secure programming. Generating random numbers by using predictable manner will ease attackers to disturb our software. Thus we need to consider the secure method for generating random numbers.

2.4. Anti-Tampering

Reverse engineering has been known as a threat to the security of software. With anti-tampering mechanisms we will be able to increase the security level of our software by protecting secret data or algorithm and ensuring proper execution of our software. Although there are no easy answers for avoiding reverse engineering from our compiled code but we can still apply several anti-tampering techniques in order to create obstacles for people who wants to gain the protecting information in our software.

2.5. Error Handling

Error handling is also simple matter which could lead to the security problem if we do not pay more attention on it. The most common problem in error handling occurs when the internal error messages provide too detail information such as stack traces which should not be revealed to the user. This simple information could be used by an attacker to disturb our software. Consequently, the solution of this flaw is by providing robust error handling which provide enough information to the user about the error without revealing any protected information.

2.6. Injection Flaws

There are many programs which work by accessing the other programs or operating system features. If we write a code that access to the operating system and the code does not have any protection, a malicious code could be implanted in our program and there will be possibility that the malicious code will be able to access the operating system also. Certainly, the easiest way to solve this problem is by avoiding any access to the other programs or operating system. For many shell commands and some system calls, there are language specific libraries that perform the same functions which are needed by us. Using such libraries does not involve the operating system shell interpreter, and therefore avoids a large number of problems with shell commands [8]. However, if we have to access the operating system or the other program we should provide a secure operation and provide protected parameter into the operation call.

2.7. Security Features in Java

Indeed, besides the above aspects there are still many aspects for secure programming. However we will focus on some aspects which are applicable to be implemented in Java and also open opportunity to apply refactoring. Java, which will be used as the platform of this paper, is known as a programming language with large numbers of security features [10]: a. Java has no pointer; it means that a Java code is not able to directly access arbitrary memory locations in the address space. b. As mentioned above, Java has bytecode verifier. This feature is very useful for avoiding buffer overflow attacks because this feature checks the length of the input before the execution. If the length is not proper, Java will reject the input. c. Java has Fine-grained control over resource access for both applets and applications. For instance, an applet could be prohibited from writing or reading to disk space. d. Java has a large number of library functions for cryptographic building blocks and SSL, and authentication and authorization. Consequently, it is quite difficult to find opportunity for applying secure refactoring in Java, however we try to determine several applicable secure refactoring and expect that our efforts will be able to increase the security level of a Java code. Information and Communication Technology Seminar, Vol. 1 No. 1, August 2005 ISSN 1858-1633 2005 ICTS 96

3. DESIGN OF SECURITY CONCERN REFACTORINGS

We present several refactorings, which are considered applicable to be implemented in Java, in order to increase the security level of its source code.

3.1. Encapsulate Field

One important requirement of secure code is data hiding. In the other word we can say that we have to avoid for making our data public [1]. The easiest way, although perhaps not secure enough, is by creating our data become private. This type of refactoring is included in 72 types of refactorings in [1]. Figure 1 shows codes before and after applying Encapsulate Field refactoring. An accessibility setting of a variable something was changed from public to private so that the value of the variable can not be directly read and written. Figure 1. Encapsulate Field refactoring

3.2. Restructuring Arrays

In [4], Viega and Messier wrote that one way of anti-tampering effort is by restructuring arrays. Since arrays can describe the information in their structure, it will help the attacker for understanding our code. Restructuring arrays in order to protect our data structure from tampering can be done by changing the structures of our arrays. Indeed, arrays is a weak data structure if we compare with a collection in Java but still arrays are used by large number of Java programmers. Consequently, we would like to provide refactoring for restructuring arrays in Java as one feature to increase the security level of the code. Referring to [4], we could restructure our arrays in four ways: a. Splitting a one-dimensional array into multiple one-dimension arrays see Figure 2. b. Folding a one-dimensional array into multi- dimensional array see Figure 3. c. Merging two one-dimensional arrays into a single one-dimensional array see Figure 4. d. Flattening a multi-dimensional array into a one- dimensional array see Figure 5. Definitely, restructuring arrays should be done not only in the declaration of the arrays such as double[ ] data = new double [20] but also in the accessing methods of the arrays. Figure 2. Array Representation of Splitting Arrays refatoring Figure 3. Array Representation of Folding Arrays refatoring Figure 4. Array Representation of Merging Arrays refatoring before refactoring public String something; after refactoring private String something; public String getSomething { return something; } public void setSomethingString argument { something = argument; } before refactoring A1 A2 A3 A4 A5 A6 after refactoring A1 A3 A5 A2 A4 A6 before refactoring A1 A2 A3 A4 A5 A6 A7 A8 after refactoring A1 A4 A7 A2 A5 A8 A3 A6 before refactoring A1 A2 A3 A4 A5 A6 A7 B1 B2 B3 after refactoring A1 A2 B1 A3 A4 B2 A5 A6 B3 A7 A1 A2 Security Concern Refactoring – Putu Ashintya Widhiartha Katsuhisa Maruyama ISSN 1858-1633 2005 ICTS 97 Figure 5. Array Representation of Flattening Arrays refatoring.

3.3. Generating Secure Random Number

As mentioned above, generating random number seems become an unimportant aspect in security. However, if we could increase the security level of our code by altering a piece of our code without change the behavior of entire program, we should try to use more secure method or class in our code. For Java programmers, it does not need big effort for changing random generator to a more secure one. Java provides java.util.Random class for generating random number. Despite of using this class it will be better if we use its subclasses java security.SecureRandom. This class provides a cryptographically strong pseudo-random number generator PRNG. The Secure Random class must produce non-deterministic output and therefore it is required that the seed material should be unpredictable and the output of the SecureRandom class will be cryptographically strong sequences as described in RFC 1750: Randomness Recommendation for Security [9]. The mechanism of this refactoring could be observed in Figure 6. Perhaps people will ask what are the weaknesses of SecureRandom class compared with Random class? The answer is the features of SecureRandom are less than Random class. This is a common dilemma for secure programming since the features of the software and the security level usually opposite each other [3]. Figure 6. Secure Random Number refactoring

3.4. Storing Deleting Passwords

We know that in Java programming language String variable are immutable, it means we are not able to delete them from memory. This unique characteristic of Java String data type leads us to avoid using it for passwords because String passwords will stay in memory and vulnerable from snooping [10]. Even worse, if real memory runs low, the operating system might page this password String to the disk’s swap space. Therefore, it will be vulnerable to disk block snooping. The solution, although not a perfect solution, is by substituting the String passwords with Char arrays passwords. Figure 7 shows codes before and after applying the StoringDeleting Password Refactoring. The last line is needed in order to overwrite the value of PassKey variable in memory with fake value. Figure 7. Storing Deleting Password Refactoring

3.5. Smart Serialization

Java has ability to serialize object for storage or transmission. Unfortunately, since any private field also will be present in the stream during this process, sensitive data is vulnerable to snooping when objects are serialized [10]. We could use transient keyword to flag an attribute so that it will be skipped in the streaming. In Figure 8, the keyword transient was attached to the code after a Smart Serialization refcatoring. Figure 8. Smart Serialization Refactoring

3.6. Message Digest

Message Digest is a security feature that ensures the integrity of a message. Message digest use a message as input and generate a block of bits that represents the fingerprint of the message. Each small change in the message automatically will create a change in the fingerprint. Although using java.security.MessageDigest class is definitely easy and secure, however for easing programmers maintain their code security we would like to propose the refactoring which helps programmers for create their message digest. before refactoring String PassKey = “enter”; after refactoring char KeyInChar[ ] = {‘e’,’n’,’t’,’e’,’r’}; String PassKey = new StringKeyInChar; ………… after execution lines String PassKey = “fake passwords”; before refactoring A 11 A 12 A 13 A 21 A 22 A 23 A 31 A 32 A 33 after refactoring A 11 A 21 A 31 A 12 A 22 A 32 A 13 A 23 A 33 before refactoring private char KeyInChar[ ] = {‘e’,’n’,’t’,’e’,’r’}; after refactoring private transient char KeyInChar[ ] = {‘e’,’n’,’t’,’e’,’r’}; before refactoring import.java.util.random; Random generator = new Random ; int ran = generator.nextInt ; after refactoring import.java.security.SecureRandom; SecureRandom generator = new SecureRandom ; int ran = generator.nextInt ; Information and Communication Technology Seminar, Vol. 1 No. 1, August 2005 ISSN 1858-1633 2005 ICTS 98 In the code after a Message Digest refactoring of Figure 9, new code fragments for creating a message digest object and calculating the digest were inserted.

3.7. Convert Message with Private Key to Public Key

A message which is encrypted by using Private Key such as DES, AES, or Blowfish has a weakness. The problem is: how to send the key to the receiver without a risk of information disclosure. Since Java also allows for using Public Key for encryption, it is more secure to use Public Key to increase the security level of our message. Figure 9. Message Digest refactoring Next are the principles of Public Key implementation [10]. • When a sender wants to send a secure message to the receiver, she needs to encrypt the message. Therefore she does the encryption by using receiver public key and sends. The receiver could use her private key to decrypt the message. • The receiver also could do the same method to send message to the sender. It means the private keys of the receiver and sender are never sent. • The third party could get the message and both public keys but she will not be able to decrypt the message. It opens opportunity to apply a refactoring to a method or class which is using private key to encrypt a message. We could propose for using Public Key in order to increase the security level of the code. Figure 10 and 11 show codes before and after applying a Convert Message refactoring. before refactoring this code read the plain text input but we assume that the programmer did not create any effort to protect the plain text. public static void main String[ ] args throws Exception { get plain text from input if args.length =1 { System.err.println“ Please provide the text parameter”; System.exit1; } byte [ ] plaintext = args[0].getBytes“UTF8”; } after refactoring MessageDigest function is added import java.security.; import javax.crypto.; public static void main String[ ] args throws Exception { get plain text from input if args.length =1 { System.err.println“Please provide the text parameter”; System.exit1; } byte [ ] plaintext = args[0].getBytes“UTF8”; crete a message digest object by using the MD5 algorithm MessageDigest fingerprint = MessageDigest.getInstance“MD5”; calculate the digest and print it out fingerprint.update plaintext; System.out.println“\Digest: “; System.out.printlnnew String fingerprint.digest ,”UTF8”; } Security Concern Refactoring – Putu Ashintya Widhiartha Katsuhisa Maruyama ISSN 1858-1633 2005 ICTS 99 figure 10 Convert Message refactoring in Encrypting a message. Figure 11 Convert Message refactoring in Decrypting a message. before refactoring this is a class which is using DES private key for encryption of a message import java.security.; import javax.crypto.; public class EncryptExample { public static void mainString[ ] args throws Exception { get the plain text if args.length =1 { System.err.println“Please provide the text”; System.exit1; } byte[] MessageText = args [0].getBytes“UTF8”; get a DES key KeyGenerator KeyGene = KeyGenerator.getInstance“DES”; KeyGene.init56; Key kagi = KeyGene.generateKey ; Cipher cipher = Cipher.getInstance“DESECBPKCS5Padding”; starting encryption cipher.initCipher.ENCRYPT_MODE, kagi; byte[ ] cipherText = cipher.doFinalMessageText; System.out.printlnnew StringcipherText,”UTF8”; } } after refactoring this is a class which is using RSA public key for encryption of a message import java.security.; import javax.crypto.; public class EncryptExample { public static void mainString[ ] args throws Exception { get the plain text if args.length =1 { System.err.println“Please provide the text”; System.exit1; } byte[] MessageText = args [0].getBytes“UTF8”; get a RSA key KeyPairGenerator KeyGene = KeyPairGenerator.getInstance“RSA”; KeyGene.initialize1024; KeyPair kagi = KeyGene.generateKeyPair ; Cipher cipher = Cipher.getInstance“RSAECBPKCS1Padding”; starting encryption cipher.initCipher.ENCRYPT_MODE, kagi.getPublic ; byte[ ] cipherText = cipher.doFinalMessageText; System.out.printlnnew StringcipherText,”UTF8”; } } applying refactoring into decryption lines before refactoring cipher.initCipher.DECRYPT_MODE,kagi; byte[] newMessageText = cipher.dofinalcipherText; System.out.printlnnew StringnewMessageText, “UTF8”; after refactoring cipher.initCipher.DECRYPT_MODE,kagi.getPrivate; byte[] newMessageText = cipher.dofinalcipherText; System.out.printlnnew StringnewMessageText, “UTF8”; Information and Communication Technology Seminar, Vol. 1 No. 1, August 2005 ISSN 1858-1633 2005 ICTS 100

4. CURRENT STATUS

We have already developed a refactoring browser [11] for Java programs, which is available for free. It supports the application of 22 general refactorings including the Encapsulate Field refactoring mentioned in 3.1. We are currently developing algorithms of transformations of the proposed refactrorings except the Encapsulate Field refactoring and constructing a module that implements each of the algorithms. The modules will be integrated into the refactoring browser or a popular IDE integrated development environment such as Eclipse [12] as plug-in. In the proposed refactoring browser, the task to check preconditions and change code is automated. However, almost all security concern refactorings require a refactoring browser to automatically detect “bad smell” concerning security, which might or will be a security hole. We are also developing a mechanism for such detection.

5. CONCLUSION