Project Software Security: Securing SendMail with JAAS and Polymer Frank van Vliet frank@pine.nl Diego Ortiz Yepes d.a.ortiz.yepes@student.tue.nl Jornt van der Wiel j.h.v.d.wiel@student.tue.nl Guido Kok g.kok@student.utwente.nl 1 Introduction In this project, we develop a simple SendMail application which is then secured using two different technologies: the Java Authentication and Authorization Service (JAAS) [1] -for the authentication tasks-, and Polymer [2] -a research runtime security monitor- for the authorization tasks. The (unsecured) SendMail application design is discussed in Section 2, followed by its security aspects in Section 3. Subsequently, Section 4 compares JAAS and Polymer based on the experience in this project. Finally, the conclusions are presented in Section 5. 2 SendMail Design The SendMail application is expected to allow users to send email messages via a SMTP server. For this purpose, when invoking the application they have to provide the smtp server name, the email address of the originator, the email address of the recipient, the message subject, and the message contents (body). The application will examine these five parameters and if they are well-defined, the email message will be created and sent using the Java Mail API [3]. Figure 1 presents the sequence diagram of the main actions performed by the application to send an email message. As shown in Figure 2, when sending an email message, a Session object is instantiated (representing a SMTP run with the mail server) and a MimeMessage object is created and configured according to the message parameters (representing the message itself). The latter is transmitted to the specified SMTP server using the the Transport class. More information can be found in the Java Mail API [3]. Figure 1: Successful sequence of the SendMail class 1
Figure 2: Class diagram of the Sendmail Application 3 SendMail Security The main focus of this project is securing a SendMail application in such a way that any message that it sends must have been originated by a valid, logged on user whose username corresponds to the address of the message originator. In other words, according to the security policy it should not be possible for a user to send email messages from any other address than her own. Since the SendMail application is quite simple, it could have been easily secured by conventional means. However, a different approach consisting of delegating the authentication and authorisation on JAAS [1] and Polymer [4] resp. was used for this project. The particulars of this approach are presented in the remaining parts of this section. 3.1 JAAS After reviewing the JAAS authentication tutorial [5] and the JAAS documentation [1], we concluded that it was required to implement two classes: A Principal We named it PasswordPrincipal as it is related to a user who authenticated using her password. It corresponds to a user name, which for the SendMail application is expected -but not restrictedto be an email address. A LoginModule We named it PasswordAuthenticationModule (as requested by the project statement). It is responsible for authentication of users based on their username and password. The main decisions that we took regarding this module were: User names are stored along with the hash of a salt concatenated with the password in a password file. We decided upon hashing rather than encryption since hashing takes less time and offers enough security for our purposes. Note that the salt is used to add some randomness to the hashed values (passwords). Passwords are stored in memory for as short as possible. In fact, once password verification succeeds, the password is immediately erased from memory. The PasswordFileManager disallows de-serialization, as this could be used by an attacker to specify an arbitrary password file. A similar reasoning leaded to disallowing serialization and de-serialization of the PasswordAuthenticationModule. The location of the password file is not hardcoded, but can be specified via the JAAS configuration file, which adds flexibility to our application. Note that we assume that the JAAS configuration file is protected by suitable means so an attacker cannot specify an arbitrary password file through it. A separate class (PasswordFileManager) performing username/password verification was created in order to clearly separate the authentication responsibilities. 2
Figure 3: Sequence diagram of the secured SendMail Application using JAAS and Polymer All the design decisions presented above were taken in order to reduce potential threats, except the last two, which were motivated by architectural reasons. At the moment we do not see any new vulnerabilities introduced by our design decisions. The classes related to the authentication part (using JAAS) can be easily identified in the updated class and sequence diagrams illustrated in Figures 3 and 4 as their borders appear in a lighter colour. 3.2 Polymer Polymer [2] allows a policy to monitor the invocation of methods, allowing it to decide at run-time whether such invocations should be permitted or not. Policies can be applied to all Java applications, even when the source code is not known. To secure the SendMail application with Polymer, the policy as illustrated in Figure 5 was implemented. This policy is a combination of the generic sub-policies on the left branch 1 and a new sub-policy named Login, which ensures that all emails are sent from the email address of the logged in user. In order to accomplish these goals, the policy monitors and intercepts any calls to the following methods, which are identified by the thick arrow lines in Figure 3 2 : javax.security.auth.login.logincontext.login When the application invokes the login method on a LoginContext object, this object later contains all information regarding the logged in user (as a reference to a Subject object). As this information is required to make a decision in the javax.mail.transport.send method, a reference to the LoginContext is stored in the policy object. Note that all invocations of this method are allowed since the only goal is to store the reference to the LoginContext. javax.mail.transport.send When the application tries to send an email, the policy only allows it if the logged in user matches the message s from address. To make this decision, the reference to the LoginContext object is used to retrieve the current user s Subject. Then, the email address of the message originator is compared to the PasswordPrincipal which was added to the user s Subject during the login process. In case that the email addresses match, the email is allowed to be sent, otherwise, the SendMail application is halted by Polymer. 1 These policies prevent any target from loading classes itself or executing system commands, and are not specific to the SendMail application. 2 We acknowledge that as Polymer monitors the complete application it should be associated with all the classes loaded at run time. Further, polymer in Figure 3 represents all classes related to Polymer (including for instance the bytecoderewriter). However, our purpose in this diagram is to identify the exact places where it actually intercepts the security sensitive calls. 3
Figure 4: Class diagram of the secured SendMail Application using JAAS and Polymer Policy Conjunction Dominates Login Conjunction Dis- SysCalls Class- Loaders NoOpen- ClassFiles Figure 5: Policy for the SendMail application 4
In this simple design, the user s email address equals her username. In a real life situations, users might have multiple addresses and a database should be used. It is also assumed that the program uses a valid JAAS authentication module to authenticate her users. In fact, the system administrator should ensure that a current and genuine JAAS authentication module is used, since such module is trusted by the policy to report the logged in username. Furthermore, it is important to note that only the javax.mail.transport.send method is restricted by the Login sub-policy. There are many other ways to send email messages, for instance, by directly opening a socket to an SMTP server. In this line of thought, it is then our opinion that for unknown applications policies should be implemented at the lowest possible layer, for instance, at the socket API methods. 3.3 Security Overview and Assumptions Securing an application with JAAS and Polymer is a very interesting idea because it allows separating the application functionality from the security concern. Furthermore, it allows reusing existing infrastructures specifically designed to provide security services, not having to reinvent the wheel in order to use these services in the secured application. It is important to bear in mind, however, that just by using JAAS and Polymer it cannot be claimed that the application is 100% secure. In fact, there are other layers where further security measures are required, which are assumed to be provided by other suitable means. For instance, it should be impossible for regular users to access both the password file or the JAAS configuration file. Further, the Polymer design imposes three requirements in order to effectively secure an application. First, the application should be invoked by Polymer and not directly by the JVM; second, all libraries (including the JRE) which are used by the application should have been instrumented by Polymer prior to execution; and third, any class used by the application must be loaded by Polymer s class loader. We assume that there is no way for a malicious user to bypass any of this requirements, as doing so would result in the application not being effectively monitored by Polymer. Provided that these security assumptions hold, we consider that the SendMail application adequately satisfies the security requirement that the logged in user should match the originator address of any email message sent using the application. 4 JAAS versus Polymer From our experience with JAAS, we would like to remark the following facts: 1. Using it is as easy as using any other Java API functionality (it is included in the JDK). 2. Understanding it and using it is an uncomplicated task due to the completeness of its documentation. 3. Its architectural design is nice: the possibility of creating, using and combining arbitrary authentication modules is particularly remarkable. 4. It is a pity that an extensive library/collection of audited JAAS authentication modules is not available. On the other hand, regarding Polymer, we consider it important to mention that: 1. It allows a clear separation of concerns, in this case, security. 2. Policies can be reused across applications. 3. It is flexible: it allows the designer to specify policies at the method call level, which is quite powerful. However, its flexibility could be improved by allowing the usage of dynamic information in the action declaration file, besides the static method information (method signature) which is currently supported. This would allow the monitor to determine whether calls match a given action based on such dynamic information 3. 4. The compositionality of policies is a superb feature. The fact that policies can be structurally composed using combinators and selectors allows implementing complex security policies in an easily and understandable way. 3 This functionality is mentioned in [2] but it does not seem to be implemented in the code 5
5. Learning how to use it is difficult, mainly due to the following reasons: There is almost no documentation. Naming in [2] and the actual implementation differs. For example, what in the paper are referred as IrrSugs, in the code are referred as UnregSuggestions. There are no guidelines on how to write good policies. 6. The distribution of Polymer found at the Leuven website [6] contains an ant script file. We think that the original distribution [4] should have this file too because ant -unlike make- is portable across different platforms. 7. When Polymer instruments a method like send of the class Transport, it copies this method to Transport send $$POLY METHOD$$ (a backdoor method). It then creates its own send method which calls the backdoor Transport send $$POLY METHOD$$ method if the policy allows it. When instrumenting a private method, the backdoor method is made PUBLIC, to make it accessible from the Polymer classes. This is a very important security-breaking design flaw. Now the private methods which are instrumented can be accessed by any other class by invoking the backdoor method. Polymer tries to reduce this problem by denying invocations of backdoor methods while loading and instrumenting the classes. However, it does not instrument classes in the TCB packages: sun., com.sun., javax., java. and polymer (as defined in the constructor of polymer.polymerclassloader. In this order of ideas, to call one of the backdoor methods (bypassing the monitor) it suffices to do so from a class added to one of the TCB packages 4. 8. Even though the usage of aspect oriented programming technologies allows the separation of concerns, understanding the run time application behavior might end up being quite complicated, especially when policies become complex. Furthermore, the use of this technologies might induce endless loops or behaviors that are not feasible when the non-monitored application is executed, as presented below. 9. The Polymer class loader might create multiple instances of a given class, which cripples the target application whenever it uses comparisons based on Class objects. For instance, an execution trace such as the one below which works when the application is executed in standalone mode, throws an exception when executed inside Polymer: Subject s = new Subject ( ) ; PasswordPrincipal p = new PasswordPrincipal ( " test@cs. ru. nl" ) ; s. add ( p ) ; (... ) if ( s. getprincipals ( MyPrincipal. class ). length()==0) Throw new PolymerCrippledTheApplication ( ) ; System. out. println ( "ok" ) ; In the context of this project, comparing JAAS and Polymer from a functional point of view is not possible given that they were used for different purposes, namely, authentication and authorization. Therefore, rather than comparing them using that criterion, we decided to base our comparison on some other aspects as shown below: Both are flexible, extensible, and reusable. Usability: Polymer was found to be much more difficult to use than JAAS. In fact, JAAS is well documented and requires a short learning curve, while Polymer was found to be quite complicated to use, poorly documented and has a long learning curve. Design: Both the design of Polymer and JAAS are quite nice. Although Polymer requires some special setup (link to the three requirements of polymer stated in the assumptions section). Security: We were able to bypass Polymer and not able to bypass JAAS. 4 see javax.evil.sendmailevil, a class that we created which bypasses the Polymer monitor using this trick. In order to execute the hack, compile the application as specified in the README file and execute the javax.evil.sendmailevil class instead of ss.sendmailcli (or use the runevil script) 6
5 Conclusion We found securing software by means of authentication and authorization an interesting experience. We all had experience on breaking into software (Hacker s hut course) and writing secure code (from the same course), but we lacked hands-on experience on securing software by using authentication and authorisation provided by specialized tools and APIs. We were rather disappointed and frustrated by the unreasonable amount of time taken to configure and get Polymer working, which was exacerbated by the fact that writing Polymer code took much less time than configuring the tool. When it comes down to comparing Polymer and JAAS, for the reasons discussed at the end of the Section 4, we can say that our overall experience with JAAS was much better than with Polymer. On the other hand, we understand that Polymer -unlike JAAS, which is a mainstream part of the standard JDK- is a research tool, which still has several issues that need to be resolved (such as the hack we discovered) and smoothed before being usable outside the software security research community. References [1] S. M. Inc. (2007, May) Java authentication and authorization service (jaas). [Online]. Available: http://java.sun.com/products/jaas/ [2] L. Bauer, J. Ligatti, and D. Walker, Composing security policies with Polymer, in Proceedings of the 2005 ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI), Jun. 2005, pp. 305 314. [Online]. Available: http://www.ece.cmu.edu/ lbauer/papers/polymer-pldi05.pdf [3] S. M. Inc. (2007, May) Javamail api. [Online]. Available: http://java.sun.com/products/javamail/ [4] L. Bauer, J. Ligatti, and D. Walker. (2007, May) Polymer: Software monitoring in theory and practice. [Online]. Available: http://www.cs.princeton.edu/sip/projects/polymer/ [5] S. M. Inc. (2007, May) Jaas authentication. [Online]. Available: http://java.sun.com/j2se/1.5.0/docs/ guide/security/jgss/tutorials/acnonly.html [6] F. Piessens and T. Verhanneman. (2007, May) Practicum ontwerpen van veilige software (ovs) - 2006. [Online]. Available: http://www.cs.kuleuven.ac.be/ tine/ovs/index.htm 7