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