Vous êtes sur la page 1sur 41

Bachelor Thesis EmployeeWeb - Redesign of spirit-news and integration into the spirit@fhs ecosystem

Bachelor of Science - Computer Science -

Faculty of Computer Science Supervisor: Prof. Dr. Oliver Braun Assessor: Prof. Dr. Dietmar Beyer Author: Marcus Denison Matr.-Nr. 280362 Brckenauerstr. 21 97772 Wildecken Schmalkalden, 09-01-2011

Abstract This thesis deals with the implementation of EmployeeWeb, a web application which can be integrated into the spirit@fhs ecosystem. The key task of EmployeeWeb is to act as the frontend for all employees in order to create/update news or events which concern the students at the faculty of computer science. Based on the ideas from spirit-news, EmployeeWeb was designed from scratch to have a cleaner code base. EmployeeWeb received a more modular User management layer, a persistence layer based on the Active Record Pattern and the option of being upgraded very easily. The prototype was developed using the Lift webframework, a secure and scalable framework using the Scala programming language.

Acknowledgements Many among my fellow students, professors that have taught me my knowledge, the Lift Community, my supervisor during my internship and at last but not least my parents have greatly deserved to be honorably mentioned.

Contents
1 Introduction 2 Goals 3 Background 3.1 Scala: Functional and Object-oriented programming 3.1.1 Functional Scala . . . . . . . . . . . . . . . 3.1.2 Object-oriented Scala . . . . . . . . . . . . . 3.2 Lift: A web framework implemented with Scala . . 3.2.1 A brief history . . . . . . . . . . . . . . . . 3.2.2 Design Goals . . . . . . . . . . . . . . . . . 3.2.3 Goodbye MVC, Hello V-VM-M . . . . . . . 3.2.4 Lifts answers to OWASP Top 10 . . . . . . 4 Analysis of the current implementation 4.1 User Management . . . . . . . . . . . 4.2 Persistence Layer . . . . . . . . . . . 4.3 Security vulnerabilities . . . . . . . . 4.3.1 Session Stealing . . . . . . . . 4.3.2 Cross Site Scripting . . . . . . 4.3.3 SQL Injection . . . . . . . . . 4.4 Design failures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 3 3 4 5 5 5 6 7 9 9 12 13 14 14 16 16 19 19 21 23 24 26 26 28 28 30 31 32 37

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

5 A new implementation from scratch 5.1 Authentication Module . . . . . . . . . . . . . . . 5.2 SpiritRecord based on the Active Record Pattern 5.3 A cleaner design . . . . . . . . . . . . . . . . . . . 5.4 DRY - Dont repeat yourself . . . . . . . . . . . . 6 Integration into the spirit@fhs ecosystem 6.1 SPIRIT . . . . . . . . . . . . . . . . . . 6.2 StudWeb . . . . . . . . . . . . . . . . . . 6.3 RESTful DB-Service . . . . . . . . . . . 6.4 Merging with PlanningWeb . . . . . . . 7 Conclusion and Future work Bibliography Statutory declaration

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

Marcus Denison

IV

1 Introduction
Innocent Code - A Security Wake-Up Call for Web Programmers is the title of a book by Sverre H. Huseby [Hus03]. It addresses the needs of developing secure web applications. Sverre H. Huseby sets up 27 best practices, how one can evolve to a better web programmer. Web application security does not start with a rewall nor with encryption, rst of all it is more the developer which has to be sensitised in writing more reliable and secure code. It is important that the developer understands the complete chain between data input on the client side and data processing on the server side. The Web Application Security Consortium released the Web Application Security Statistic Project in 20081 , which revealed data about over 12,000 web applications with more than 97,000 detected vulnerabilities of dierent risks. Around 13 percent of the tested web applications were vulnerable to be compromised completely automatically. Half of the tested web applications contained high risk level vulnerabilities. Cross Site Scripting was the most found security issue with overall 39 percent, this problem problem is based in the code of the web applications. In addition there were around 41.000 vulnerabilities found on administrative side. The Lift web framework praises itself to be a secure web framework, which will be illustrated in chapter 3. The objectives of this thesis is it to analyse spirit-news, a web application which was implemented with Lift and a novice developer, as well as re-implement this web application with a developer who had a deeper look into the Lift libraries and integrate the new implementation into the spirit@fhs ecosystem.

http://projects.webappsec.org/w/page/13246989/Web-Application-SecurityStatistics

Marcus Denison

Page 1 of 37

2 Goals
Primary goal is it to get a better understanding of the Lift libraries and the creation of a cleaner design which can be adopted for new features within the project. It is also necessary to take a closer look at the security features which are integrated into the web framework. The following Steps which will be taken throughout this thesis: Analysing the implementation of spirit-news and which false decisions were made, due to lack of experience. Taking a short glance at the security, since it was not taken into consideration when spirit-news was implemented. Taking spirit-news apart, create modules and use more of Lift internal libraries for implementing features. Evaluate the new design, whether it is ecient enough to be used any further in this project. Integrating the new implementation into the spirit@fhs ecosystem and which possible failures for the design it might bring. In each chapter one or more of these steps will be evaluated. The output will be a sample web application as a prototype, which is not meant to be fully functional but will be released as an open source project, so anyone could work on this to make it really work.

Marcus Denison

Page 2 of 37

3 Background
"Modern Applications Demand Modern Tools" was stated on the greylockpartners blog1 when theyve invested $3 million Dollars into the new founded company TypeSafe2 by Martin Odersky3 . Preparing for a new era, it is important to take a look at modern programming languages and their frameworks. A quick introduction into the Scala4 Programming Language and an overview of the Lift5 web framework is going to be part of this chapter. In this thesis Scala 2.8.1 and Lift 2.3 are outlined.

3.1 Scala: Functional and Object-oriented programming


The name Scala stands for scalable language. The language is so called because it was designed to grow with the demands of its users. [OSV10, P. 3] It combines the world of the object-oriented [Mey00] with the functional programming paradigm [Bar11, P. 292 f.]. One of the key features is that Scala compiles down to Java Byte Code which means it runs awlessly on the Java Virtual Machine, so any Java library can be used within Scala program code without a problem.

3.1.1 Functional Scala


Collections After version 2.7.7, Scala introduced a re-design of the collections library, which now is very powerful. Creating either a mutable or immutable collection, they inherit very useful methods from the Traversable trait, such as map atMap foldLeft foldRight foreach collect and many more6 which help the developer to write concise and readable program code. Lazy Evaluation Using the keyword lazy as a modier in front of a denition for a value, it is set for lazy evaluation. Therefore in the process of object instantiation, the value is not evaluated. Once the value is called it will be evaluated, the evaluation is only done once and the result is saved into that value. Only val s can
1

http://greylockvc.com/2011/05/12/why-we-invested-in-typesafe-modernapplications-demand-modern-tools/ 2 http://typesafe.com/ 3 http://people.epfl.ch/martin.odersky 4 http://www.scala-lang.org 5 http://www.liftweb.net 6 http://www.scala-lang.org/api/2.8.1/scala/collection/Traversable.html

Marcus Denison

Page 3 of 37

3. Background be modied for lazy evaluation.

Marcus Denison

Functions Functions are rst-class citizens in functional programming. It is possible to pass functions as parameters to other functions, return functions from functions or nest functions into functions. Functions that take functions as parameters are so called higher-order functions. [Sub09, P. 75 f.] Currying Transforming a function that takes more than one parameter into a function that takes multiple parameter lists, is called Currying, named after Haskell Brooks Curry7 , whose rst name is also the name of the pure functional programming language Haskell8 .

3.1.2 Object-oriented Scala


Classes Classes are the blueprint for objects. Dening methods and elds, which can be used when the class is instantiated as an object. Scala holds several types of other classes, such as case classes, abstract classes and sealed classes. The dierent types of classes dier from their usage. Objects Objects refer to the singleton design pattern [FFSB04, P. 177], instead of dening it as a class the keyword object is used for direct instantiation of an object. A special object is the companion object [Bra10, P. 57], it refers to a class with the same name, thus they know each other and share their elds and methods. Traits Reusing code is a very important topic in a programming language. Traits can be used to dene methods and elds, it is possible to mix in a various number of traits into a class or an object. Also it is possible to only declare abstract methods and elds, whence they need to be dened where the trait is mixed in. Scratching on the surface of Scala was the purpose of this chapter. For a broad overview of Scala it is recommended to read at least one or more books which deal with the Scala programming language, referenced in this thesis.

7 8

http://www-history.mcs.st-and.ac.uk/history/Biographies/Curry.html http://www.haskell.org

University of Applied Sciences Schmalkalden SS 2011

Page 4 of 37

3. Background

Marcus Denison

3.2 Lift: A web framework implemented with Scala


Taking a quick glance at the Lift web framework and where it came from.

3.2.1 A brief history


On November 21st, 2006 David Pollak wrote a Web Framework Manifesto which included several criteria for a good web framework. The list with 24 criteria was said as feasibly with existing technologies, such as Rails9 , Seaside10 , Erlyweb11 , Jifty12 , Django13 and Aranea14 . After searching for a reasonable programming language, he stumbled across Scala. In 2007 the Lift web framework was born. Lift 1.0 was released on February 26, 2009. Until now David Pollak remains leader of this open source project. In the meanwhile Lift is available in the version 2.3 and 2.4 is on its way.

3.2.2 Design Goals


Three main design goals, which Lift has achieved and they are still being worked on to get better on each release there is made: Security Lift takes a great approach at helping the developer, which isnt familiar with the threats that come from the Internet. Lift provides protection against common attacks such as cross-site request forgery15 , cross-site scripting16 and SQL injection17 . Conciseness Precisely because Lift was realized with Scala, it takes advantage of Scala being very expressive with very few lines of code and thus Scala has functional programming rudiments and functional programming is more elegant [Bar11, P. 302], it is to say that producing code with Scala is more elegant than in an web framework which was realized with an imperative programming language. Performance According to Gomez18 : The average on-line shopper expects your pages to load in two or less seconds. [com09, P. 2] Lift takes this part seriously and according to Timothy Perrett 300 requests per second with only 1 GB RAM and a middle-of-the-road processor could be expected [Per10, P. 4]. Based on this, using lots more RAM and adjusting the JVM settings the performance of Lift can be tremendously fast.
http://rubyonrails.com http://seaside.st 11 http://erlyweb.org 12 http://jifty.org 13 http://www.djangoproject.com 14 http://www.araneaframework.org 15 https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) 16 https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) 17 https://www.owasp.org/index.php/SQL_Injection 18 The Web Performance Division of Compuware.
10 9

University of Applied Sciences Schmalkalden SS 2011

Page 5 of 37

3. Background

Marcus Denison

3.2.3 Goodbye MVC, Hello V-VM-M


The Model View Controller Pattern [Fow03] is the most common approach for User Interfaces by web frameworks. According to Timothy Perrett, in the design phase of Lift there was a conscious choice not to use MVC, since MVC assumes that each page has a single driving call to action; in modern applications this is no longer the case. The approach that was rst implemented in Lift was called View rst. In the Book Lift in Action [Per10] it is called V-VM-M19 .

Figure 3.1: View-ViewModel-Model An explanation what Figure 3.1, taken from Lift in Action [Per10, P. 4], means. View There are two approaches which are valid for Lifts View templates. Validated XHTML templates are the rst and the more important one, secondly, embedded XML within Scala code which is generated into a valid View. Lift forces the developer to write correct XML markup. It is not possible to put any logic within a XHTML template. ViewModel The middle piece of this pattern, also called snippet. A Scala class or object may represent a snippet, which are responsible for rendering valid HTML output. Snippets are not controllers, as known from the MVC pattern. Snippets should only be responsible for non-control ow actions. Views can call any amount of snippets. According to David Pollak, snippets are the reason why developers have to work hard to introduce cross site scripting vulnerability [Pol11, Ch. 3.4]. Model The third part is responsible for taking calls from and returning data to the ViewModel. Data from the persistence and return values from actions can be a part of this.

19

View-ViewModel-Model

University of Applied Sciences Schmalkalden SS 2011

Page 6 of 37

3. Background

Marcus Denison

3.2.4 Lifts answers to OWASP Top 10


In a discussion from the year 2009 within the Lift mailing-list, David Pollak mentioned ten answers20 to the OWASP21 Top 10 of 200722 . Table 3.1 lists these answers.

Table 3.1: Lift vs. OWASP Top 10 Web application vulnerability Lifts answer A1 - Cross Site Scripting (XSS) "Lift is resistant to XSS attacks. By default pages are composed in XML rather than Strings. It takes the developer extra work to insert XSS strings into output rather than having to make sure each String is properly escaped before being cated to the output." A2 - Injection Flaws "Lift is resistant to SQL Injection attacks because mapper and JPA do not compose Strings into SQL statements, but rather bind well typed parameters into prepared statements. So, if you go the normal path, you get SQL injection resistance. If you want to manually craft a String to send as a query, in mapper you have to sign the string with the time, date and a certication that youve reviewed the String for SQL Injection problems." "Lift never shells out. You cant cause a le to be executed from a Lift app unless your app manually uses Javas Runtime.execute() call." "By default, Lift creates opaque GUIDs to refer to components on the server side (whether thats a function to execute when a form eld is submitted, what to do on an Ajax call, etc.) By default, its easier to use this callback mechanism than advertise a primary key or other sensitive piece of information. Lift also has the KeyObfuscator which will create a session-specic mapping of primary keys to opaque ids. Using KeyObfuscator, you can send JSON objects to the client with stable primary keys that are obfuscated and not usable outside the current session."

A3 - Malicious File Execution

A4 - Insecure Direct Object Reference

http://groups.google.com/group/liftweb/browse_thread/thread/c140011a62ba3b7/ 50fb371a72949474?hl=en&lnk=gst&q=security#50fb371a72949474 21 The Open Web Application Security Project 22 https://www.owasp.org/index.php/Top_10_2007

20

University of Applied Sciences Schmalkalden SS 2011

Page 7 of 37

3. Background

Marcus Denison

Table 3.1: (continued) A5 - Cross Site Forgery (CSRF) Request "By default Lifts form elds contain GUIDs that are cryptographically impossible to predict. Its not possible to do CSRF because one does not know the name of form elds (they are not stable)."

A6 - Information Leakage and "Lift has dierent production vs. development Improper Error Handling mode error messages. Theres little information that leaks about underlying congurations, even exceptions, in production mode." A7 - Broken Authentication and Session Management "Lift uses the containers session management (usually JSESSIONID) for session management. Of course, anything thats not over SSL is vulnerable to a cookie stealing attack."

A8 - Insecure Cryptographic "Crypto key storage is a container-level issue." Storage A9 - Insecure Communications "See 7"

A10 - Failure to Restrict URL "Lifts sitemap is the best and most secure inteAccess gration of UI and page-level access. You can look at the sitemap to determine the access control rules for a given page (its declarative) and its enforced long before your page gets accessed." This chapter was an introduction into the Lift web framework, for further understandings please see Simply Lift [Pol11], Lift in Action [Per11], or Exploring Lift [DCBW11].

University of Applied Sciences Schmalkalden SS 2011

Page 8 of 37

4 Analysis of the current implementation


EmployeeWeb is based on an older project called spirit-news1 , thus it is necessary to analyse spirit-news to separate the parts which can be adopted from the parts which are not reusable. First it is discussed how the features are implemented, afterwards design failures will be reviewed.

4.1 User Management


The User Management was based on the MegaProtoUser[DCBW11, Ch. 8.2.8], although it was necessary to take advantage of the FhS2 internal LDAP3 Service, which provides access for every employee. What was not taken into consideration at that point, was that there are two dierent LDAP Servers, named ldap1 4 and ze 5 . In Listing 4.1 a part of the LDAPAuth trait6 is shown which is used to get access over an fhs-id7 . At rst the LDAP support was only integrated for one LDAP Server, after realizing the existence of more than one LDAP Server, a proper way of handling user authentication should have been implemented, but instead Listing 4.1 was the output. Explaining the three instances of trying to authenticate a user with this implementation: First an attribute is called from a conguration le, nding any additional users in that le. This was implemented because external employees do not have an ocial fhs-id. Secondly the user is matched against the ocial LDAP Server. If both options fail from above, the user is matched against ze. This was implemented because it was a more proper way instead of lling in users that dont have an fhs-id into the extra conguration le.

1 2

https://github.com/spirit-fhs/news University of Applied Sciences Schmalkalden 3 Lightweight Directory Access Protocol 4 LDAP Server across all faculties 5 LDAP Server only for the Faculty of Computer Science 6 https://github.com/spirit-fhs/news/blob/master/src/main/scala/org/unsane/ spirit/news/model/LDAPAuth.scala 7 Username based on the membership at the FhS

Marcus Denison

Page 9 of 37

4. Analysis of the current implementation Listing 4.1: LDAPAuth

Marcus Denison

def tryLogin ( userName : String , passWord : String ) : Boolean = { // allow additional users in setting . properties val additionalUsers = loadProps ( " users " ) . split ( ; ) . map { _ . trim } if ( additionalUsers contains userName ) { val userInfo = loadProps ( userName ) . split ( ; ) . map { _ . trim } if ( userInfo . length >= 3) { if ( userInfo (2) = = md5SumString ( passWord ) ) { S . setSessionAttribute ( " fullname " , userInfo (0) ) S . setSessionAttribute ( " email " , userInfo (1) ) true }}} if ( useLDAPAuth ) { tryLoginLDAP ( userName , passWord ) } else { S . setSessionAttribute ( " fullname " , userName ) S . setSessionAttribute ( " email " , " testuser @ nonvalid " ) true } } def tryLoginLDAP ( userName : String , passWord : String , ldapServer : String = " ldap1 " ) : Boolean = { val ( ldapURL , dn ) = if ( ldapServer = = " ldap1 " ) { ( " ldaps : // ldap1 . fh - schmalkalden . de : 636 " ," uid = " + userName + " ," + ( if ( userName . equals ( " denison " ) ) " ou = students , dc = fh - sm , dc = de " else " ou = people , dc = fh - sm , dc = de " ) ) } else if ( ldapServer = = " zefi " ) { ( " ldaps : // zefi . fh - schmalkalden . de : 636 " ," uid = " + userName + " , ou = people , ou = in , dc = fh - schmalkalden , dc = de " ) } else { false }}

University of Applied Sciences Schmalkalden SS 2011

Page 10 of 37

4. Analysis of the current implementation

Marcus Denison

Reviewing a part of the User object8 in Listing 4.2, demonstrates how LDAP authentication is integrated into the User life cycle within the project. In detail: The LDAPAuth trait is mixed in via with LDAPAuth The values sitemap, loginXhtml and login are overridden in order to receive proper output for the user which is viewing the login page. Within the denition of login, the tryLogin method is called and if successful the user name is logged in and a valid session is opened for the users browser. Listing 4.2: User Object object User extends User with MetaMegaProtoUser [ User ] with LDAPAuth with Config { ... override lazy val sitemap : List [ Menu ] = List ( loginMenuLoc , logoutMenuLoc ) . flatten ( a = > a ) override def loginXhtml = { ... <tr > < td style = " border : 0; colspan : 2 " > { S .??( " log . in " ) } </ td > </ tr > <tr > < td style = " border : 0 " > { S .??( " FHS - ID " ) } </ td > < td style = " border : 0 " > < user : user / > </ td > </ tr > <tr > < td style = " border : 0 " > { S .??( " password " ) } </ td > < td style = " border : 0 " > < user : password / > </ td > </ tr > <tr > < td style = " border : 0 " > < user : submit / > </ td > </ tr > ...} override def login = { if ( S . post _ ?) { ... if ( tryLogin ( S . param ( " username " ) . open _ ! , S . param ( " password " ) . open _ !) ) { User . logUserIdIn ( S . param ( " username " ) . open _ !) ... } else { } } ... }} A comparison between Figure 4.1 and 4.2 views the dierences without and with the necessary modications for employee authentication.
8

https://github.com/spirit-fhs/news/blob/master/src/main/scala/org/unsane/ spirit/news/model/User.scala

University of Applied Sciences Schmalkalden SS 2011

Page 11 of 37

4. Analysis of the current implementation

Marcus Denison

Figure 4.1: Before modication of the User object

Figure 4.2: After modication of the User object

4.2 Persistence Layer


The primary function of spirit-news is to provide information from employees for students, information that may be ltered by term, creation date or by employee. Since spirit-news was adopted in a course on functional programming, it was the idea to use a NoSQL [SEB10] database for the back end, MongoDB9 was chosen because Lift has a working Record [Per11, Ch. 11.1] implementation. Figure 4.3 displays the UML notation of the implemented Record for spirit-news. Listing 4.3 demonstrates the usage of the Entry Record implemented in the CRUDEntry class10 , fetching all news that were created by the user that was authenticated by LDAP and displaying them to the user. Figure 4.4 views the output in the users browser.
9 10

http://www.mongodb.org/ https://github.com/spirit-fhs/news/blob/master/src/main/scala/org/unsane/ spirit/news/snippet/CRUDEntry.scala

University of Applied Sciences Schmalkalden SS 2011

Page 12 of 37

4. Analysis of the current implementation

Marcus Denison

Figure 4.3: Entry Record Listing 4.3: Record Usage def viewUserEntries ( xhtml : NodeSeq ) : NodeSeq = { Entry . findAll ( " name " -> User . currentUserId . open _ !. toString ) . sortWith ( ( entry1 , entry2 ) = > ( entry1 > entry2 ) ) . flatMap ( v = > <tr > < td style = " border : 0 " >{ v . writer . value . toString } </ td > ... < td style = " border : 0 " >{ link ( " / edit / delete " , () = > CurrentEntry ( Full ( v ) ) , Text ( " Delete " ) ) } </ td > </ tr > ) }

Figure 4.4: Entries by a User As mentioned in the previous chapter user management was not part of the required persistence. User management was retrieved from the internal LDAP servers.

4.3 Security vulnerabilities


Spirit-news was implemented without any design in mind and without secure concepts for a web application, since Lift was stated as a secure web framework. Taking

University of Applied Sciences Schmalkalden SS 2011

Page 13 of 37

4. Analysis of the current implementation

Marcus Denison

three common vulnerabilities (Cross Site Scripting11 , Session Stealing12 and Injection13 ) and reviewing why they are or arent potential risks to spirit-news.

4.3.1 Session Stealing


Lift renders everything stateful by default, means that for every user a new session will be created. For as long as this user browses the entire web application, the session sticks to the users browser. Nevertheless, the server should assign the client a new session when the client uses an authentication mechanism. Figure 4.5 displays a delineation of the login process within spirit-news. A quick explanation on Figure 4.5: The client visits the starting page of the server. The server responds with a session for that client. Taking into consideration, at this point a Man in the middle attack [Hus03] could have listened to the communication and have been able to read clear text since both steps were made with a non-SSL connection. The client visits the login page, now via an SSL connection, and sends an authentication request to the server, in order to get access to restricted pages. The server responses, via an SSL connection, that the login was successful and that the session for this client is now able to see the restricted areas. The password cant be stolen at this point, since it is sent over an SSL connection. Although the created session at the beginning was sent over a non-SSL connection and was read by a Man in the middle attack. Since the session is not getting renewed by the server when authenticating the user, the stolen session can be used from any browser. Which means an unauthorized person can now act as the user that just logged in.

4.3.2 Cross Site Scripting


All pages are rendered to a user, thus it is ensured that no static HTML les were compromised on the server side. However it is necessary to guarantee that data inputted by a user will not be a threat to other users displaying that information. Despite the fact that only employees use the forms for the input of data, taking into consideration that a user account may be compromised and someone may try to input harmful data. In chapter 4.4.1 it was explained that a session might be stolen from a user. If that would be the case the following scenario might happen. Figure 4.6 is an example input of a simple script that will bring a pop up message when the page is loaded, in that case this would be an XSS14 vulnerability. Listing 4.4 is part of the imple11 12

https://www.owasp.org/index.php/Top_10_2010-A2 https://www.owasp.org/index.php/Top_10_2010-A3 13 https://www.owasp.org/index.php/Top_10_2010-A1 14 Cross Site Scripting

University of Applied Sciences Schmalkalden SS 2011

Page 14 of 37

4. Analysis of the current implementation

Marcus Denison

Figure 4.5: User Session

Figure 4.6: XSS Input mentation for the text area which the user uses for inputting data, which takes the input and stores it into the database without checking for any malicious code. Listing 4.4: Textarea code def view ( xhtml : NodeSeq ) : NodeSeq = { bind ( " CRUDView " , xhtml , ... " textarea " -> textarea ( CrudEntry . news . value . toString , CrudEntry . news . set ( _ ) , " rows " -> " 12 " , " cols " -> " 80 " , " style " -> " width : 100% " , " id " -> " entry " ) , ...) }

University of Applied Sciences Schmalkalden SS 2011

Page 15 of 37

4. Analysis of the current implementation

Marcus Denison

Listing 4.5 is the function which renders the inputted data from the database to the browser. It doesnt check for malicious code either. The Textile-Parser15 just indicates that a markup language may be used for output. On the other hand, Figure 4.7 views the data just as it was inputted. Lift escapes everything by default, so it is hard for the developer to introduce XSS vulnerabilities, as stated by David Pollak [Pol11, Ch. 3.4]. Listing 4.5: Textarea output code def view ( xhtml : NodeSeq ) : NodeSeq = { ... " news " -> TextileParser . toHtml ( entry . news . value . toString ) ) ) ...}

Figure 4.7: XSS Output

4.3.3 SQL Injection


In the previous chapters 4.4.1 and 4.4.2, two vulnerabilities were evaluated where an SSL connection from the beginning would have been sucient enough to disallow the Man in the middle attack. Whereas SQL Injection, can be done with either nonSSL or an SSL connection. This is where the developer needs to be aware of what programmcode he is producing. As it is stated on the MongoDB website, the only risk there could be using MongoDB is using server side JavaScript16 , which is not a part of spirit-news. Also the Record implementation is binding typed parameters into prepared statements, thus it makes it even more reliable to be secure.

4.4 Design failures


As mentioned in the beginning of chapter 4, the results of the analysis will be evaluated here. User management has three points of authentication and depends on two LDAP servers17 . The option for extra users in a conguration le is obsolete and should have been removed when introducing ze into the authentication mechanism. If there is a new option introduced for user authentication at the FhS, it can be a painful task to implement this into spirit-news since someone would have
15 16

A HTML Markup language. http://www.mongodb.org/display/DOCS/Do+I+Have+to+Worry+About+SQL+Injection 17 See Chapter 4 for the three points of authentication and two LDAP servers.

University of Applied Sciences Schmalkalden SS 2011

Page 16 of 37

4. Analysis of the current implementation to understand the whole code base to adopt a new mechanism.

Marcus Denison

Reviewing Figure 4.3 every eld of an Entry was implemented as a StringField, that means the attributes semester, date, lifecycle and nr could not be obvious to other developers. Creating new features using the Entry record for spirit-news could cause tremendous problems for a developer, since type-safety18 is not given for those attributes at any point. The same occurs with the attribute nr which is used as a sort of primary key, while the primary key should be handled by the database and not by business logic within the program code. Reviewing Listing 4.6 and 4.7 which are parts of the snippet that creates the view for inputting news, both methods are controlling the usage of the nr attribute. Recalling that this attribute is used as the primary key for entries and should be handled by the persistence layer and not by the snippets which are actually only used by rendering output to the users browser. Another part is that both methods make usage of the possibility to send the created entry as an email or tweeting19 it on twitter20 . Listing 4.6: Update method def update () { val oldNr = CrudEntry . nr . value val newNr = if ( tweetUpdate ) if ( EntryCounter . findAll . isEmpty ) " 1 " else EntryCounter . findAll . head . counter . toString else oldNr ... if ( newNr ! = oldNr ) { val count = if ( EntryCounter . findAll . isEmpty ) EntryCounter . createRecord else EntryCounter . findAll . head count . counter . set ( ( newNr . toInt + 1) . toString ) count . save } if ( sendEmail ) MailHandler . send ( TextileParser . toHtml ( CrudEntry . news . value ) . toString , " [ Update ] " + CrudEntry . subject . value , loadEmails ( changedSemester split ( " " ) ) ) if ( tweet && tweetUpdate )
18 19

Giving assurance that objects are always compatible with each other. Posting on twitter.com is called tweeting. 20 http://www.twitter.com

University of Applied Sciences Schmalkalden SS 2011

Page 17 of 37

4. Analysis of the current implementation

Marcus Denison

Spreader ! Tweet ( " [ Update ] " + CrudEntry . subject . value , changedSemester . split ( " " ) . map ( " # " + _ ) . mkString , newNr ) } Listing 4.7: Create method def create () { lazy val nr = if ( EntryCounter . findAll . isEmpty ) " 1 " else EntryCounter . findAll . head . counter . toString ... val count = if ( EntryCounter . findAll . isEmpty ) EntryCounter . createRecord else EntryCounter . findAll . head count . counter . set ( ( nr . toInt + 1) . toString ) count . save if ( sendEmail && changedSemester . nonEmpty ) { MailHandler . send ( TextileParser . toHtml ( CrudEntry . news . value . toString ) . toString , CrudEntry . subject . value , loadEmails ( changedSemester . split ( " " ) ) ) } if ( tweet ) { Spreader ! Tweet ( CrudEntry . subject . value , changedSemester . split ( " " ) . map ( " # " + _ ) . mkString , nr ) } } The security issue regarding session stealing, was known prior to Lift version 2.2 and was xed during the development of the 2.2 release21 . But other than relying on the framework in all terms, it was also a failure in the server side conguration. Putting it all together, spirit-news was implemented without any knowledge on persistence layers, security nor where to properly put business logic within the code base. It is necessary to re-think the implementation of the user management, redesign the persistence UML and clearly put business logic where it belongs.

21

https://www.assembla.com/spaces/liftweb/tickets/727-create-new-http-sessionon-login

University of Applied Sciences Schmalkalden SS 2011

Page 18 of 37

5 A new implementation from scratch


"Leave the campground cleaner than you found it." This boy scout rule was applied to the programming profession in a book on clean coding [Mar09]. Due to this fact, it is necessary to re-factor the messy campground that was evaluated in chapter 4.

5.1 Authentication Module


Instead of creating a new user management within EmployeeWeb, an authentication module based on the ideas of a Lift module1 was implemented. The module was designed to work for any Lift project which needs to have authentication at the FhS via employee or students fhs-id. Also a clean API for other developers was a goal. Based on the failures evaluated in chapter 4 and the ideas mentioned here, the FhSLDAP-Module2 was created. The module is authenticating users only against ze, which holds all FhS members and external employees of the Faculty of Computer Science. Taking a look at Figure 5.1 and 5.2 both LDAP servers are still used, since specic attributes are only found on ldap1 and others only on ze. However the API was created to be clear to the developer using it and having a set of methods and an object with all attributes needed from an FhS member, which was implemented successfully. Listing 5.1 is a part of the EmployeeWeb bootstrap which demonstrates the easy usage of the module. After initialisation the API is ready for usage. Listing 5.1: FhS LDAP Module Init package bootstrap . liftweb ... import de . codecarving . fhsldap . fhsldap ... class Boot ... { def boot { ... // Starting the FhS LDAP Module fhsldap . init ...} }

1 2

https://www.assembla.com/spaces/liftweb/wiki/Modules https://github.com/mdenison/FhS-LDAP-Module

Marcus Denison

Page 19 of 37

5. A new implementation from scratch

Marcus Denison

Figure 5.1: FhS-LDAP-Module API

Figure 5.2: FhS-LDAP Module API LDAP Attributes

University of Applied Sciences Schmalkalden SS 2011

Page 20 of 37

5. A new implementation from scratch

Marcus Denison

5.2 SpiritRecord based on the Active Record Pattern


With the exception of the type occupancy, the persistence layer of spirit-news is reusable in some ways. Comparing Figure 4.3 with the re-factored Figure 5.3 only small adjustments were done. The Entry can be reused, but it was unclear at the starting point of EmployeeWeb which database will be used as a back end, so only the database schema is really reusable. One of the requirements was to adopt a persistence layer, which can be used for any database as a back end. Reviewing the Active Record Pattern [Fow03, P. 160] and the Data Mapper, [Fow03, P. 165] both dened by Martin Fowler, it was clear to use the Active Record Pattern, since the Lift web framework has a bare bone Record3 which can be easily adopted into new implementations.

Figure 5.3: Re-factored Entry Record Figure 5.4 explains the path of creating an instance of a type which has inherited from the SpiritRecord. Listing 5.2 shows an example which denes methods for a SpiritRecord, pattern matching [OSV10] against which database as back end shall be used and for what kind of SpiritRecord the methods are needed. Reviewing the SpiritMetaRecord trait in Figure 5.4, it is clear that the MethodFactory is given the parameter this, thus the MethodFactory returns the appropriate object of methods for the type which was created, in the example case for an SpiritEntry.

Listing 5.2: Method factory object MethodFactory { def apply [ T <: SpiritRecord [ T ]]( in : T ) : SpiritMethods [ T ] = ( db , in ) match { case ( this . rest , in : SpiritEntry ) = > new persistence . rest . SpiritEntryMethods [ T ] case ( this . h2db , in : SpiritEntry ) = > new persistence . h2 . SpiritEntryMethods [ T ]
3

Found in the package net.liftweb.record .

University of Applied Sciences Schmalkalden SS 2011

Page 21 of 37

5. A new implementation from scratch ... }

Marcus Denison

lazy val db = Props . get ( " spirit . admin . record . backentry " ) . openOr (( " " )) lazy val h2db = " h2db " // Usage for H2 Database lazy val rest = " rest " // Usage for RESTful DB Service } Every SpiritRecord, which is created needs to implement the methods dened in the SpiritMethods trait4 in order to work awlessly, therefore the verbosity may increase to an tremendously unreadable code chaos. That is the reason why the MethodFactory was implemented. Once a SpiritRecord is implemented and a decision for a dierent database may come up, that specic SpiritRecord does not have to be changed, merely the classes which are instanced by the MethodFactory have to be adjusted. This chapter described the implementation of SpiritRecord, which

Figure 5.4: SpiritRecord UML allows the code to be cleaner than it was within spirit-news. The next chapter is going to explain, how the SpiritRecord helps having a cleaner design.

See Figure 5.4.

University of Applied Sciences Schmalkalden SS 2011

Page 22 of 37

5. A new implementation from scratch

Marcus Denison

5.3 A cleaner design


"A programmer without code-sense can look at a messy module and recognize the mess but will have no idea what to do about it. A programmer with code-sense will look at a messy module and see options and variations. The code-sense will help that programmer choose the best variation and guide him or her to plot a sequence of behavior preserving transformations to get from here to there." [Mar09, P. 7] The denition of a clean code base can vary from developer to developer, this chapter is to view an example of how a cleaner design was achieved by re-factoring. In chapter 4.5, it was already mentioned that there were horrible design failures. Such as Listing 4.6 and 4.7. Listing 5.3 is the re-factored snippet for creating, updating news and also responsible for rendering the forms for the users browser. Business logic was removed from all snippets in order to achieve a cleaner design. It was a great impact using the Active Record Pattern, since business logic can be a part of a Record [Fow03, P. 161]. Having already bare bone methods from the Lift-record which may be executed before or after any action that is going to take place when interacting with the implemented back end is also a feature which is very helpful, which can be seen in Listing 5.4. Listing 5.3: Refactored snippet for writing news def render = { def process () : JsCmd = { openEntry . semester . setFromDirtyList ( semesterList . toList ) openEntry . save ( openEntry . newEntry . value ) S . redirectTo ( " / news / news " ) } " name = twitterBool " # > openEntry . twitterBool . toForm . map { x = > x } & " name = emailBool " #> openEntry . emailBool . toForm . map { x = > x } & " name = displayName " # > openEntry . displayName . toForm . map { x = > x } & " name = subject " #> openEntry . subject . toForm . map { x = > x } & " name = news " #> openEntry . news . toForm . map { x = > x } & " name = expires " #> ( openEntry . expires . toForm . map { x = > x } ++ SHtml . hidden ( process ) ) & " type = preview " #> createPreviewButton &

University of Applied Sciences Schmalkalden SS 2011

Page 23 of 37

5. A new implementation from scratch " name = tooltip " #> createTextileTooltip }

Marcus Denison

Listing 5.4: Validating that the subject is never empty object subject extends StringField ( this , 100) with LifecycleCallbacks { override def beforeSave () { if ( this . value . isEmpty ) { this . set ( news . value ./ : (( " " , 20) ) { ( output , input ) = > if ( output . _ 2 = = 0) output else ( output . _ 1 + input , output . _ 2 - 1) }. _ 1 + " ... " ) } } }

5.4 DRY - Dont repeat yourself


DRY is a programming principle [HT99] which denes reducing code by reusing the same code over and over. If business logic needs to change, then this change will aect every program piece which uses the dened code and doesnt have to be applied to all pieces of business logic. The idea was to create a piece of code, which allows the developer to reuse it for any SpiritRecord in order to create a link for deletion in the back end with a conrmation dialog. Listing 5.5 can be mixed in any snippet where a link for deleting a SpiritRecord is necessary. If a user wishes to delete an Entry, the browser will be blocked by a dialog, asking for conrmation or truncation. Listing 5.5: Block UI trait trait blockUI extends GlobalRequests { object reloadAfterDelete extends RequestVar [ String ]( " / index " ) def deleteLink [ T <: SpiritRecord [ T ]]( in : T ) : Elem = { SHtml . a (() = > { CurrentSpiritRecord ( Full ( in ) ) ; S . runTemplate ( List ( " _ delete _ template " ) ) . map ( ns = > ModalDialog ( ns ) ) openOr Alert ( " Couldn t find _ delete _ template " ) } , Text ( " Loeschen " ) )

University of Applied Sciences Schmalkalden SS 2011

Page 24 of 37

5. A new implementation from scratch }

Marcus Denison

def confirmdelete ( in : NodeSeq ) = { ( " name = yes " # > (( b : NodeSeq ) = > ajaxButton (b , () = > { CurrentSpiritRecord . open _ !. delete _ ! Unblock & RedirectTo ( reloadAfterDelete ) }) ) & " name = no " # > (( b : NodeSeq ) = > < button onclick = { Unblock . toJsCmd } >{ b } </ button >) ) ( in ) } } This is an example of the DRY principle, since it can be used by any SpiritRecord without modication and if another style of dialog is needed it is only to be changed within the blockUI trait and nowhere else.

University of Applied Sciences Schmalkalden SS 2011

Page 25 of 37

6 Integration into the spirit@fhs ecosystem


During the implementation of spirit-news, the idea came up to create a bigger project which would provide the possibility to create applications around an eco-system, in order to be used by students and employees. Project SPIRIT was created and it stands for Service Point Information READ IT 1 . This chapter describes what other projects are important for EmployeeWeb and how they interact with each other. EmployeeWeb is still actively developed, the work described in this chapter is a so called Work in Progress.

6.1 SPIRIT
Figure 6.1 is a basic structure of most projects worked on at the present moment and how they communicate. Data - Is a RESTful DB-Service which provides the persistence for the complete ecosystem. StudWeb - The front end for Students, where it is possible to read news, submit comments and dene their schedule for the current semester. Mobile - Mobile applications which can be used to interact with the complete ecosystem, based on Android, Windows Mobile and the iPhone platform. Migrate - Dening an interface between the old schedule and the sub-project data is the goal of the Migrate project. LibSpirit - Providing access to the RESTful DB-Service through a C Library, which can be used in class to create small pieces of software by students in order to achieve a greater learning eect. EmployeeWeb & PlanningWeb - Both projects shall interact as the front end for employees, EmployeeWeb is part of this thesis and PlanningWeb provides support for time scheduling. For a more complete and comprehensible list of projects and a more detailed explanation, please see the spirit@fhs projects website2 .
1

The project name came up on a Wednesday afternoon when Oliver Braun and the Author were brainstorming. 2 http://pads.fh-schmalkalden.de/spirit.html

Marcus Denison

Page 26 of 37

6. Integration into the spirit@fhs ecosystem

Marcus Denison

Figure 6.1: The spirit@fhs ecosystem

University of Applied Sciences Schmalkalden SS 2011

Page 27 of 37

6. Integration into the spirit@fhs ecosystem

Marcus Denison

6.2 StudWeb
After introducing the spirit@fhs ecosystem, the communication between two projects which are more important to EmployeeWeb are to be reviewed, one of them is StudWeb. All communication between StudWeb and EmployeeWeb is happening through the DB-Service. Basically an agreement had to be found which denes the data, whichever needs to be transferred between the two projects. The second agreement was for a markup-language, the textile markup language3 was chosen, since the Lift web framework has superior support with a textile plug in.

6.3 RESTful DB-Service


The second project which is most important for EmployeeWeb is the RESTful DBService. With a dened specication it is possible to interact with this service via a REST interface. The REST interface returns everything via the JSON format4 , thus it was the decision to use the support of the powerful lift-json5 library. In order to strengthen the decision for lift-json, an example integration for fetching news from the REST service will be evaluated. Explaining listing 6.1: Dening that the request shall return the data in the JSON format. The request is dened to only fetch the data for the logged in user. The request and the option for JSON are concatenated. The returned JSON value is extracted into the case class which is dened at the bottom of listing 6.1. The newsList is transformed into a List[SpiritEntry]. If any changes occur within the REST service, only the case class and the mapping would having the need of adjustment. The actual SpiritEntry Record does not have to be touched. Listing 6.1: Fetching data from the RESTful DB-Service def findAll () : List [ T ] = { val asJson = Map ( " Accept " -> " application / json " ) . toMap val req = new Request ( restURL + " news ? owner = " + User . currentUserId . open _ !)
3 4

http://textile.thresholdstate.com/ JavaScript Object Notation. 5 Even if the library is a part of the Lift web framework, it may be used by any Scala project without having dependencies on Lift.

University of Applied Sciences Schmalkalden SS 2011

Page 28 of 37

6. Integration into the spirit@fhs ecosystem val rawJson = h ( req <: < asJson as _ str ) val newsList = for { i <- ( parse ( rawJson ) \ " news " ) . children } yield i . extract [ news ]

Marcus Denison

newsList map { nl = > val newSE = SpiritEntry . createRecord newSE . id . set ( nl . news _ id ) newSE . subject . set ( nl . title ) newSE . news . set ( nl . content ) newSE . displayName . set ( nl . owner . displayedName ) newSE . crdate . set ( nl . creationDate ) newSE . semester . set ( nl . degreeClass . map ( _ . title ) ) newSE . asInstanceOf [ T ] } } case class news ( news _ id : Int , title : String , content : String , owner : owner , creationDate : String , degreeClass : List [ degreeClass ]) Listing 6.2 is a rudimentary implementation of the save(inst: T) method of the SpiritEntry. Which uses the :-* method, dened in the SpiritEntry, to get a valid JSON string from a created SpiritRecord in order to send it to the RESTful DBService. Listing 6.2: Saving data to the RESTful DB-Service def save ( inst : T ) : Boolean = { val in = inst . asInstanceOf [ SpiritEntry ] val asJson = Map ( " Accept " -> " application / json " , " Content - Type " -> " application / json " ) . toMap val req = new Request ( restURL + " news " ) <<< in . : -* val answer = h ( req <: < asJson as _ str ) true }

University of Applied Sciences Schmalkalden SS 2011

Page 29 of 37

6. Integration into the spirit@fhs ecosystem

Marcus Denison

6.4 Merging with PlanningWeb


PlanningWeb and EmployeeWeb were planned to be the front end for employees as mentioned before in this chapter. Both are developed with Scala and the Lift web framework, therefore integrating both into one single project should not be a big problem. Table 6.1 compares both, to achieve an overview what parts of both projects might be a blocker in order to disallow a merge. Theoretically, based on Table 6.1: EmployeeWeb vs. PlanningWeb EmployeeWeb PlanningWeb Persistence SpiritRecord MongoRecord User management Lift Version FhS-LDAP-Module 2.3 FhS-LDAP-Module 2.3

the comparison, the only dierence is the persistence layer. It would be necessary to evaluate the behaviour of the Lift web framework when dening more than one persistence layer within the bootstrap. Chapter 6 described the easiness of integration into the spirit@fhs ecosystem, thanks to the thoughtful integration of the Active Record Pattern which was evaluated in chapter 5. Merging PlanningWeb with EmployeeWeb into one project was not achieved. In chapter 7 next steps and future work on the integration are going to be specied.

University of Applied Sciences Schmalkalden SS 2011

Page 30 of 37

7 Conclusion and Future work


Stated in chapter 2, the main goal was to achieve a better understanding of the Lift web framework. The main goal was achieved by implementing a User module, the SpiritRecord and achieving the knowledge in order to create a cleaner code base. The new design was completely developed for this project and up to this point it is ecient enough to be developed further in the future. A complete integration into the spirit@fhs ecosystem was not achieved, due to lack of time. At last, reecting a list of what future work might and should be done with EmployeeWeb. Integration into the spirit@fhs - It is still necessary to implement a working bridge between EmployeeWeb and the RESTful DB-Service. The essentials were developed during this thesis, building on top of these would be an optimal option for a working solution. Merging into PlanningWeb - Creating one project out of EmployeeWeb and PlanningWeb should be done, otherwise the users of EmployeeWeb and PlanningWeb are distracted always having to log into two dierent systems. It would be welcomed for user experience to have both projects in one front end. Upgrading to Lift 2.4 - Lift 2.4 is on its way and holds many bug xes and enhancements, one of them is ticket NR. 10611 . This would make the integration of PlanningWeb into EmployeeWeb a lot easier. Design & Usability - User experience is an important role in web applications, EmployeeWeb is in need of a design which ts the FhS and a better usability when a user uses the application.

https://www.assembla.com/spaces/liftweb/tickets/1061-allow-snippet-resolutionfor-subpackages

Marcus Denison

Page 31 of 37

Bibliography
[Bar11] Barski, Conrad: Land of Lisp. no starch press, 2011 [Bra10] Braun, Oliver: Scala Objektfunktionale Programmierung. Hanser Verlag, 2010 Carl

[com09] compurware, Gomez The Web Performance D.: Why Web Performance Matters. Whitepaper, 2009. Available online at www. gomez.com/pdfs/wp_why_web_performance_matters.pdf, visited on June 4th 2011. [DCBW11] Derek Chen-Becker, Marius D. ; Weir, Tyler: Exploring Lift: Lift 2.0 Edition. http://exploring.liftweb.net, 2011. Available online at http://exploring.liftweb.net, visited on June 4th 2011 [FFSB04] Freeman, Eric ; Freeman, Elisabeth ; Sierra, Kathy ; Bates, Bert: Head First Design Patterns. OReilly, 2004 [Fow03] Fowler, Martin: Patterns of Enterprise Application Architecture. Addison Wesley, 2003 [HT99] Hunt, Andrew ; Thomas, David: The Pragmatic Programmer. Addison Wesley, 1999 [Hus03] Huseby, Sverre H.: Innocent Code: A Security Wake-Up Call for Web Programmers. John Wiley and Sons, 2003 [Mar09] Martin, Robert C.: Clean Code: A Handbook of Agile Softare Craftsmanship. Prentice Hall, 2009 [Mey00] Meyer, Bertrand: Object-Oriented Software Construction. Prentice Hall, 2000 [OSV10] Odersky, Martin ; Spoon, Lex ; Venners, Bill: Programming in Scala 2nd Edition. artima, 2010 [Per10] Perrett, Timothy: Introducing Lift from Lift in Action. Greenpaper, 2010. Available online at http://www.manning.com/perrett/; visited on June 3rd 2011. [Per11] Perrett, Timothy: Lift in Action: The simply functional web framework for Scala. 2011. Available online at http://www.manning.com/ perrett/, visited on June 3rd 2011.

Marcus Denison

Page 32 of 37

Bibliography

Marcus Denison

[Pol11] Pollak, David: Simply Lift. Website, 2011. Available online at http://simply.lift.net; visited on June 3rd 2011. [SEB10] Stefan Edlich, Jens H. Achim Friedland F. Achim Friedland ; Brauer, Benjamin: NoSQL: Einstieg in die Welt nichtrelationaler Web 2.0 Datenbanken. Hanser, 2010 [Sub09] Subramaniam, Venkat: Programming Scala: Tackle Multicore Complexity on the Java Virtual Machine. Pragmatic Programmers, 2009

University of Applied Sciences Schmalkalden SS 2011

Page 33 of 37

List of Figures
3.1 4.1 4.2 4.3 4.4 4.5 4.6 4.7 5.1 5.2 5.3 5.4 6.1 View-ViewModel-Model . . . . . . . . . . . . . . . . . . . . . . . . . Before modication of the User object After modication of the User object . Entry Record . . . . . . . . . . . . . . Entries by a User . . . . . . . . . . . . User Session . . . . . . . . . . . . . . . XSS Input . . . . . . . . . . . . . . . . XSS Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 12 12 13 13 15 15 16 20 20 21 22

FhS-LDAP-Module API . . . . . . . . . . FhS-LDAP Module API LDAP Attributes Re-factored Entry Record . . . . . . . . . SpiritRecord UML . . . . . . . . . . . . .

The spirit@fhs ecosystem . . . . . . . . . . . . . . . . . . . . . . . . . 27

Marcus Denison

Page 34 of 37

List of Tables
3.1 6.1 Lift vs. OWASP Top 10 . . . . . . . . . . . . . . . . . . . . . . . . . 7 EmployeeWeb vs. PlanningWeb . . . . . . . . . . . . . . . . . . . . . 30

Marcus Denison

Page 35 of 37

Listings
4.1 4.2 4.3 4.4 4.5 4.6 4.7 5.1 5.2 5.3 5.4 5.5 6.1 6.2 LDAPAuth . . User Object . . Record Usage . Textarea code . Textarea output Update method Create method . . . . . . . . . . . . code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 11 12 15 16 17 18 19 21 23 24 24

FhS LDAP Module Init . . . . . . . . . . Method factory . . . . . . . . . . . . . . . Refactored snippet for writing news . . . . Validating that the subject is never empty Block UI trait . . . . . . . . . . . . . . . .

Fetching data from the RESTful DB-Service . . . . . . . . . . . . . . 28 Saving data to the RESTful DB-Service . . . . . . . . . . . . . . . . 29

Marcus Denison

Page 36 of 37

Statutory declaration
I declare that I have authored this thesis independently, that I have not used other than the declared sources / resources, and that I have explicitly marked all material which has been quoted either literally or by content from the used sources.

Schmalkalden, 09-01-2011

Marcus Denison

Marcus Denison

Page 37 of 37

Vous aimerez peut-être aussi