You are on page 1of 194

Security Analysis of University Databases/Services

Suthee Kitcharoenkarnkul

Master of Science in Internet Systems and Security


The University of Bath
September 2015
This dissertation may be made available for consultation within the Uni-
versity Library and may be photocopied or lent to other libraries for the
purposes of consultation.

Signed:
Security Analysis of University
Databases/Services

Submitted by: Suthee Kitcharoenkarnkul


for the degree of MSc
of the University of Bath

COPYRIGHT
Attention is drawn to the fact that copyright of this dissertation rests with its author. The
Intellectual Property Rights of the products produced as part of the project belong to the
author unless otherwise specified below, in accordance with the University of Bath’s policy
on intellectual property (see http://www.bath.ac.uk/ordinances/22.pdf).
This copy of the dissertation has been supplied on condition that anyone who consults it
is understood to recognise that its copyright rests with its author and that no quotation
from the dissertation and no information derived from it may be published without the
prior written consent of the author.

Declaration
This dissertation is submitted to the University of Bath in accordance with the requirements
of the degree of Bachelor of Science in the Department of Computer Science. No portion of
the work in this dissertation has been submitted in support of an application for any other
degree or qualification of this or any other university or institution of learning. Except
where specifically acknowledged, it is the work of the author.

Signed:
Abstract

SQL injection is regarded as the most dangerous and famous hacking technique against
web applications and database systems [34]. An attacker can use this technique to exploit
web application vulnerabilities in order to manipulate data in database systems, leading
to theft, modification, or destruction of sensitive information. The University of Bath
provides many online services, for example, the Moodle e-learning system. Nevertheless,
there is no SQL injection vulnerabilities assessment officially performed. This research
gives an opportunity to scan and analyze the security of the university online services and
databases, especially SQL injection vulnerabilities. In addition, it proposes a new concept
to prevent SQL injection attacks. There are many pieces of research about SQL injection
prevention, but most of them require application code modification or are deployed in the
middle between a web server and a database server. These conditions lead to an inability to
implement in some environments. Therefore, ReppSi, an SQL injection prevention system
in this research, is designed to be deployed in front of the web server as a reverse proxy and
does not need to modify the application code. An approach used to detect SQL injection
attacks based on the behavior-based detection. The operation is divided into two phases, a
learning phase and a protection phase. In the learning phase, the behaviour-based detection
system collects the characteristics of using the web application. Then, in the protection
phase, it creates profiles as security rules to detect unauthorized (anomalous) web usage,
for example, an SQL injection attack hidden inside the HTTP request. The results of the
experiments show that ReppSi could detect 100 percent of SQL injection attacks with only
one false positive, but it could block the attacks only 92 percent due to the limitation of
the program. Additionally, the average process time of the ReppSi system is less than 5
milliseconds that are very low compared to the average response time of the direct request
without the ReppSi deployment.
Contents

1 Introduction 1

1.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.3 Statement of Purposes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.4 Scope of Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 The University Background 7

3 SQL Injection Attacks 9

3.1 Overview of SQL Injection Attacks . . . . . . . . . . . . . . . . . . . . . . . 9

3.2 Types of SQL Injection Attacks . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.1 Tautologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.2 Illegal/Logically Incorrect Queries . . . . . . . . . . . . . . . . . . . 10

3.2.3 Union Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.4 Piggy-backed Queries . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2.5 Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2.6 Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.2.7 Alternate Encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.3 Impacts of SQL Injection Attacks . . . . . . . . . . . . . . . . . . . . . . . . 13

ii
CONTENTS iii

4 Literature Reviews 14

4.1 Static Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.1.1 An Analysis Framework for Security in Web Applications [47] . . . . 15

4.2 Dynamic Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.2.1 SQLrand: Preventing SQL Injection Attacks [3] . . . . . . . . . . . . 16

4.2.2 Using Positive Tainting and Syntax-Aware Evaluation to Counter


SQL Injection Attacks [13] . . . . . . . . . . . . . . . . . . . . . . . 17

4.3 Model-based Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.3.1 AMNESIA Analysis and Monitoring for NEutralizing SQL-Injection


Attacks [12] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.3.2 Using Parse Tree Validation to Prevent SQL Injection Attacks [4] . . 18

4.3.3 The Essence of Command Injection Attacks in Web [41] . . . . . . . 19

4.3.4 SQL-IDS: A Specification-based Approach for SQL-Injection Detec-


tion [20] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.4 Anomaly-based Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.4.1 A Learning-Based Approach to the Detection of SQL Attacks [45] . 21

4.4.2 CANDID: Preventing SQL Injection Attacks using Dynamic Candi-


date Evaluations [2] . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5 The University’s Service Assessment 23

5.1 Assessment Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.1.1 Assessment Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.1.2 Vulnerability Scanning Tools . . . . . . . . . . . . . . . . . . . . . . 24

5.2 Results and Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5.2.1 Using OWASP ZAP . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5.2.2 Using Subgraph Vega . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
CONTENTS iv

6 Design 36

6.1 Design’s Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

6.2 System Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

6.3 System Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6.3.1 Listener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6.3.2 Session Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6.3.3 Suspicious Input Detection Engine . . . . . . . . . . . . . . . . . . . 40

6.3.4 Profile Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

6.3.5 Logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

6.3.6 Sender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

6.4 System Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

6.4.1 Database and Proxy Preparation . . . . . . . . . . . . . . . . . . . . 41

6.4.2 Learning Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

6.4.3 Protection Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

6.5 Database System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

6.5.1 Log Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6.5.2 Profile Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6.6 Logging System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6.7 Error Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6.8 False Positives and False Negative Handling . . . . . . . . . . . . . . . . . . 50

7 Implementation 51

7.1 Necessary Tools for Implementation . . . . . . . . . . . . . . . . . . . . . . 51

7.1.1 Java Programming Language . . . . . . . . . . . . . . . . . . . . . . 51

7.1.2 Membrane Service Proxy . . . . . . . . . . . . . . . . . . . . . . . . 51

7.1.3 MySQL Database Management System . . . . . . . . . . . . . . . . 52

7.1.4 Laptop for running ReppSi . . . . . . . . . . . . . . . . . . . . . . . 52


CONTENTS v

7.2 Listener, Sender, and Session Manager Modules . . . . . . . . . . . . . . . . 53

7.2.1 Proxy Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

7.2.2 HTTP Request Handling . . . . . . . . . . . . . . . . . . . . . . . . 55

7.2.3 HTTP Response Handling . . . . . . . . . . . . . . . . . . . . . . . . 56

7.3 Suspicious Input Detection Engine . . . . . . . . . . . . . . . . . . . . . . . 57

7.3.1 Database Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . 57

7.3.2 Request Logging and Profile Updating . . . . . . . . . . . . . . . . . 58

7.3.3 Suspicious Input Detection . . . . . . . . . . . . . . . . . . . . . . . 64

7.4 Profile Database Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

7.5 Logger Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

7.6 Classes and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

8 Experiments 74

8.1 Protection Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

8.1.1 Experimental Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

8.1.2 Preparation before Testing . . . . . . . . . . . . . . . . . . . . . . . 75

8.1.3 Vulnerability Scanning Tools . . . . . . . . . . . . . . . . . . . . . . 77

8.1.4 Results and Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

8.2 Performance Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

8.2.1 Experimental Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

8.2.2 Results and Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

8.3 False Positive Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

8.4 summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

9 Limitations and Future Work 93

9.1 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

9.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94


CONTENTS vi

10 Conclusion 96

A Installation Guide 105

A.1 MySQL Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

A.2 ReppSi Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

B User Manual 109

B.1 Running the ReppSi System . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

B.2 MySQL Database Management . . . . . . . . . . . . . . . . . . . . . . . . . 110

B.3 Viewing the Log File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

C Raw Results Output 113

C.1 The Moodle E-learning System Vulnerability Scanning by OWASP ZAP . . 113

C.2 The Moodle E-learning System Vulnerability Scanning by Subgraph Vega . 126

C.3 The Profile Table of the Super Veda Application . . . . . . . . . . . . . . . 144

C.4 Example of the Log File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

C.5 The SQL injection alerts of the Super Veda application Scanned by OWASP
ZAP (Before) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

C.5.1 SQL Injection - Authentication Bypass . . . . . . . . . . . . . . . . . 147

C.5.2 SQL Injection - MySQL . . . . . . . . . . . . . . . . . . . . . . . . . 148

C.6 The SQL injection alerts of the Super Veda application Scanned by Subgraph
Vega (Before) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

C.6.1 MySQL Error Detected - Possible SQL Injection . . . . . . . . . . . 149

C.6.2 SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

D Source Code 156

D.1 ReverseProxy.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

D.2 TrafficInterceptor.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

D.3 SuspiciousInputDetectionEngine.java . . . . . . . . . . . . . . . . . . . . . . 161


CONTENTS vii

D.4 TxtLogger.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

D.5 TxtLogFormatter.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176


List of Figures

4.1 High-level overview of AMNESIA [12] . . . . . . . . . . . . . . . . . . . . . 18

4.2 An example of the parse trees before and after the inclusion of the user-
supplied input [4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4.3 The architecture of SQL-IDS [20] . . . . . . . . . . . . . . . . . . . . . . . . 20

4.4 The deployment of the systems installed between the web server and the
database server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1 A network diagram for the assessment setup . . . . . . . . . . . . . . . . . . 24

5.2 Comparison between the web page and its source code . . . . . . . . . . . . 30

5.3 Two different error pages generated by the Moodle . . . . . . . . . . . . . . 32

6.1 An overview of the ReppSi system designed in this research . . . . . . . . . 38

6.2 The architecture of the ReppSi sytem . . . . . . . . . . . . . . . . . . . . . 39

6.3 The process of database and proxy preparation . . . . . . . . . . . . . . . . 42

6.4 The process of the learning phase . . . . . . . . . . . . . . . . . . . . . . . . 44

6.5 The process of the protection phase . . . . . . . . . . . . . . . . . . . . . . . 46

6.6 An error page generated by ReppSi . . . . . . . . . . . . . . . . . . . . . . . 49

7.1 A comparison between the modules in ReppSi and the tools for implementation 53

7.2 An example of using the Membrane Service Proxy . . . . . . . . . . . . . . 54

7.3 Flowchart of the profile updating . . . . . . . . . . . . . . . . . . . . . . . . 61

7.4 A flowchart of the suspicious input detection 1 . . . . . . . . . . . . . . . . 65

viii
LIST OF FIGURES ix

7.5 A flowchart of the suspicious input detection 2 . . . . . . . . . . . . . . . . 66

7.6 The log table of researchtest.com . . . . . . . . . . . . . . . . . . . . . . . . 69

7.7 The profile table of researchtest.com . . . . . . . . . . . . . . . . . . . . . . 69

7.8 The user interface of the phpMyAdmin . . . . . . . . . . . . . . . . . . . . . 70

7.9 An example of the system event logs and the alert logs . . . . . . . . . . . . 70

8.1 The network diagram of the protection test . . . . . . . . . . . . . . . . . . 75

8.2 An example of the log table after logging HTTP requests . . . . . . . . . . 76

8.3 An example of the profile table that digested the data from the log table . . 76

8.4 Bypassing the authentication system using SQL injection . . . . . . . . . . 77

8.5 The result of bypassing the authentication system using SQL injection . . . 78

8.6 The error page generated by ReppSi . . . . . . . . . . . . . . . . . . . . . . 78

8.7 The alert from the log file (See more details of the log file in Appendix C.4) 79

8.8 A comparison between the OWASP ZAP’s log and the ReppSi’s log for
/dosearch.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

8.9 A comparison between the OWASP ZAP’s log and the ReppSi’s log for
/register.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

8.10 A comparison between the SQL exception and the source code . . . . . . . 82

8.11 The source code of handling the HTTP request/response . . . . . . . . . . . 87

8.12 The response time of browsing the Moodle service from London [48] . . . . 88

8.13 The false positive alerts generated by ReppSi . . . . . . . . . . . . . . . . . 89

8.14 The /register.jsp page that caused the false positives . . . . . . . . . . . . . 90

8.15 The profile records that caused the false positives . . . . . . . . . . . . . . . 91

8.16 The SQL command for updating the profile records . . . . . . . . . . . . . . 91

A.1 The library files of the Membrane Proxy Service . . . . . . . . . . . . . . . 106

A.2 The hierarchy of the ReppSi project . . . . . . . . . . . . . . . . . . . . . . 106

A.3 Java build path that the Membrane libraries have been already imported . 107
LIST OF FIGURES x

A.4 Membrane proxy configuration . . . . . . . . . . . . . . . . . . . . . . . . . 108

A.5 MySQL connection configuration . . . . . . . . . . . . . . . . . . . . . . . . 108

A.6 Logger configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

B.1 The Java console prompts the user for the operation mode . . . . . . . . . . 109

B.2 The phpMyAdmin’s main page . . . . . . . . . . . . . . . . . . . . . . . . . 110

B.3 An example of the log file . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

C.1 The X-Frame-Options Header Not Set alert of http://moodle.bath.ac.uk/ 117

C.2 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 117

C.3 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 117

C.4 The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.uk/118

C.5 The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.


uk/login/logout.php?sesskey=2Ip9Ixv3xj . . . . . . . . . . . . . . . . . 118

C.6 The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.


uk/login/logout.php?sesskey=HlSnsofSqb . . . . . . . . . . . . . . . . . 119

C.7 The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.


uk/login/logout.php?sesskey=f5jFI7mpmN . . . . . . . . . . . . . . . . . 119

C.8 The Cookie Set without HttpOnly Flag alert of http://www.bath.ac.uk/


common/css/print.css?columns=2 . . . . . . . . . . . . . . . . . . . . . . 120

C.9 The Cookie Set without HttpOnly Flag alert of http://www.bath.ac.uk/


web/tools/sso/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

C.10 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 121

C.11 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 121

C.12 The Cross-Domain JavaScript Source File Inclusion alert of http://moodle.


bath.ac.uk/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

C.13 The response body of for the alert . . . . . . . . . . . . . . . . . . . . . . . 122

C.14 The Cross-Domain JavaScript Source File Inclusion alert of http://moodle.


bath.ac.uk/my/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

C.15 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 123


LIST OF FIGURES xi

C.16 The Web Browser XSS Protection Not Enabled alert of http://moodle.
bath.ac.uk/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

C.17 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 124

C.18 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 124

C.19 The X-Content-Type-Options Header Missing alert of http://moodle.bath.


ac.uk/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

C.20 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 125

C.21 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 126

C.22 The Cleartext Password over HTTP alert of http://moodle.bath.ac.uk/


enrol/index.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

C.23 The source code of http://moodle.bath.ac.uk/enrol/index.php . . . . . 127

C.24 26 affected URLs of the Cross-Site Script Include alerts . . . . . . . . . . . 128

C.25 The Cross-Site Script Include alert of http://moodle.bath.ac.uk/ . . . . 129

C.26 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 129

C.27 The Integer Overflow of http://moodle.bath.ac.uk/course/search.php 130

C.28 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 130

C.29 The Page Fingerprint Differential Detected of http://moodle.bath.ac.uk/


course/search.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

C.30 The Page Fingerprint Differential Detected of http://moodle.bath.ac.uk/


course/view.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

C.31 The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/ . 133

C.32 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 133

C.33 The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/


lib/javascript.php/-1/lib/javascript-static.js . . . . . . . . . . . 134

C.34 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 134

C.35 The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/my/ 135

C.36 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 135

C.37 The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/


/theme/yui_combo.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
LIST OF FIGURES xii

C.38 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 136

C.39 21 affected URLs of the Directory Listing Detected alerts . . . . . . . . . . 137

C.40 The Directory Listing Detected alert of http://moodle.bath.ac.uk/blog/


index.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

C.41 26 affected URLs of the Email Addresses Found alerts . . . . . . . . . . . . 139

C.42 The Email Addresses Found alert of http://moodle.bath.ac.uk/course/


view.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

C.43 The response body of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 140

C.44 The Cookie HttpOnly Flag Not Set alert of http://moodle.bath.ac.uk/ . 141

C.45 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 141

C.46 46 affected URLs of the X-Frame-Options Header Not Set alerts . . . . . . 142

C.47 The X-Frame-Options Header Not Set alert of http://moodle.bath.ac.uk/ 143

C.48 The request header of the alert . . . . . . . . . . . . . . . . . . . . . . . . . 143

C.49 The response header of the alert . . . . . . . . . . . . . . . . . . . . . . . . 143

C.50 The profile table of the Super Veda application 1 . . . . . . . . . . . . . . . 144

C.51 The profile table of the Super Veda application 2 . . . . . . . . . . . . . . . 145

C.52 An example of the log file generated by the ReppSi system . . . . . . . . . . 146

C.53 The SQL Injection - Authentication Bypass alert of Super Veda 1 . . . . . . 147

C.54 The SQL Injection - Authentication Bypass alert of Super Veda 2 . . . . . . 147

C.55 The SQL Injection - MySQL alert of Super Veda . . . . . . . . . . . . . . . 148

C.56 The response body of the SQL Injection - MySQL alert . . . . . . . . . . . 149

C.57 The MySQL Error Detected - Possible SQL Injection alert of Super Veda . 150

C.58 The response body of the MySQL Error Detected - Possible SQL Injection
alert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

C.59 The SQL Injection alert of /addcomment.jsp . . . . . . . . . . . . . . . . . 151

C.60 The SQL Injection alert of /dosearch.jsp . . . . . . . . . . . . . . . . . . . . 152

C.61 The SQL Injection alert of /login.jsp 1 . . . . . . . . . . . . . . . . . . . . . 152

C.62 The SQL Injection alert of /login.jsp 2 . . . . . . . . . . . . . . . . . . . . . 153


LIST OF FIGURES xiii

C.63 The SQL Injection alert of /login.jsp 3 . . . . . . . . . . . . . . . . . . . . . 153

C.64 The SQL Injection alert of /postcomment.jsp . . . . . . . . . . . . . . . . . 154

C.65 The SQL Injection alert of /proddetails.jsp . . . . . . . . . . . . . . . . . . 154

C.66 The SQL Injection alert of /recoverpasswordsend.jsp . . . . . . . . . . . . . 155

C.67 The SQL Injection alert of /showproducts.jsp . . . . . . . . . . . . . . . . . 155


List of Tables

4.1 The comparison of techniques used in each research . . . . . . . . . . . . . . 15

5.1 Summary result of scanning moodle.bath.ac.uk by OWASP ZAP . . . . . . 26

5.2 Summary result of scanning moodle.bath.ac.uk by Subgraph Vega . . . . . 29

6.1 A structure of the log table . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6.2 A structure of the profile table . . . . . . . . . . . . . . . . . . . . . . . . . 48

7.1 Classes and Methods of the ReppSi System . . . . . . . . . . . . . . . . . . 71

8.1 The result of scanning Super Veda by OWASP ZAP before ReppSi deployment 79

8.2 The result of scanning Super Veda by OWASP ZAP after ReppSi deployment 80

8.3 The number of the OWASP ZAP requests, the SQL exceptions generated,
and the SQL injection attacks that pass through the ReppSi system . . . . 83

8.4 The summary result of scanning Super Veda using Subgraph Vega before
ReppSi deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

8.5 The summary result of scanning Super Veda using Subgraph Vega after
ReppSi deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

8.6 The summary results of the performance test . . . . . . . . . . . . . . . . . 86

8.7 The result of the false positive test . . . . . . . . . . . . . . . . . . . . . . . 88

C.1 Summary result of scanning moodle.bath.ac.uk by OWASP ZAP . . . . . . 113

C.2 Summary result of scanning moodle.bath.ac.uk by Subgraph Vega . . . . . 126

xiv
Acknowledgements

Many thanks to Prof. James Davenport, my supervisor, for providing great guidance
and assistance throughout the seven months of the dissertation period.

Many thanks to Asst. Prof. Krerk Piromsopa, my advisor from Chulalongkorn Uni-
versity, for inspiring me to be interested in computer security and educating me about
research method while I was studying in the University.

Many thanks to Chadchapol Vittavutkarnvej, my geek friend, for suggestions about


Java programming and database systems.

Many thanks to my colleague who always put pressure on me, as well as motivated
me to work on my dissertation.

Finally, . . . many thanks to my mother who always believed in me, encouraged me,
and supported me. I love you.

xv
Chapter 1

Introduction

1.1 Background

In the age of the Internet that everyone can easily connect to and communicate with
each other, information is regarded as an important thing in the world. To provide the
convenience of collecting and accessing an amount of the information, the digital format
has been increasingly used to store that information [24]. For example, the civil regis-
tration recorded by the government used to be stored in the paper-based format, but, in
the present, most governments have stored them in their database systems in the digital
format [10, 11, 16]. Likewise, patient records of many health care organizations have been
gradually converted from the paper-based format to the digital format so that the patients
could access their information using computers and the Internet [32]. In addition, business
information, financial information, or other information that was recorded in the papers
should be converted to the digital format due to a lot of benefits. The digital format pro-
vides faster access to and retrieval of the information, better service delivery from the ease
of locating the relevant information, less time spent looking for the information, simpler
backup as well as recovery, and cost saving because of less creation, storage, retrieval, and
handling of paper records [30].

To standardize the methodology of storing information in the digital format, database


management systems and the SQL language were invented. Database management systems
(DBMS) are specialized computer software used to manage storage, use and protect the
data stored in the database. General-purpose DBMSs are designed to provide the defini-
tion, creation, update, querying, modifying, and administration of databases. Well-known
DBMSs in the today’s market consist of MySQL, Microsoft SQL Server, Oracle, IBM DB2,

1
CHAPTER 1. INTRODUCTION 2

Sybase, PostgreSQL, and so on [38]. Originally, DBMSs were used by programmers. The
stored data could be accessed via a program that the programmers wrote using a com-
plex programming language, such as COBOL. One program was responsible for a specific
purpose. If users wanted to access other data, it often required the DBMS programmers
to write new software, leading to an expensive for ad-hoc, or one-time, inquiries. Struc-
tured Query Language (SQL), invented by IBM in the 1970s, was developed as a simple
programming language that allowed non-technical users to easily contact the DBMSs in
order to access and manage data stored in the databases. The users could send requests to
the databases using simple SQL queries. Consequently, the SQL language has been widely
used in a great number of database management systems and database applications [27].

However, the SQL also required a basic skill of computer programming. Database users
need to learn some keywords and syntax to create queries sent to the databases. In some
cases, the users need to create very complex SQL queries to retrieve only specific data from
huge databases. As a result, a database application, computer software whose main purpose
is to enter and retrieve information from computerized databases, was invented to help the
users. It has an ability to create automatically SQL queries from the user’s input via the
application. Many database applications have been developed for multiple purposes. Most
organizations in the world, such as retail chain stores, government departments, financial
institutes, manufacturing enterprises, education, etc., use their database systems, including
databases, DBMSs, and database applications, to keep essential information they need to
run the businesses [38]. One of the most complex database systems is accounting system
from SAP which might contain several thousands of tables in a single module [5]. Another
famous enormous database system designed for social networking is Facebook which was
built on top of MySQL [23].

The advent of the Internet and the World Wide Web (WWW) provides more features
to the database systems. The Internet and the WWW have offered unique information
delivery mechanism which has allowed people throughout the world to communicate and
exchange information with each other. International Telecommunication Union [17] states
that there are almost 3 billion people (around 40 percents of the world population) who
use the Internet this day. Additionally, the growth rate has been increasing noticeably
year by year. Instead of designing applications specific for certain platforms, programmers
capitalized on the WWW and the Internet to create web-based applications (i.e., web ap-
plications or web services) on the top of DBMSs. The web application is cross-platform and
has become the most powerful data repository and information delivery system. Combined
with the Internet, it allows everyone to access and share information from anywhere in the
world. Most enterprises have taken advantage of the WWW and the database system to
CHAPTER 1. INTRODUCTION 3

create many kinds of web applications for multiple purposes, for example, online shopping,
online banking, online video streaming, online restaurant booking, and so on [38]. In ad-
dition to those business purposes, the web application has been widely used in education
such as library systems, registration systems, and e-learning systems. For the University of
Bath, there are many web services provided to staff, lecturers, and students, for instance,
SAMIS the University’s central database of student records, online library services that the
students can search for ebooks, online journals, or other academic articles, and Moodle a
learning platform [40].

1.2 Motivation

The undesirable thing that has followed the widespread use of web applications is a
cyber threat. People take advantage of using the web applications so that they can access
information on the Internet, communication with other people, and use online services for
the purpose of convenience. Similarly, attackers can exploit the web applications in order
to access or manipulate sensitive data in the databases without permission due to the
improper coding that leads to serious weaknesses or vulnerabilities. Many of the databases
contain valuable information, such as personal and financial details, making them a frequent
target of the attackers. The attackers exploit the web applications for several purposes,
e.g., showing their hacking skill to the world or launching political attacks. However, most
the attacks are financial motivated because the attackers could sell the information to the
organizations’ adversaries or even ask for ransom. The most popular and dangerous attack
against the database systems via the web applications is SQL injection [1].

The latest data breach investigations report from Verizon [46] points out that data
breaches in 2013 were caused by many types of threats such as point-of-sale intrusions,
insider misuse, cyber-espionage, crimeware, etc. However, the main cause was web ap-
plication attacks which took 35 percents of all types of the threats. There are a lot of
reasons why the attackers primarily targeted web applications. Firstly, web applications
must be available 24/7 to provide their services to employees, customers, and other stake-
holders. The attackers can launch attacks against web applications all the time. Secondly,
port-based firewalls and SSL cannot protect web applications from attacking since access
to the web applications have to be made public. In other words, port 80 (HTTP) and
443 (HTTPS) have to allow all traffic from both insiders and outsiders. It is difficult to
make the good/bad traffic distinction. Thirdly, web applications often connect directly to
backend databases. The attackers could exploit the web applications to access valuable
CHAPTER 1. INTRODUCTION 4

data in the databases. Finally, most web applications are custom software which involves
a lesser degree of testing than commercial off-the-shelf software. Consequently, they are
more susceptible to attack [1].

OWASP (Open Web Application Security Project), a worldwide non-profit organiza-


tion dedicated to web application security, released the ten most critical web application
security risks in 2013. It states that the most severe risk of the web application is injection
flaws such as SQL injection. Untrusted data could be sent to an interpreter as part of a
query or command. It can trick the interpreter into accessing data without proper per-
mission or executing unintended commands. Likewise, the United States Department of
Homeland Security, SANS institute, and MITRE all named SQL injection as the number
one most dangerous error for software [25]. SQL injection is the most severe vulnerability
due to ease of launching attacks but leading to critical impact to business operations. In
2012, a representative of Barclays claimed that 97% of data breaches were a result of SQL
injection attacks which contributed to more than 2.7 billion loss every year and affected
more than 1.8 million people [8]. It is noteworthy that SQL injection has been appeared
for more than ten years, responsible for countless data breaches around the world. Never-
theless, there is no solution that unconditionally prevents web applications and database
systems from SQL injection attacks [21].

For education, the report of Verizon [46] also discovered that education experienced
data breaches caused by web application attacks which were ranked second after miscella-
neous errors. Although the loss of the educational industry cannot be comparable to that
of financial institutes, government departments, or large enterprises, it has to confront a lot
of skillful students. Some of them may study computer science and want to test their new
hacking skills. Some may attack the university systems for some purposes such as steal-
ing exam papers, modifying the scores, or delaying assessment testing. More importantly,
some IT staff in the university might think that the university has no valuable informa-
tion. Hence, they do not seriously take concern about the security systems. As a result,
the university may leave security vulnerabilities unpatched, leading to being attacked by
attackers.

For the University of Bath which provides many online services, my supervisor, Prof.
James Davenport, is in close liaison with Mark Acres, the University Computer Security
Manager. We found that there were no vulnerabilities assessment and analysis of this kind
officially performed. This research will give an opportunity to scan and analyze the security
of the university’s online services and databases, especially SQL injection vulnerabilities.

To fix the vulnerabilities, there are many pieces of research about SQL injection de-
CHAPTER 1. INTRODUCTION 5

tection and prevention in the present. Although most of them are capable of handling SQL
injection attacks, they cannot implement in the real world without disturbing the applica-
tion systems. In other words, they need to modify the application code or be deployed in
the middle between the web server and the database server. In some situations that code
modification is not allowed or the web server and the database are on the same physical
server, it is difficult to apply those pieces of research to the application systems.

1.3 Statement of Purposes

The primary objective of this research is to evaluate security vulnerabilities of the


university’s databases/services such as the e-learning system, the registrations system, and
the library system. The research will begin with the e-learning system always used by staff,
lecturers, and students. Finding the vulnerability that allows an attacker to launch SQL
injection attacks is the first priority. Furthermore, a security system will be developed
for detecting and preventing SQL injection attacks which are the most dangerous threat
for web applications [25, 34]. This day, there are many pieces of research about protect-
ing applications from SQL injection attacks. Nonetheless, most of them need to alter the
application code or be deployed between a web server and a database server. These con-
ditions sometimes are not suitable for many environments. This research will propose a
new approach named as “ReppSi” (Reverse Proxy for Preventing SQL Injection) which
combines the use of a reverse proxy and the behaviour-based detection to prevent SQL
injection attacks. The proxy will be implemented in front of a web server and does not
require application code modification. Therefore, it could be easily installed in both the
university system and general web application systems.

1.4 Scope of Work

The scope of this research including:

• Discover and analyze the vulnerabilities of the university’s e-learning service, the
Moodle system.

• Implement and test the security system that is easy to install and does not require
application code modification.
CHAPTER 1. INTRODUCTION 6

• Implement and test the security system that can detect and prevent SQL injection
attacks.

1.5 Summary

In this paper, an analysis of the University of Bath’s online services and information
about the research of protecting web applications from being attacked by SQL injection
will be presented. It begins with the background of the university including databases/ser-
vices that the university has been using, in Chapter 2. Then, Chapter 3 shows the basic
concept of the SQL injection attack which is the primary threat this research would like to
mitigate. Moreover, this chapter will show types of SQL injection attacks and their effects
on the database system. After that, reviews of related researches in the past as well as their
strengths, weakness, and other comments will be described in Chapter 4. Chapter 5 pro-
vides security analysis of the University’s e-learning service, the Moodle system, using two
well-known web vulnerability scanner tools, OWASP ZAP and Subgraph Vega. Next two
chapters, Chapter 6 and 7, are the primary sections of this research. They present design
and implementation of the proxy “ReppSi” used to prevent the university’s databases/ser-
vices from the SQL injection attack. Then, Chapter 8 shows results and analysis of using
the ReppSi proxy to detect and prevent a web server from being attack by SQL injection.
Finally, the paper provides information about limitations, future works, and conclusion in
Chapter 9 and 10.
Chapter 2

The University Background

The University of Bath provides many online services to students, lecturers, and staff
so that they can access the university resources and databases from anywhere without going
to the university. There are three important web services including Moodle, the library
system, and the registration system.

Moodle is a free, online learning management system designed for both lecturers and
students. The lecturers can create courses, upload slides and learning materials, create
assignments, and give a mark along with comments to the students. For the students, they
can check the courses they attend, view and download the learning materials, submit the
assignments, and see their scores, as well as comments from the lecturers. Moodle also
provides forums so that the lecturers and the students can have a discussion. Besides, it
has a notification system that automatically alerts the students for new assignments as well
as deadline, and forum posts [29].

The library online system is offered by the Library & Learning Centre. The main
function is to store information about books, dissertations, journals, and other educational
materials. It also stores electronic versions (i.e., ebooks, e-journals, etc.) of those materials
which students, lecturers, and staff can search and view online. The library system is
linked to other publisher databases, such as ACM, IEEE, so that the users can access
varied electronic materials around the world. Additionally, the library system provides
information about borrowing and returning books which the users can track the status
from borrowing to returning items via the library website. The users can check and renew
their loans as well as place a reservation online as well [44].

The registration system powered by Student records & Examinations Office provides

7
CHAPTER 2. THE UNIVERSITY BACKGROUND 8

online information about registration for both new students and existing students. Inside
the registration system, there is a core service called SAMIS (Student & Applicant Manage-
ment Information System), the university’s central database of student records. It stores
information about applicants and students. The users can access SAMIS via the website,
or the full database can be accessed via a PC client-server. Students can view their units,
personal details, exam timetables, and choosing their units on-line. SAMIS is connected to
other computer systems across the university network and the Library & Learning Centre.
The registered status of the student on SAMIS provides access to university resources such
as the library resources, email, gaining a Students’ Union card [40].

In addition to those three main web services, there are many websites providing on-
line information and services, for example, websites for departments and faculties, a web
application for computing services, a website about the campus life, and so on.

In this research, security analysis will begin with Moodle since it is an important
e-learning system that both students and lecturers usually access everyday. More impor-
tantly, Moodle does not use SSL encryption, in other words, it is a unencrypted HTTP
website. Therefore, it cannot prevent third parties from eavesdropping on communications
between clients and web servers, leading to more online risk exposure to cyber attacks. Fur-
thermore, the Moodle template used to be vulnerable to SQL injection attacks more than
ten times starting from version 1.4.1 in 2004 to the latest version 2.8.5 in the present. The
programmers are also required to write additional code to prevent SQL injection attacks
[9, 28].
Chapter 3

SQL Injection Attacks

Structured Query Language (SQL) is a special-purpose programming language for


accessing databases. It is used to query, operate, and manage database systems, such as
Oracle, MsSQL, or MySQL. Database systems commonly provided backend functionality
to many web applications. User-supplied data from the web application is often used to
create dynamically SQL queries that interact directly with the backend database. An SQL
injection attack is an attack aimed at perverting the original intent of the web application
by submitting attacker-supplied SQL queries directly to the database system [7].

3.1 Overview of SQL Injection Attacks

SQL Injection is an attack technique that exploits non-validated input vulnerabilities


to pass attacker-supplied SQL commands through a web application so that they are ex-
ecuted by a backend database. Most SQL injection attacks are executed through a web
application that accepts user-supplied inputs as SQL query parameters. An attacker in-
puts a carefully crafted string in a form filed or as an URL parameter to build a new SQL
query sent to the backend database with results that are different from the intent of the
application developer [35].

A successful SQL injection attack can read sensitive data stored in the database,
modify data (insert, update, delete), execute administration operations on the database
such as shutdown the DBMS, and, in some cases, issue commands to the operating system.
The SQL injection attack is ranked first on the top ten most critical web application security
risk conducted by OWASP [34].

9
CHAPTER 3. SQL INJECTION ATTACKS 10

3.2 Types of SQL Injection Attacks

SQL injection attacks can be classified into seven types [14].

3.2.1 Tautologies

SQL tokens are injected to the conditional SQL statement in order to be evaluated
always true. This type of attack is often used to bypass authentication and access to data
by exploiting non-validated input using WHERE clause.

Example: An attacker submits a tautology statement “’ OR ‘1’=‘1” into the password


input field. Therefore, the SQL statement is always true. The result query is:

SELECT * FROM employee WHERE username=‘admin’ and password=‘’ OR ‘1’=‘1’

This tautology attack leads to bypass authentication.

3.2.2 Illegal/Logically Incorrect Queries

When an SQL query is rejected, the database will return an error message including
debugging information. An attacker can use this information to find vulnerable parameters
and the type as well as structure of the database.

Example: An attacker injects the following string into the password input field:“convert(int,
(select top 1 name from sysobjects where xtype=‘u’))” in order to cause a type conversion
error which can reveal database information. The result query is:

SELECT * FROM employee WHERE username=‘’ AND password=convert(int,(select


top 1 name from sysobjects where xtype=‘u’))

The MsSQL Server with the metadata table called sysobjects will return an error: “Mi-
crosoft OLE DB Provider for SQL Server (0x80040E07) Error converting nvarchar value
‘CreditCards’ to a column of data type int” From the error, the attacker will know that
the database is a MsSQL Server and the string’s value that caused the type conversion to
occur.

3.2.3 Union Query

An attack can join an injected query to the safe query using the keyword UNION in
order to obtain extra information related to other tables from the web application.
CHAPTER 3. SQL INJECTION ATTACKS 11

Example: “’ UNION SELECT cardnumber FROM creditcards WHERE accountnum-


ber=10032 -- ” is injected into the username field. The result query is:

SELECT * FROM employee WHERE username=‘’ UNION SELECT cardnumber FROM


creditcards WHERE accountnumber=10032 --’ and password=‘’

The null set will be returned for the original first query whereas the second query will
return data from the “creditcard” table (column “cardnumber” for account “10032”).

3.2.4 Piggy-backed Queries

This attack allows an attacker to exploit a database using the query delimiter such
as “;” in order to append an extra query to the original one. A successful attack causes
the database to receive and execute both the original query and the extra query which
is usually illegitimate. As a result, the attacker can access data, modify data, or execute
remote commands.

Example: An attacker injects “’; DROP table users --” into the password field. The result
query is:

SELECT * FROM employee WHERE username=‘admin’ and password=‘’; DROP table


users --

After finishing the first query, the database recognizes the query delimiter “;”, and then
executes the injected second query which would drop table users.

3.2.5 Stored Procedure

A stored procedure is a set of SQL statements that form a logical unit as well as
perform a particular task. It is used to encapsulate a set of queries or operations to
execute on a database server. For instance, operations on an employee database (e.g., hire,
fire, promote, lookup) could be written as stored procedures executed by the application
code. As the stored procedure could be coded by the programmer, it could be injected
by an attacker as well. Depend on the backend database, SQL injection attacks can be
built to execute stored procedures specifically provided by that database, including stored
procedures that interact with the operating system.
CHAPTER 3. SQL INJECTION ATTACKS 12

3.2.6 Inference

This type of attack is used against a high-security database. An attacker tries to get
information from the database by injecting various SQL commands into the web applica-
tion and then observes how the response/function of the application changes. The SQL
commands usually bases on true/false question about data values in the database. Con-
sequently, the attacker can deduce whether certain parameters are vulnerable and extra
information about the values in the database. There are two well-known inference attacks,
blind injection and timing attacks.

• Blind Injection: In some cases, a developer hides error information generated by


a database. An attacker can still steal database information by asking the database
true/false questions through SQL statements, and then observes the behavior of the
web application.

• Timing Attacks: An attacker can collect database information from a database


by observing delays in the database’s responses. The attacker builds injected queries
using an if/then statement whose branch predicate corresponds to an unknown about
the database contents. Along each branch, the attacker uses an SQL construct that
takes a known amount of time to execute, such as the WAITFOR keyword. The attacker
can deduce which branch was taken in his injection by measuring the increase/de-
crease in response time of the database. As a result, the attacker can infer the answer
to the injected question.

3.2.7 Alternate Encodings

Alternate encoding is evasion technique which allows an attacker to escape from the
detection system that scans input queries for certain known “bad characters”. The attacker
can modify the injected queries using alternate encodings such as hexadecimal, ASCII, or
Unicode. This technique is usually used with other types of attacks.

Example: The following string is injected into the username field: “admin’; exec(char
(0x73687574646f776e)) --”. The result query is:

SELECT * FROM employee WHERE username=‘admin’; exec(char(0x73687574646f776e))


-- AND password=‘’

The char(0x73687574646f776e) is the ASCII hexadecimal encoding of the text “SHUT-


DOWN”. When this query is interpreted by the database, it will result in the execution of
CHAPTER 3. SQL INJECTION ATTACKS 13

the SHUTDOWN command.

3.3 Impacts of SQL Injection Attacks

The impact and consequences of successful SQL injection attacks can be classified into
four categories.

• Confidentiality: SQL injection attacks lead to loss of confidentiality since databases


generally store sensitive and essential information. Unauthorized users can use SQL
injection attacks to view or steal the information in the databases.

• Integrity: Attackers can use SQL injection attacks to modify or delete critical in-
formation in the database without permission.

• Authentication: Due to poor user validation, SQL injection attacks allow attackers
to bypass authentication. The attackers can access to the database as an authenti-
cated user without knowledge of the username and password.

• Authorization: Successful SQL injection attacks contribute to privilege escalation.


They can execute SQL commands even though they do not have authorization [19].
Chapter 4

Literature Reviews

So far, there are many pieces of research which develop new frameworks, algorithms,
or techniques to detect and/or prevent SQL injection attacks. In this paper, those pieces
of research are classified into five categories according to their techniques including static
analysis, dynamic analysis, model-base approach, and anomaly-base approach. The com-
parison of all techniques used in each research is shown in table 4.1.

14
CHAPTER 4. LITERATURE REVIEWS 15

Table 4.1: The comparison of techniques used in each research


Modify
Approaches Type Code Additional Infrastructure
Base
4.1.1 Analysis Framework Detection No None
4.2.1 SQLrand Prevention Yes Proxy between web and database,
Application Instrumentation,
key Management
4.2.2 Positive Tainting Prevention Yes Application Instrumentation,
External libraries are required
4.3.1 AMNESIA Prevention Yes Application Instrumentation
4.3.2 SQLGuard Prevention Yes Application Instrumentation,
Key Management
4.3.3 SQLCheck Prevention Yes Application Instrumentation,
Key Management
4.3.4 SQL-IDS Prevention No Proxy between web and database,
IDS System-Training Set
4.4.1 Learning-based Detection No Packet sniffing, Developer Training
4.4.2 CANDID Detection Yes Application Instrumentation,
Developer Training
Proposed approach
Prevention No Proxy in front of web server
“ReppSi”

4.1 Static Analysis

4.1.1 An Analysis Framework for Security in Web Applications [47]

Wassermann and Su proposed an approach that combined static analysis and au-
tomated reasoning to verify user-supplied inputs. If the SQL queries generated by the
user-supplied inputs contain tautologies, they will be detected. They used the static anal-
ysis from Chistensen et al. [6] to generate finite state automata (FSA) for modeling a set
of valid SQL queries for each hotspot on the source code of the application that connects
to the database. Then, the context-free language (CFL) reachability algorithm was used
to analyze the structures and keywords of the valid SQL queries in the FSA so that they
CHAPTER 4. LITERATURE REVIEWS 16

could detect the presence of tautologies in WHERE clause which usually are signs of SQL
injection attacks. Moreover, the permission of using SQL commands, such as SELECT,
INSERT, UPDATE, DELETE, etc., for each user was checked. If the user did not have the
permission of using the certain command, the access control violation would be discovered.

This approach provides strong tautology-based SQL injection detection. However, this
is the primary drawback as well. This approach is limited to only detecting the tautology-
based attack which is only one of the many types of SQL injection attacks [20]. It also
cannot handle some SQL queries that contain the operator “LIKE” and “×”. Besides,
large and complex SQL queries lead to very big FSA which may cause high latency [4].

4.2 Dynamic Analysis

4.2.1 SQLrand: Preventing SQL Injection Attacks [3]

Instead of using normal SQL keywords, Boyd and Keromytis create SQL queries using
randomized instructions. That is, the SQL keywords in the source code are manipulated
by putting a random numbers (key) after the keywords. An example when the key is “123”
is shown below.

SELECT gender, AVG(age) FROM cs101.students WHERE dept = %d GROUP BY gender

SELECT123 gender, AVG123(age) FROM123 cs101.students WHERE123 dept = %d


GROUP123 BY123 gender

A proxy server implemented between the web server and the database server intercepts
the randomized SQL queries and de-randomizes the SQL keywords before forwarding the
normal SQL queries to the database. If the user tries to attack the web application using
SQL injection attacks, some SQL keywords must be input. However, the SQL keywords
from the user-supplied input will not be randomized. Therefore, the proxy’s parser will fail
to de-randomized the SQL keywords and reject the attacks.

The proxy server is also used to intercept an exception from the database so that
information about the database will not be revealed to the attacker. Nevertheless, the
security of using this approach depends on the key and the proxy server. If the attacker
compromises the key or the proxy server, SQLrand will not be able to prevent the attacks
[12, 20]. In addition, the source code must be modified to append a random key to SQL
keywords.
CHAPTER 4. LITERATURE REVIEWS 17

4.2.2 Using Positive Tainting and Syntax-Aware Evaluation to Counter


SQL Injection Attacks [13]

Halfond, Orso, and Manolios proposed an automated approach that detects and pre-
vents SQL injections based on the dynamic tainting mechanism which marks and tracks
certain data in an application at runtime. In other words, they identify “trusted” strings
in a program, mark them, and allow only these trusted strings to be created as certain
parts of the SQL query, such as SQL keywords or operators. The trusted strings in a
program are the whole code written by the programmer and the untrusted strings usually
are user-supplied inputs. In runtime, syntax-aware evaluation is used to distinguish the
trusted strings from the untrusted input data and make sure that all parts of an SQL query
other than string and numeric literals, i.e., SQL keywords and operators, consist only of the
trusted strings. If an SQL query contains strings not marked as trusted, it is assumed that
the application have been attacked by SQL injection, and the SQL query will be blocked.

Using positive tainting provides a lot of benefits. It is easier to marking and tracking
trusted data source than untrusted one. Missing untrusted data leads to false negatives,
that is, successful undetected attacks. In contrast, missing trusted data would lead to false
positives, i.e., legitimate SQL queries are classified as attacks, which are better. Addition-
ally, this approach can detect and prevent all kinds of SQL injection attacks [43]. On the
other hand, it has several drawbacks. For example, the application and its byte code must
be modified to mark the trusted strings, and the programmer is required to review the
marking process in order to prevent false positives.

4.3 Model-based Approach

4.3.1 AMNESIA Analysis and Monitoring for NEutralizing SQL-Injection


Attacks [12]

AMNESIA is a fully automated model-based approach for preventing SQL injection


attacks. It combines static analysis and runtime monitoring in order to detect the attacks.
In the static phase, web application code is analyzed, and models of all legitimate SQL
queries that can be generated by the web application are built. The generated models are
in the form of non-deterministic finite automata (NSA). In the dynamic phase, all SQL
queries sent to the database are intercepted and checked against the models from the static
phase. The SQL queries that violate the model will be classified as SQL injection attacks
and rejected. Figure 4.1 presents the architecture of AMNESIA.
CHAPTER 4. LITERATURE REVIEWS 18

Figure 4.1: High-level overview of AMNESIA [12]

AMNESIA can detect all kinds of SQL injection attacks except stored procedure
[22, 43]. Nonetheless, its capability depends on the precision and efficiency of the static
analysis for building the models. Incomplete building the models may lead to both false
negatives and false positives [2, 13]. Furthermore, it uses Java String Analyzer to analyze
the web application code and thereby obtain the query models. Hence, web applications
other than those developed using JSP, e.g. PHP or ASP, are not supported.

4.3.2 Using Parse Tree Validation to Prevent SQL Injection Attacks [4]

Buehrer, Weide, and Sivilotti implemented the SQLGuard using parse tree validation
to detect SQL injection attacks. Firstly, SQLGuard analyzes the application code and
create parse trees for every SQL statement before the inclusion of the user-supplied input.
At runtime, the parse tree for the SQL statement after the inclusion of the user-supplied
input will be created to compare with the original one, as illustrated in figure 4.2. If the
user- supplied input contains SQL keywords or operators, it will make the parse tree at
runtime different from the original parse tree and be suspected of an SQL injection attack.
CHAPTER 4. LITERATURE REVIEWS 19

Figure 4.2: An example of the parse trees before and after the inclusion of the user-supplied
input [4]

This approach is efficient and easy to validate the user-supplied input whether it
contains an SQL statement or a sub-statement. However, there are two major drawbacks.
The application code is needed to be modified, and a secret key is required for encapsulating
the user-supplied input. If the key is compromised, SQLGuard will fail to detect SQL
injection attacks [20].

4.3.3 The Essence of Command Injection Attacks in Web [41]

Su and Wassermann proposed the SQLCheck that used the similar technique as the
SQLGuard introduced by Buehrer, Weide, and Sivilotti [13, 20]. But instead of using a
secret key to wrap the user-supplied input, they add the key at the beginning and the
end of every user-supplied input. At runtime, any SQL statement that is not in a valid
syntactic form is suspected as an SQL injection attack.
CHAPTER 4. LITERATURE REVIEWS 20

Both SQLCheck and SQLGuard can detect all typed of SQL injection attacks except
stored procedure [22, 43]. Like the SQLGuard, the SQLCheck has two major weaknesses.
The application code is required to be modified in order to identify and annotate user-
supplied inputs. Missing identifying the user-supplied inputs may lead to false negatives
[13]. Moreover, the detection ability depends on the strength of the secret key [20].

4.3.4 SQL-IDS: A Specification-based Approach for SQL-Injection De-


tection [20]

SQL-IDS introduced by Kemalis and Tzouramanis has the similar concept as a general
signature-based intrusion detection system. Specifications of the web application must be
defined. They collect a set of rules which describe the expected structure of all SQL queries
that are generated by the application. SQL-IDS consists of two modules. Event monitoring
module intercepts SQL queries sent to the database and forwards them to the validity
check module which compares the structures of the SQL queries with those described by
the pre-defined specifications. If the queries do not conform to the specifications, they are
considered as SQL injection attacks. Then, the event monitoring module drops the queries.
Figure 4.3 shows the architecture of SQL-IDS.

Figure 4.3: The architecture of SQL-IDS [20]


CHAPTER 4. LITERATURE REVIEWS 21

The advantages of the SQL-IDS are that the programmer does not need to modify
the application code, and it is independent of any application environment or DMBS. In
contrast, the primary drawback is that the detection ability bases on the completeness of the
specifications. The application develop need to define the specifications by himself/herself,
leading to false positives and false negatives as a result of the gaps in such a specification.

4.4 Anomaly-based Approach

4.4.1 A Learning-Based Approach to the Detection of SQL Attacks [45]

This approach was developed under the concept of behaviour-base SQL injection de-
tection. Valeur, Mutz, and Vigna proposed an IDS system based on a machine learning
technique. This approach is divided into two phases, a learning phase and a monitoring
phase. In the learning phase, profiles of the legitimate SQL queries are created from the
normal database access performed by the web application. In the monitoring phase, SQL
queries sent to the database are compared with the structures of the SQL queries in the
profiles. If the queries do not match the pre-defined structures, they are suspected of SQL
injection attacks.

The main disadvantage of this approach is that the effectiveness of detecting SQL
injection attacks depends on the profiles learned from the normal situation. If the profiles
are incomplete, it may lead to high rate of false positive [2, 12]. Besides, this approach
is not designed to detect directly SQL injection attacks. It is developed to detect the
anomalous behavior while the users from using the web application.

4.4.2 CANDID: Preventing SQL Injection Attacks using Dynamic Can-


didate Evaluations [2]

Bandhakavi and his team members proposed an SQL injection detection tool called
Candidate evaluation for discovering intent dynamically or CANDID. This approach tries to
create automatically the structure of the programmer-intended SQL query from every part
of code connected to the database so that it can solve the issue of manually modifying the
application code to create the prepared statements. This process can be done by recording
the legitimate SQL queries and learning their structures. At runtime, the structures of the
SQL queries sent to the database are compared with the pre-defined structures in order to
detect SQL injection attacks.
CHAPTER 4. LITERATURE REVIEWS 22

Like the IDS system proposed by Valeur, Mutz, and Vigna, the detection ability
depends on the prepared statements built from the normal database access. It might be
impossible to make a complete of legitimate SQL structures for a large web application.

4.5 Summary

In conclusion, there are a lot of pieces of past research using various techniques to
detect and prevent SQL injection attacks, for example, static analysis, dynamic analysis,
model-based, or anomaly-based methods. Each of them has its own advantages and lim-
itations. Some of them need to modify the application code to create the models used
to detect SQL injection attacks at runtime. Some of them design SQL detection systems
installed between the web server and the database server, as presented in figure 4.4, in
order to inspect SQL queries generated by the web application.

Figure 4.4: The deployment of the systems installed between the web server and the
database server

However, the application source code may be not allowed to modify in many situations,
especially in banking and financial systems. In addition, in some environments such as a
web application on a single server with a built-in database deployment or a virtual machine
running both a web server and a database server, it is difficult to install the SQL detection
systems in the middle of the web server and the database server. To eliminate these
problems, this research will design an SQL prevention system that can be easily installed
in front of the web server and does not need to alter the application code.
Chapter 5

The University’s Service


Assessment

After reviewing the pieces of research in the past, the security system is decided to
be deployed in front of a web server in order to avoid code modification and incapability
of installing in some environments. Next step is to determine an approach to detect SQL
injection attacks. To assure that the approach can fix the SQL injection vulnerabilities
and protect the University’s e-learning service, Moodle, from being attacked, vulnerabil-
ity assessment must be performed. The Moodle system will be evaluated to discover and
identify web security vulnerabilities, especially SQL injection flaws. Two well-known web
application vulnerability scanners are used to provide comprehensive patterns of SQL in-
jection attacks. After that, the results will be analyzed and applied to design the effective
approach to detect SQL injection attacks.

5.1 Assessment Procedure

The objective of the assessment is to discover and identify web security vulnerabilities
of the Moodle e-Learning system, especially the vulnerability that can cause SQL injection
attacks. Two different web vulnerability scanning tools are used to search for security holes
in all directories under the domain moodle.bath.ac.uk. The procedure of the assessment is
shown below.

23
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 24

5.1.1 Assessment Setup

As illustrated in figure 5.1, the machine running web vulnerability scanning tools con-
nects to the internal network via the university-provided Wi-Fi “eduroam” so that traffic
from the machine is not inspected by the firewall. The Moodle website (http://moodle.bath.ac.uk)
will be logged in using a student account. Consequently, all HTTP requests from the scan-
ning tools can pass the authentication system.

Figure 5.1: A network diagram for the assessment setup

5.1.2 Vulnerability Scanning Tools

Two web vulnerability scanning tools consist of OWASP ZAP and Subgraph Vega.

• ZAP or Zed Attack Proxy is an open source penetration testing tool developed by
OWASP for finding vulnerabilities in web applications. It can scan many types of
web application attacks such as SQL injection, cross-site scripting, cross-site request
forgery, etc [37].

• Vega is a free, open source vulnerability scanner and testing platform developed by
Subgraph. It is a cross-platform, GUI-based, Java application designed to help IT
administrators to find vulnerabilities in their web applications [42].

Both of them are up-to-date software at the assessment time (ZAP version 2.3.1 and
Vega version 1.0). Each scanning tool is configured to scan all web vulnerabilities in its list
as shown in the next page.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 25

Vulnerability Scanning Lists of OWASP ZAP

Application Error Disclosure, Directory Browsing, Content-Type Header Missing, Cookie


Set without HttpOnly Flag, Cookie Without Secure Flag, Cross-Domain JavaScript Source
File Inclusion, CRLF Injection, Cross Site Scripting (persistent), Cross Site Scripting (per-
sistent) - Prime, Cross Site Scripting (persistent) - Spider, Cross Site Scripting (reflected),
External Redirect, Incomplete or No Cache-control and Pragma HTTP Header Set, Param-
eter Tampering, Password Autocomplete in Browser, Path Traversal, Private IP Disclosure,
Remote File Include, Remote OS Command Injection, Script Active Scan Rules, Script Pas-
sive Scan Rules, Secure Pages Include Mixed Content, Server Side Code Injection, Server
Side Include, Session ID in URL Rewrite, SQL Injection, Web Browser XSS Protection Not
Enabled, X-Content-Type-Options Header Missing, X-Frame-Options Header Not Set

Vulnerability Scanning Lists of Subgraph Vega

AJAX Detector, Bash Environment Variable Blind OS Injection, Blind OS Command Injec-
tion Timing, Blind SQL Injection Arithmetic Evaluation Differential, Blind SQL Injection
Timing, Blind SQL Text Injection, Differential Checks, Blind XPath Injection Checks,
Character Set Not Specified, Cleartext Password Over HTTP, Credit Card Identification,
Cookie Scope Detection, Cookie Security Module, Cross Domain Policy Auditor, Directory
Listing Detection, E-Mail Finder Module, Empty Response Body Module, Error Page De-
tection, Eval Code Injection, File Upload Detection, Form autocomplete, Format String
Injection Checks, HTTP Authentication Over Unencrypted HTTP, HTTP Header Checks,
HTTP Header Injection Checks, HTTP Trace Probes, Insecure Cross-Domain Policy, In-
secure Script Include, Integer Overflow Injection Checks, Interesting Meta Tag Detection,
Internal IP Addresses, Local File Include Checks, Oracle Application Server Fingerprint
Module, Path Disclosure, Remote File Include Checks, RSS/Atom/OPL Feed Detector,
Shell Injection Checks, Social Security/Social Insurance Number Detector, Source Code
Disclosure Module, Unsafe Or Unrecognized Character Set, URL Injection Checks, Version
Control String Detection, WSDL Detector, XML Injection Checks, XSS Injection Checks,
X-Frame-Options Header Not Set
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 26

5.2 Results and Analysis

5.2.1 Using OWASP ZAP

The summary result of using OWASP ZAP to discover the Moodle’s vulnerabilities is
presented in table 5.1.

Table 5.1: Summary result of scanning moodle.bath.ac.uk by OWASP ZAP


Number of False
Alert Severity
Affected URLs Positive
X-Frame-Options Header Not Set Medium 37 No
Cookie Set without HttpOnly Flag Low 6 No
Cross-Domain JavaScript Source File Inclusion Low 2 No
Web Browser XSS Protection Not Enabled Low 37 No
X-Content-Type-Options Header Missing Low 35 No

X-Frame-Options Header Not Set

Severity: Medium
Number of Affected URLs: 37
Definition by OWASP [37]: X-Frame-Options header is not included in the HTTP
response to protect against “ClickJacking” attacks.
Solution by OWASP [37]: Most web browsers in the present support the X-Frame-
Options HTTP header. The developer should ensure that it is set on all web pages returned
by the developer’s site. If the developer expects the page to be framed only by pages on
the developer’s server (e.g. it is part of a FRAMESET) then the developer needs to set the
header as SAMEORIGIN, otherwise if the developer never expects the page to be framed,
the developer should set DENY. ALLOW-FROM allows specific websites to frame the web
page in supported web browsers.

Comment: This alert is a ClickJacking vulnerability of the Moodle. The University’s web
developer is strongly recommended to configure the X-Frame-Options header field properly
in order to prevent the system from ClickJacking attacks. For example, X-Frame-Options:
deny or X-Frame-Options: sameorigin, depending on the Moodle’s source code.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 27

Cookie Set without HttpOnly Flag

Severity: Low
Number of Affected URLs: 6
Description by OWASP [37]: A cookie has been configured without the HttpOnly flag.
That is, the cookie can be accessed by JavaScript. If an attacker runs a malicious script on
this page, the cookie will be accessible and can be transmitted to another site. Similarly,
if it is a session cookie, session hijacking might be occurred.
Solution by OWASP [37]: The developer needs to ensure that the HttpOnly flag is set
for all cookies.

Comment: This alert is a vulnerability of the cookie in the Moodle page with low severity.
It leads to the accessibility of the cookie by JavaScript inside the application code. When
this vulnerability is combined with the “Cross-Domain JavaScript Source File Inclusion”
that allowed using external JavaScript running in the web page, an attacker might forge
the script and inject it into the web page, leading to leakage of sensitive cookies or session
hijacking.

Cross-Domain JavaScript Source File Inclusion

Severity: Low
Number of Affected URLs: 2
Description by OWASP [37]: The pages of the affected URLs include one or more
script files from a third-party domain.
Solution by OWASP [37]: The developer needs to ensure that JavaScript source files
are loaded from only trusted sources, and the sources cannot be controlled by end users of
the application.

Comment: The JavaScript files inside the affected URL pages are from MathJax, which
is a website providing a high-quality display of mathematics notation JavaScript files for
all web browsers [26]. It is a trusted source for downloading JavaScript files. However,
the connection between the Moodle page and the MathJax is unencrypted (http://cdn.
mathjax.org/mathjax/latest/MathJax.js). It might be attacked by a hacker using man-
in-the-middle technique. Consequently, the hacker can modify the JavaScript file and inject
it into the Moodle page. Additionally, combined with the “Cookie Set without HttpOnly
Flag” vulnerability, the hacker could steal the cookie or hijack the session.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 28

Web Browser XSS Protection Not Enabled

Severity: Low
Number of Affected URLs: 37
Description by OWASP [37]: Web Browser XSS Protection is not enabled or is disabled
by the configuration of the “X-XSS-Protection” HTTP response header on the web server.
Solution by OWASP [37]: The developer needs to ensure that the web browser’s XSS
filter is enabled, by setting the X-XSS-Protection HTTP response header to “1”.

Comment: This alert is not a vulnerability of the Moodle. It is an additional configuration


for the X-XSS-Protection header field in order to enable the web browser’s XSS protection
mechanism. The developer is strongly recommended to set this header field to “1”, meaning
that XSS attacks will be blocked.

X-Content-Type-Options Header Missing

Severity: Low
Number of Affected URLs: 35
Description by OWASP [37]: The “X-Content-Type-Options”, an Anti-MIME-Sniffing
header, was not set to “nosniff”. This allows older versions of Google Chrome and Internet
Explorer to perform MIME-sniffing on the response body, potentially causing the response
body to be interpreted and displayed as a content type other than the declared content
type.
Solution by OWASP [37]: The developer needs to ensure that the web application sets
the Content-Type header appropriately. That is, sets the X-Content-Type-Options header
to “nosniff” for all web pages.

Comment: This alert is also an additional configuration to raise the security level of
using web applications. The developer should set the Content-Type-Options header field
to “nosniff” so that the web application can be prevented from MIME-sniffing.

* See a full report of the result of using OWASP ZAP in Appendix C.1

5.2.2 Using Subgraph Vega

The summary result of using Subgraph Vega to discover the Moodle’s vulnerabilities
is presented in table 5.2.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 29

Table 5.2: Summary result of scanning moodle.bath.ac.uk by Subgraph Vega


Number of False
Alert Severity
Affected URLs Positive
Cleartext Password over HTTP High 1 No
Cross-Site Script Include High 26 No
Integer Overflow High 1 Yes
Page Fingerprint Differential Detected High 2 Yes
Local Filesystem Paths Found Medium 4 No
Directory Listing Detected Low 21 Yes
Email Addresses Found Low 26 No
Cookie HttpOnly Flag Not Set Info 1 No
X-Frame-Options Header Not Info 46 No

Cleartext Password over HTTP

Severity: High
Number of Affected URLs: 1
Description by Vega [42]: A form with a password user-supplied input is submitted
over an insecure channel (HTTP). This vulnerability could cause unauthorized disclosure
of passwords to attackers.
Solution by Vega [42]: Passwords should never be sent in the cleartext across unen-
crypted channel. The form should submit to an HTTPS target.

Comment: After an investigation, there is no cleartext password transmitted from/to web


clients over HTTP. Vega detected this flaw because it found the “password” type inside the
form in the application code. This form is used to send an enrolment key for self-enrolment.
However, the key is sensitive information that is recommended to be concealed. Figure 5.2
displays a screen capture of the web page and its source code.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 30

Figure 5.2: Comparison between the web page and its source code

Cross-Site Script Include

Severity: High
Number of Affected URLs: 26
Description by Vega [42]: The content on a web server is including JavaScript file from
an unrelated domain. When this script code is fetched by a user browser and loaded into
the DOM, it will have complete control over the DOM, bypassing the protection offered
by the same-origin policy. Even if the source of the script code is trusted by the website
operator, malicious code could be introduced if the server is ever compromised.
Solution by Vega [42]: It is strongly recommended that web servers should host their
own JavaScript locally, especially for critical applications.

Comment: This is the same vulnerability as “Cross-Domain JavaScript Source File In-
clusion” from the OWASP ZAP’s result. The external JavaScript file is from MathJax, a
trusted source.

Integer Overflow

Severity: High
Number of Affected URLs: 1
Description by Vega [42]: Integer overflow is a kind of buffer overflow which occur when
an integer data type exceeds its maximum value. When it occurs in programs written in
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 31

languages such as C, it contributes to security implications. For instance, unsigned integers


will be reduced, result in wrapping back to a lower numeric value. The consequence on
security depends on how the integer value is used. If it is used as the size of a data buffer,
it may lead to bypassing of size checks.
Solution by Vega [42]: The developer should investigate the error and determine if a
vulnerability is present.

Comment: After investigating, there is no sign of a bad result presenting on the Moodle
page. Moodle still operates as expected. This alert is not counted as a vulnerability of the
Moodle service.

Page Fingerprint Differential Detected

Severity: High
Number of Affected URLs: 2
Description by Vega [42]: A different response page fingerprint in relation to a local
file include injection request was detected. This means that the response page content
returned by the web application has a different signature from that returned by an ordi-
nary request, which may indicate the existence of a local file include vulnerability. Local
file includes vulnerabilities are present when externally-supplied input is used to specify
the location of a local filesystem resource that is requested by the web application. The
differing page fingerprint may include error messages or indicate a state change in the ap-
plication in response to the local file include injection attempt made by Vega. Differing
responses may also be indicative of a file enumeration vulnerability, which would allow an
attacker to determine if specific files exist on the system. Developers should examine the
response content and underlying code to verify whether or not a vulnerability is present.
If the vulnerability exists and precautions are not taken, such a vulnerability could allow
attackers to gain unauthorized access to sensitive information contained in local files, which
may also be leveraged in further attacks on the web application.
Solution by Vega [42]: To prevent this type of vulnerability, the developer should canon-
icalize the path of any filesystem resource that has a path composed of externally-supplied
input and then perform an authorization check prior to access. For example, the real-
path() library call will return the canonical path of the resource for PHP, Perl, and Python
programming.

Comment: After testing this vulnerability by sending many requests that made the Moo-
dle page returns its error pages, two different error messages were found as shown in figure
5.3. The messages generated depended on which type of the error the user made. Never-
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 32

theless, the error messages did not provide any sensitive information about the web server.
As a result, this is a false positive alert.

• If the user enters an ID inappropriately, the error page will display “Must specify
course id, short name or idnumber” message.

• If the user does not enter an existing ID, the error page will display “Cannot find
data record in database table course” message.

Figure 5.3: Two different error pages generated by the Moodle

Local Filesystem Paths Found

Severity: Medium
Number of Affected URLs: 4
Description by Vega [42]: A possible absolute filesystem path (i.e. one that is not
relative to the web root) was detected. This information is sensitive, as it may reveal things
about the server environment to an attacker. Knowing filesystem layout can increase the
chances of success for blind attacks.
Solution by Vega [42]: Full system paths are very often found in error output. This
output should never be sent to clients on production systems. It should be redirected
to another output channel (such as an error log) for analysis by developers and system
administrators.

Comment: The web server reveals filesystem paths in error responses by itself, for exam-
ple, /lib/ajax/setuserpref.php. This vulnerability may lead to exposure of sensitive infor-
mation such as the application’s environment and directories. An attacker can collect the
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 33

information and launch other attacks with a high success rate. The developer is recom-
mended to fix this vulnerability following the method Vega suggested

Directory Listing Detected

Severity: Low
Number of Affected URLs: 21
Description by Vega [42]: Listing directory contents when no index file is present in
a common misconfiguration. The directory contents can provide useful information to an
attacker, especially if there are files that are not meant to be accessible, such as source code
or backups. The directory listing may also provide useful information about the habits of
the server administration and/or web developers, such as file naming convention, that could
be used to increase the probable success of brute-force or other attacks.
Solution by Vega [42]: For Apache, add “IndexIgnore *” to the directory’s .htaccess
file, or alternatively remove “Indexes” from the line “Options All Indexes FollowSymLinks
MultiViews” in the Apache configuration file. For lighttpd, change “dir-listing.activate”
parameter from “enable” to “disable” in the lighttpd configuration file.

Comment: After checking the response source code thoroughly, the listing directory con-
tents that show sensitive information such as source code or backups were not found. This
alert is suspected as a false positive.

Email Addresses Found

Severity: Low
Number of Affected URLs: 26
Description by Vega [42]: Patterns that resemble email addresses in scanned content
were found. These may be user the addresses of system users, addresses inserted in user-
supplied content, or third-party addresses embedded in components of the application (such
as JavaScript libraries). Automatically scraping websites is one way that spammers and
phishers collect email addresses for their distribution lists.
Solution by Vega [42]: It is recommended that email addresses not be displayed on
exposed parts of the web application, directly or indirectly.

Comment: The email addresses found on the Moodle page is e-learning@bath.ac.uk and
lecturers’ email addresses. These email addresses are needed to be display for being a
communication channel for students and staff. It is an unavoidable risk. The spam filter
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 34

can help the university system to reduce the risk.

Cookie HttpOnly Flag Not Set

Severity: Information
Number of Affected URLs: 1
Description by Vega [42]: Vega has detected that this cookie was set without the
HttpOnly flag. When this flag is not present, it is possible to access the cookie via client-
side script code.
Solution by Vega [42]: The HttpOnly flag is a security measure that can help mitigate
the risk of cross-site scripting attacks that target session cookies of the victim. If the
HttpOnly flag is set and the browser supports this feature, attacker-supplied script code
will not be able to access the cookie.

Comment: This is the same vulnerability as “Cookie Set without HttpOnly Flag” from
the OWASP ZAP’s result.

X-Frame-Options Header Not Set

Severity: Information
Number of Affected URLs: 46
Description by Vega [42]: Vega has detected that the resource has not set the X-Frame-
Options HTTP response header. This header allows the resource to specify its policy with
regards to whether it may be included in frames in other domains as well as which domains
are allowed. When the header has been set, this may help to mitigate clickjacking attacks
against browsers that support this feature. If the header has not been set, the affected
resource may be used in clickjacking attacks.
Solution by Vega [42]: Set the X-Frame-Options header to DENY, SAMEORIGIN, or
ALLOW-FROM according to policy.

Comment: This is the same vulnerability as “X-Frame-Options Header Not Set” from
the OWASP ZAP’s result.

* See a full report of the result of using Subgraph Vega in Appendix C.2.
CHAPTER 5. THE UNIVERSITY’S SERVICE ASSESSMENT 35

5.3 Summary

Regardless of false positive vulnerabilities, OWASP ZAP and Subgraph Vega gave
quite similar results. For instance, the risk of using external JavaScript file and suggestions
about additional header field configurations. The results of the assessment show that the
Moodle e-learning system is programmed to tolerate web attacks quite well. That is, there
are no vulnerabilities with high severity able to harm the system except sensitive data
exposure from the enrolment key. In addition, any specific SQL injection vulnerability that
can compromise the Moodle service was not found from the assessment. As a result, there
is no need to design an approach to detect the SQL injection attack specifically for the
Moodle service. Although the result states that the SQL injection vulnerability was not
found, it does not mean the Moodle service does not have an SQL injection flaw. It might
not have been discovered yet. Besides, according to the concept of defense-in-depth [31],
the system should have multi-layered security mechanisms so that if an attack causes any
security mechanism to fail, other mechanisms can still provide the necessary mechanism to
protect the system. Hence, the Moodle service should have an additional security system
to prevent SQL injection attacks.

Due to no specific vulnerability about SQL injection, the security system designed in
this research will use an approach that can detect any SQL injection attack regardless of
its pattern, as well as suspicious HTTP traffic that may contain an SQL injection attack.
Another issue to point out is that even though the script from MathJax belongs to trusted
sources, the result shows that the Moodle page is allowed to use external JavaScript. The
security system should be carefully designed by considering this issue as well.
Chapter 6

Design

From literature reviews, the security system is decided to be deployed in front of a web
server instead of deploying between a web server and a database server. Its functionality
comprises of detecting and preventing HTTP traffic that is suspected as an SQL injection
attack. Reverse proxy deployment is selected as it provides many benefits including ease of
deployment and no application code modification required. Additionally, a web application
system that has both a web server and a database server on the same physical server can
take advantage of this type of deployment. The security system designed as a reverse proxy
with SQL injection prevention system will be called “Reverse Proxy for Preventing SQL
Injection” or “ReppSi”.

According to the results of the Moodle’s assessment, there is no specific vulnerability


for SQL injection needed to be considered carefully. The SQL injection prevention sys-
tem will be designed to both detect and prevent all types of SQL injection techniques.
Behaviour-based detection is selected as an approach of the prevention system since it
provides effective discovery of SQL injection attacks. In other words, an attacker has to
inject an SQL command via the user-supplied input or the URL of the web page. The SQL
command, which is later sent to be executed by the database server, generally contains
special characters such as “ ‘ ” (quote), “ ” (white space), “ , ” (comma), “ % ” (percent
sign), and so on. Checking special characters in the user-supplied input is a good idea to
detect SQL injection attacks but it leads to high rate of false positives. Behaviour-based
detection is more flexible by allowing only the characters that the users used to enter before
and blocking the rest. Additionally, most SQL commands have a longer length than normal
user-supplied inputs except those for comments or sending messages. The behaviour-based
detection collects the characteristics of using the web application such as URLs that the

36
CHAPTER 6. DESIGN 37

users accessed, patterns, and length of the user-supplied inputs. After that, it creates pro-
files as a set of security rules to detect unauthorized (anomalous) web usage. This approach
can identify attacks that enter through the user-supplied input efficiently. In addition to
SQL injection attacks which are the main targets, cross-site scripting, OS command injec-
tion, and parameter tampering are also expected to be detected by the behaviour-based
detection. Nonetheless, a successful rate of detecting the attacks and false positive rate
depend on correctness and accuracy of the profiles.

To conclude, the ReppSi system will be developed using the behaviour-based detection
as an approach to detect and prevent suspicious user-supplied inputs that may contain SQL
injection attacks.

6.1 Design’s Goals

Design’s goals for ReppSi are as follows.

• Create a security system in front of a web application without modifying application


code.

• The security system will be implemented as a reverse proxy that can intercept HTTP
traffic from users, and inspect the traffic for an SQL injection attack before redirecting
the traffic to the protected web server.

• Create a behaviour-based detection system for detecting SQL injection attacks hidden
inside HTTP traffic.

• The security system can block HTTP requests when necessary and return an appro-
priate error page.

In order to create the behaviour-based detection system, a database system is required


to collect HTTP traffic logs and create profiles as protection rules.

To support cross-platform feature, the security system will be written using Java
programming
CHAPTER 6. DESIGN 38

6.2 System Overview

The security system, ReppSi, is a reverse proxy designed to prevent SQL injection
attacks. That is, HTTP request traffic from a web client, instead of being sent directly to a
web server, will be redirected to the ReppSi system. Then, the system inspects the HTTP
traffic whether it is a legitimate HTTP request without any sign of an SQL injection attack
using the behaviour-based detection. After that, the HTTP request is forwarded to the
web server if it is legitimate. Otherwise, the ReppSi system drops the request and returns
an error page to the web client. Figure 6.1 illustrates an overview of the ReppSi system.

Figure 6.1: An overview of the ReppSi system designed in this research

The deployment in the reverse proxy mode provides several benefits including:

• Ease of deployment: ReppSi can be installed in front of the web server without
disturbing the application system much.

• Application transparent: Reppsi can protect the web application without manip-
ulating the web content or disrupting the protected application.

• Complete inspection: ReppSi can assemble packets into a complete message.


Then, it inspects the message and confirms that the message is not an SQL injection
attack before forwarding to the web server.
CHAPTER 6. DESIGN 39

6.3 System Architecture

ReppSi contains six modules, Listener, Sender, Session Manager, Suspicious Input
Detection Engine, Profile Database, and Logger. Figure 6.2 shows a block diagram that
presents the relationship among modules inside the ReppSi system.

Figure 6.2: The architecture of the ReppSi sytem

6.3.1 Listener

Listener module is responsible for handling incoming HTTP requests from the web
client and incoming HTTP responses from the web server, and then forward them to the
Session Manager module.

6.3.2 Session Manager

Session Manager module collects and manages information about HTTP sessions.
It modifies the HTTP request/response message received from the Listener module by
replacing the source/destination IP with an appropriate IP for redirecting the message to
the target destination (the web client or the web server).
CHAPTER 6. DESIGN 40

Moreover, it forwards the HTTP request/response to the Suspicious Input Detection


Engine for checking an SQL injection attack that might be hidden inside. In the case that
an SQL injection attack is detected, instead of modifying the message, it sends an error
page to the Sender module and drops the related session.

6.3.3 Suspicious Input Detection Engine

Suspicious Input Detection Engine (SIDE) is the main module of the ReppSi sys-
tem responsible for HTTP traffic inspection. It extracts necessary information from the
HTTP request message such as URL, method, header fields, and parameter values for some
purposes.

• In the learning phase, SIDE logs the information into the Profile Database module.
The information will be used to create profiles which will become security rules for
detecting suspicious user-supplied input later.

• In the protection phase, SIDE checks the information whether there is a suspicious
user-supplied input hidden inside the request by comparing to the security rules
(profiles) from the Profile Database module. If the suspicious input is detected, the
request will be suspected as an SQL injection attack. The result of the inspection is
sent to the Logger module and the Session Manager module.

6.3.4 Profile Database

Profile Database module is an SQL database that contains many database tables.
Each protected web server possesses two unique tables, a log table and a profile table.

• A log table collects legitimate HTTP request information such as URLs, methods,
and parameters from the Suspicious Input Detection Engine. This information will
be used to create/update the profile table.

• A profile table collects conditions digested from the log table for each URL and
parameter. The HTTP request that matches the conditions will be counted as a
legitimate request. Otherwise, it will be suspected as an SQL injection attack.
CHAPTER 6. DESIGN 41

6.3.5 Logger

The primary function of the Logger module is to collect information of the inspection
from the Suspicious Input Detection Engine. The information consists of a timestamp, the
original HTTP request, and the result of the inspection. A security administrator can use
the Logger module to track the history of the HTTP requests in order to analyze a trend
of SQL injection attacks or create an SQL injection report.

6.3.6 Sender

Sender module is responsible for handling the HTTP request/response including the
error page received from the Session Manager module. It creates a connection and forwards
the request/response to the destination.

6.4 System Process

ReppSi’s Suspicious Input Detection Engine (SIDE) use behaviour-based detection as


an approach to inspect the HTTP request for an SQL injection attack. This approach re-
quires a learning phase for collecting legitimate HTTP requests so that the SIDE can create
profiles for the protected web application. After finishing learning, in the protection phase,
the SIDE will use the profiles as security rules to scan all HTTP requests for suspicious
user-supplied input. If the suspicious input is detected, the requests will be suspected as
SQL injection attacks. ReppSi’s process can be divided into three steps.

6.4.1 Database and Proxy Preparation

1. When ReppSi starts the operation, the security administrator must enter a hostname
or an IP address of the protected web server and the operation mode (Profiling or
Protection) via the Java console.

2. If the operation mode is “Profiling”, SIDE checks whether the log table of the pro-
tected web server exists. If not, SIDE creates a log table for the protected web server.
If the operation mode is “Protection”, ignore this step.

3. SIDE creates a profile table for the protected web server if it does not exist. Then,
SIDE updates the profile table according to the information in the log table.
CHAPTER 6. DESIGN 42

4. The Logger module prepares a log file for logging the system events and the alerts
generated by SIDE.

5. SIDE sends a message which contains information about the protected web server,
the operation mode, and the database status to the Logger module.

6. The Logger module writes the information on the log file. This information is also
displayed on the console.

Figure 6.3: The process of database and proxy preparation


CHAPTER 6. DESIGN 43

6.4.2 Learning Phase

1. An HTTP request is sent from the web client to the ReppSi.

2. The Listener module receives the request, and then forward to the Session Manager
module.

3. The Session Manager saves the request along with the session information.

4. The Session Manager modifies the request’s headers by replacing the source IP with
the ReppSi IP and the destination IP with the web server IP before forwarding to
the Sender module.

5. The Sender module forwards the modified request to the protected web server.

6. The web server processes the request and returns an HTTP response to the ReppSi.

7. The Listener module receives the response, and then forward to the Session Manager
module.

8. The Session Manager module checks the status code. If it is success 2xx or redirection
3xx, the Session Manager finds the response’s request from its session information,
and then sends it to the SIDE for logging. Otherwise, go to step 9.

9. The SIDE extracts necessary information from the request message such as, header
fields, URL, method, parameter values, etc., and then inserts the information into
the protected web server’s log table via the Database module.

10. The Session Manager modifies the response’s headers by replacing the source IP with
the ReppSi IP and the destination IP with the web client IP before forwarding to the
Sender module.

11. The Sender module forwards the modified request to the web client.

Figure 6.4 shows the process of the learning phase for any HTTP request sent to the
protected web server.
CHAPTER 6. DESIGN 44

Figure 6.4: The process of the learning phase

When the learning phase finishes, stopping and restarting the ReppSi system are
required in order to create/update the profiles (see details in 6.4.1 Database and Proxy
Preparation). The security administrator can change the operation mode to “Protection”
as well.
CHAPTER 6. DESIGN 45

6.4.3 Protection Phase

1. An HTTP request is sent from the web client to ReppSi.

2. The Listener module receives the request, and then forward to the Session Manager
module.

3. The Session Manager forwards the request to SIDE for checking the suspicious user-
supplied input.

4. SIDE extracts necessary information from the request message such as header fields,
URL, method, parameter values, etc. and then selects a profile according to the
request information from the Profile Database module.

5. SIDE performs condition matching.

(a) If the request information complies with the profile, SIDE informs the Session
Manager that the request is legitimate.
(b) Otherwise, SIDE informs the Session Manager that the request is suspicious and
may contain an SQL injection attack. The information about the request and
the reason why it is illegitimate is sent to the Logger module.

6. The Session Manager receives the decision from SIDE.

(a) If legitimate, the Session Manager modifies the request’s headers by replacing
the source IP with the ReppSi IP and the destination IP with the web server IP
before forwarding to the Sender module.
(b) If illegitimate, the Session Manager creates an error page, and then forwards to
the Sender module. Meanwhile, the Logger module writes the alert information
on the log file. This information is also displayed on the console.

7. The Sender module forwards the modified request to the protected web server or
returns the error page to the web client.

Figure 6.5 presents the process of the protection phase for any HTTP request sent to
the protected web server. For any HTTP response returned from the web server, ReppSi
just forwards it to the web client.
CHAPTER 6. DESIGN 46

Figure 6.5: The process of the protection phase

6.5 Database System

A database system inside ReppSi is a part of the Profile Database module. HTTP
request logs and profiles of each protected web server are collected individually. That is,
one web server has its own log table and profile table. The web server is defined by a
domain name or an IP address such as example.com or 172.16.1.250.
CHAPTER 6. DESIGN 47

6.5.1 Log Table

A log table for the protected web server is created when ReppSi start its operation if it
does not exist. The log table name will be in the format of PROTECTED WEB SERVER
NAME-log, such as example.com-log. In the learning phase (profiling mode), this table
collects traffic logs from legitimate HTTP requests including request number, URL, method,
parameter name, parameter value, parameter type, and parameter length as presented in
table 6.1.

Table 6.1: A structure of the log table


Column Name Type Description
Req Integer Request number of the request, starting with 1 and incre-
menting by 1. The same request with different parameter
also has the same request number.
URL varchar The URL of the request
Method varchar The method of the request, such as GET, POST, etc.
Name varchar The parameter name
Value varchar The parameter value
Type varchar Type of the parameter value, including “Blank”, “Latin
Characters”, “Numeric”, “Special Characters”, “Latin
Characters & Numeric”, “Latin & Special Characters”,
“Numeric & Special Characters”, and “All”.
Length Integer Length of the parameter value
isCheck Boolean This column indicates a status of the record. True means
this record has been already used to update the profile.
False means not yet.

The records in the log table will be used to create or update the protected web server’s
profile.

6.5.2 Profile Table

Similar to the log table, a profile table is updated when the ReppSi starts its operation
or created if it does not exist. The table name is in the format of PROTECTED WEB
SERVER NAME-profile, such as example.com-profile. This table collects data that is di-
gested from the data in the log table for each URL and parameter. The data consists of
CHAPTER 6. DESIGN 48

URL, method, parameter name, parameter type, maximum/minimum length of the pa-
rameter value, and special characters that are allowed for the parameter value as shown in
table 6.2. This data will be used for condition matching in the protection phase (protection
mode).

Table 6.2: A structure of the profile table


Column Name Type Description
URL varchar The URL that the user can access
GET Boolean True if the URL supports GET method
POST Boolean True if the URL supports POST method
OtherMethods Boolean True if the URL supports other methods except GET and
POST
Name varchar The parameter name that belongs to the URL
Type varchar Value type allowed for the parameter value, including
“Blank”, “Latin Characters”, “Numeric”, “Special Char-
acters”, “Latin Characters & Numeric”, “Latin & Special
Characters”, “Numeric & Special Characters”, and “All”.
Max Integer Maximum length allowed for the parameter value
Min Integer Minimum length allowed for the parameter value
AllowedSpecial varchar List of special characters allowed for the parameter value
Characters

In the protection phase, when ReppSi intercepts the HTTP request from the web
client, the request information is forwarded to the Suspicious Input Detection Engine where
the condition matching is processed. If the request information complies with the conditions
(data) in the profile table, the request will be regarded as a legitimate HTTP request.
Otherwise, it will be suspected as an SQL injection attack.

6.6 Logging System

ReppSi contains the Logger module responsible for collecting and displaying system
event logs and alert logs. All logs will be displayed on the console and written on the text
file so that a security administrator can use the log file to track the history of the SQL
injection attacks detected by the ReppSi system or create an SQL injection report. The
logs are collected in the pattern showing in the next page.
CHAPTER 6. DESIGN 49

DATE TIME [SEVERITY] SYSTEM EVENT LOG OR ALERT LOG


DETAILS OF THE ALERT LOG

Example: System event log

21-08-2015 03:03:04 [INFO] Creating a table ‘172.16.1.101-profile’ for profiling

Example: Alert log

21-08-2015 05:17:27 [SEVERE] Unauthorized Special Character for Parameter:


password=’ OR ‘1’=‘1 (;$!)
IP: 172.16.1.100 Destination: 172.16.1.101 URL: /login.jsp Method: GET
Parameter: username = admin, return = welcome.jsp, password = ’ OR ‘1’=‘1,
mode = login,

6.7 Error Page

As illustrated in figure 6.6, an error page is generated by the Session Manager when
a suspicious request that may contain an SQL injection attack is detected, and the Session
Manager drops the HTTP request. This feature helps the developer to conceal sensitive
server information from an error message generated by the web server. Furthermore, it
helps the security administrator to prevent Blind SQL injection attacks.

Figure 6.6: An error page generated by ReppSi


CHAPTER 6. DESIGN 50

6.8 False Positives and False Negative Handling

In the protection phase, all HTTP requests intercepted by ReppSi are compared to
the profiles in the database. If ReppSi cannot find appropriate profiles, it will block the
requests and return an error page to the web clients. In the case that the dropped request
is a legitimate request without any sign of an SQL injection attack, it will be a false
positive. This is mostly because of the incompleteness of the profiles. The root causes of
the incompleteness is that the number of the requests collected in the learning phase might
be not enough to cover all patterns of the legitimate requests. In order to reduce the false
positive rate, ReppSi will permit the security administrator or the developer to update
or modify the profile database. It is strongly recommended that they review the profiles
before running ReppSi in the protection mode. A log file is a useful tool for reviewing and
adapting the profile database.

On the other hand, if the requests collected in the learning phase contain illegitimate
requests or requests that have malicious code inside, they might cause false negatives.
Review and discussion of the profiles between the security administrator and the web
developer help to minimize the false negative rate. In the case that the profile record led to
the false negative cannot be modified, the security administrator is recommended to apply
other security mechanisms according to the defense-in-depth concept or takes the risk of
the vulnerability.
Chapter 7

Implementation

This chapter will begin with describing necessary equipment and tools used to imple-
ment each module in the security proxy, ReppSi. Then, it presents how each module works
and is implemented in details. Tables, diagrams, and pseudo code will be shown to make
the content easy for understanding.

7.1 Necessary Tools for Implementation

There are four main tools required for implementing the ReppSi system.

7.1.1 Java Programming Language

Java is one of the most famous programming languages commonly used in the world
today. It is cross-platform, meaning that it can run on major operating systems such
as Windows, Mac OS X, and Linux if they have Java virtual machine (JVM) installed.
Additionally, there are many online resources and documents that support the programmer
to write Java code efficiently [18].

7.1.2 Membrane Service Proxy

Membrane Service Proxy is a framework written in Java for implementing a reverse


HTTP proxy. It provides functions for intercepting HTTP traffic and redirecting them
to appropriate destinations. More importantly, the interception feature is regarded as an
essential feature of the Membrane Service Proxy. An interceptor can be added into the flow

51
CHAPTER 7. IMPLEMENTATION 52

of messages in order to add functionality or change the behavior. The interceptor can be
built to read the content of a request/response message and its protocol information such
as HTTP header fields. It also can modify a message, for instance, changing the destination
of a message. Moreover, it can stop the message processing and create its own message to
be forwarded to the destination [39].

Therefore, implementing ReppSi using the Membrane framework will provide HTTP
traffic interception and redirection features which cover the operations of three ReppSi’s
modules including Sender, Listener, and Session Manager. The framework version used in
this research is the latest version 4.0.

7.1.3 MySQL Database Management System

ReppSi requires a database system to collect logs and profiles of the protected web
servers. MySQL database management system is selected to be implemented in the ReppSi
system as it is open source software with high performance. In this research, MAMP 3.0
is installed on the laptop running ReppSi since it is a software package containing MySQL
and phpMyAdmin, a free software tool for handling the administration of MySQL over the
web.

7.1.4 Laptop for running ReppSi

ReppSi is pure Java-based reverse proxy software that can run on most operating
systems. In this research, ReppSi is implemented on the MacBook Air with Mac OS X
Yosemite 10.10. Figure 7.1 shows a comparison between the modules in the ReppSi system
and the tools for implementation.
CHAPTER 7. IMPLEMENTATION 53

Figure 7.1: A comparison between the modules in ReppSi and the tools for implementation

7.2 Listener, Sender, and Session Manager Modules

Listener, Sender, and Session Manager are implemented using a framework of Mem-
brane Service Proxy. To intercept the HTTP traffic, the framework require an IP address/a
domain name and a port of the destination server (the protected web server), as well as a
listen port of the host (ReppSi). When web clients call the host with the listen port, all
HTTP traffic sent to the host will be intercepted. The host running the Membrane Service
Proxy can make a decision to forward or reject the traffic. If the host forwards the traffic,
it will be redirected to the destination server. An example of using the Membrane Service
Proxy is shown in figure 7.2.

All HTTP requests sent to 172.16.1.100:80 will be intercepted by the host. Then, the
host can apply some policies such as suspicious input detection to the requests. After that,
the host can decide to drop or redirect the requests to www.example.com:80.
CHAPTER 7. IMPLEMENTATION 54

Figure 7.2: An example of using the Membrane Service Proxy

In the real world implementation, the DNS configuration must be modified to make
the destination server transparent from the web clients. It must resolve the hostname
“www.example.com” to “172.16.1.100” instead of its original IP address “172.16.1.250”.
As a result, whenever the web clients call www.example.com, the HTTP requests are sent
to the proxy.

7.2.1 Proxy Preparation

Listener, Sender, and Session Manager combine to be a reverse proxy module. The
proxy module is a core program of the ReppSi system for intercepting the HTTP request
so that ReppSi can use the Suspicious Input Detection Engine to inspect the request for
a suspicious user-supplied input that may contain an SQL injection attack. According
to 6.4.1 Database and Proxy Preparation, the Suspicious Input Detection Engine (SIDE)
is responsible for handling the database preparation. Therefore, when ReppSi starts the
operation, the proxy module requests the SIDE to prepare the database. The pseudo code
of preparing the reverse proxy is shown in the next page.
CHAPTER 7. IMPLEMENTATION 55

Pseudo Code 1 Proxy Preparation


1: Class
2: listenP ort ← LISTEN PORT OF PROXY;
3: targetHost ← DESTINATION NAME OR IP;
4: targetP ort ← DESTINATION PORT;
5: mode ← READ(OPERATION MODE); . “Profiling” or “Protection”
6: side ← createSuspiciousInputDetectionEngine();
7: side.prepareDatabase();
8: T raf f icInterceptor ← createInterceptor(mode, side);
9: prepareProxy(listenP ort, targetHost, targetP ort, traf f icInterceptor);
10: Logger.print(DATABASE AND PROXY STATUS);
11: EndClass

According to the pseudo code, the Membrane Service Proxy supports multiple inter-
ceptors at the same time. However, ReppSi requires only one interceptor for detecting SQL
injection attacks, called TrafficInterceptor. The TrafficInterceptor has two responsibilities,
HTTP request handling and HTTP response handling, which will be mentioned in the next
section. After finishing the preparation, the proxy module writes information about the
database and the proxy status on the log file.

7.2.2 HTTP Request Handling

One of the main functions of the TrafficInterceptor is to handle incoming HTTP


requests. That is, it can apply some security rules to filter the requests or just forward the
requests to the destination web server.

• In the protection phase, the TrafficInterceptor will send the incoming request to the
SIDE for checking SQL injection attacks. If the SIDE replies that the request is
suspected as an SQL injection attack, the TrafficInterceptor drops the request and
returns an error page to the web client. Otherwise, it forwards the request to the
destination server.

• In the learning phase, the TrafficInterceptor always forwards the request to the des-
tination server.

Additionally, only the request targeting a dynamic web page (The page that contains
server-side code such as PHP, ASP, and JSP) will be inspected since it can compromise
the database by performing an SQL injection attack. The request targeting a static web
CHAPTER 7. IMPLEMENTATION 56

page can pass through the proxy without being inspected. This condition helps the proxy
to reduce the processing time of the static request.

Pseudo Code 2 HTTP Request Handling


1: function handleRequest(request)
2: if mode = “protection” then
3: if isRequestToDynamicPage(request) then
4: if side.isSuspiciousRequest(request) then
5: errorP age ← createErrorResponse();
6: returnErrorResponse(errorP age);
7: end if
8: end if
9: end if
10: forwardRequest(request);
11: end function

7.2.3 HTTP Response Handling

Another function of the TrafficInterceptor is the response handling. Similar to the


request handling, it can apply some actions to the responses or just forward the response
to the web client.

• In the protection phase, the TrafficInterceptor checks the status code of the response
message. If it is an error 4xx or 5xx, the TrafficInterceptor will replace the response
message with its own error page in order to conceal the error message that might
display sensitive server information to the user.

• In the learning phase, the TrafficInterceptor will forward the response’s request to
the SIDE for logging if it is a good request. In other words, the response’s status
code is 2xx or 3xx and the request was sent to the dynamic web page.
CHAPTER 7. IMPLEMENTATION 57

Pseudo Code 3 HTTP Response Handling


1: function handleResponse(response)
2: if mode = “protection” then
3: if statusCode ≥ 400 then
4: errorP age ← createErrorResponse();
5: returnErrorResponse(errorP age);
6: else
7: forwardResponse(response);
8: end if
9: else
10: if statusCode < 400 && isRequestToDynamicPage(request) then
11: side.logRequest(response.getRequest());
12: end if
13: forwardResponse(response);
14: end if
15: end function

7.3 Suspicious Input Detection Engine

Suspicious Input Detection Engine (SIDE) is a core module for detecting a suspicious
user-supplied input that might contain an SQL injection attack. It applies the behavior-
based detection to create a profile as a set of security rules for identifying anomalous input
hidden inside HTTP requests. From the design, SIDE has three main functions including
database preparation, request logging and profile updating, and suspicious input detection.

7.3.1 Database Preparation

Database preparation is performed by SIDE when ReppSi starts its operation. The
main tasks are to prepare the MySQL database for logging and profile updating. From the
design in 6.4.1 Database and Proxy Preparation, the pseudo code is presented in the next
page.
CHAPTER 7. IMPLEMENTATION 58

Pseudo Code 4 Database Preparation


1: function prepareDatabase
2: connectDatabase(M ySQL);
3: if log table not exist then
4: M ySQL.createLogTable(DESTINATION-log);
5: else
6: if prof ile table not exist then
7: M ySQL.createProfileTable(DESTINATION-profile);
8: end if
9: DESTINATION-profile.updateProfile(DESTINATION-log);
10: end if
11: end function

7.3.2 Request Logging and Profile Updating

ReppSi requires a learning phase to collect a number of legitimate HTTP requests in


order to build a profile for each protected web server. The profile then will be used as a
set of security rules for SQL injection detection. The learning phase can be divided into
two steps, request logging, and profile updating.

Request logging is a process of extracting the request information from HTTP requests
and inserting it into the log table. However, not all HTTP requests will be collected in the
database. Only the requests that target dynamic web pages are selected as these requests
are usually sent to process in the web server. The processing often requires a database
connection. Consequently, an attacker can hide SQL injection attacks inside those requests
to query the database without permission. On the other hand, the requests targeting
static web pages will fetch only static content from the web server without connecting to
the database. Therefore, ReppSi does not need the profile for the HTML pages since an
attacker cannot perform SQL injection attacks on these pages. This condition will decrease
the database size and reduce the processing time of the profile updating.

Furthermore, ReppSi should filter out bad HTTP requests before inserting to the
database. The bad requests are HTTP requests that return the responses with a status
code of 4xx or 5xx. These requests do not need to collect as they generate errors. Only the
HTTP requests that return the responses with a status code of success 2xx or redirection
3xx will be appropriate for creating/updating the profiles.

The request information extracted from the HTTP request that passes all conditions
mentioned before consists of URL, method, parameter names, and parameter values. After
CHAPTER 7. IMPLEMENTATION 59

extracting, each parameter value is processed to find the parameter type which is classified
in eight types, including “Blank”, “Latin Characters”, “Numeric”, “Special Characters”,
“Latin Characters & Numeric”, “Latin & Special Characters”, “Numeric & Special Charac-
ters”, and “All”. Concurrently, the length of the parameter value is also calculated. After
that, the request information along with the parameter type and the parameter length are
inserted into the log table.

Pseudo Code 5 Request Logging


1: function logRequest(request)
2: parameters<name, value> ← getParameters(request);
3: if parameters.isEmpty() then
4: M ySQL.insertIntoLogTable(requestN umber, request.U RL, request.method, N U LL,
N U LL, N U LL, N U LL, F ALSE);
5: else
6: for each entry in parameters do
7: M ySQL.insertIntoLogTable(requestN umber, request.U RL, request.method,
parameters.name, parameters.value, getValueType(parameters.value),
parameters.value.length(), F ALSE);
8: end for
9: end if
10: requestN umber++;
11: end function

Example HTTP Request:


http://www.example.com/login.php?username=suthee&password=pass123!&code=2245

Extracted information:
URL: /login.php
Method: GET
Parameter #1 (Name, Value, Type, Length): username, suthee, Latin Characters, 6
Parameter #2 (Name, Value, Type, Length): password, pass123!, All, 8
Parameter #3 (Name, Value, Type, Length): code, 2245, Numeric, 4

Database Table:
www.example.com-log
CHAPTER 7. IMPLEMENTATION 60

Req URL Method Name Value Type Length ischeck


123 /login.php GET username suthee Latin 6 False
Characters
123 /login.php GET password pass123! All 8 False
123 /login.php GET code 2245 Numeric 4 False

After the database has collected a number of requests, profile updating can be per-
formed by restarting the ReppSi system as mentioned in 6.4.2 Learning Phase. All records
in the log table that the value in the column “isCheck” is “False” will be selected to update
the profile table. The updating process in details is shown in figure 7.3.
CHAPTER 7. IMPLEMENTATION 61

Figure 7.3: Flowchart of the profile updating


CHAPTER 7. IMPLEMENTATION 62

From the flowchart, the pseudo code can be written as follows.

Pseudo Code 6 Profile Updating


1: function updateProfile(logT able, prof ileT able)
2: logSet ← M ySQL.selectAllWhereisCheckisFalse(logT able);
3: for each record in logSet do
4: if logSet.N ame = N U LL then
5: prof ileSet ← M ySQL.selectRecordByURL(prof ileT able);
6: if prof ileSet.isEmpty() then
7: M ySQL.insertIntoProfileTable(logSet.U RL, logSet.method);
8: else
9: M ySQL.updateProfileTable(logSet.U RL, logSet.method);
10: end if
11: else
12: specialCharacters ← getSpecialCharacterInValue(logSet.value);
13: prof ileSet ← M ySQL.selectRecordByURLandParameter(prof ileT able);
14: if prof ileSet.isEmpty() then
15: M ySQL.insertIntoProfileTable(logSet.U RL, logSet.method, logSet.N ame,
logSet.T ype, logSet.Length, specialCharacters);
16: else
17: compareSet ← compare(logSet, prof ileSet);
18: M ySQL.updateProfileTable(logSet.U RL, compareSet.GET ,
compareSet.P OST , compareSet.OtherM ethods, logSet.N ame, compareSet.T ype,
compareSet.M ax, compareSet.M in, specialCharacters);
19: end if
20: end if
21: end for
22: M ySQL.updateColumnisCheckinLogTable(T rue);
23: end function
CHAPTER 7. IMPLEMENTATION 63

Example log table:

Req URL Method Name Value Type Length ischeck


123 /login.php GET username suthee Latin 6 False
Characters
123 /login.php GET password pass123! All 8 False
123 /login.php GET code 2245 Numeric 4 False
189 /login.php GET username wandi24 Latin 7 False
Characters
& Numeric
189 /login.php GET password qwerty Latin 6 False
Characters
189 /login.php GET code 8989 Numeric 4 False
256 /login.php GET username nforce Latin 5 False
Characters
256 /login.php GET password nF@rc3!! All 8 False
256 /login.php GET code 1057 Numeric 4 False
257 /main.php GET NULL NULL NULL NULL False

Example profile table after digesting the data in the log table:

Allowed
Other
URL GET POST Name Type Max Min Special
Methods
Characters
/login.php True False False username Latin 7 5
Characters
& Numeric
/login.php True False False password All 8 6 !@
/login.php True False False code Numeric 4 4
/main.php True False False NULL NULL NULL NULL NULL
CHAPTER 7. IMPLEMENTATION 64

7.3.3 Suspicious Input Detection

After the profile of the protected web server is ready, in the protection phase, the
profile is used as a set of rules to detect a suspicious input hidden inside the HTTP request
by performing condition matching. That is, the Suspicious Input Detection Engine extracts
necessary information from the HTTP request sent by the web client and compared to the
information in the profile table. If they match, the request will be a legitimate request and
forwarded to the web server. Otherwise, the request will be suspected as an SQL injection
attack and dropped. An alert is generated as well as written on the log file. There are six
categories of the alert including:

• Unauthorized URL Access: The request is sent to the URL that is not found in
the profile.

• Unauthorized Method for Known URL: The method of the request URL does
not match that in the profile.

• Parameter Type Violation: The type of the parameter in the request is different
from that in the profile.

• Unauthorized Special Character for Parameter: The special character inside


the parameter is not found in the allowed special character list in the profile.

• Parameter Value Length Violation: The length of the parameter in the request
is greater or less than that in the profile.

• Unknown Parameter: The request contains a parameter that is not found in the
profile.

The process of the suspicious input detection in details is presented in figure 7.4 and 7.5.
CHAPTER 7. IMPLEMENTATION 65

Figure 7.4: A flowchart of the suspicious input detection 1


CHAPTER 7. IMPLEMENTATION 66

Figure 7.5: A flowchart of the suspicious input detection 2


CHAPTER 7. IMPLEMENTATION 67

From the flowchart, the pseudo code can be written as follows.

Pseudo Code 7 Suspicious Input Detection


1: function isSuspiciousRequest(request)
2: isSuspicious ← 0;
3: parameters<name, value> ← getParameters(request);
4: if parameters.isEmpty() then
5: resultSet ← M ySQL.selectRecordFromProfileTable(request.U RL);
6: if resultSet.isEmpty() then
7: Logger.printLog(“Unauthorized URL Access”, getRequestInformation(request));
8: return TRUE;
9: else
10: if request.method 6= resultSet.method then
11: Logger.printLog(“Unauthorized Method for Known URL”, getRequestInformation(request));
12: return TRUE;
13: end if
14: end if
15: else
16: for each entry in parameters do
17: resultSet ← M ySQL.selectRecordFromProfileTable(request.U RL, parameters.name);
18: if request.method 6= resultSet.method then
19: Logger.printLog(“Unauthorized Method for Known URL”, getRequestInformation(request));
20: return TRUE;
21: end if
22: if parameters.value.length() > resultSet.M ax OR parameters.value.length() < resultSet.M in
then
23: Logger.printLog(“Parameter Value Length Violation”, getRequestInformation(request));
24: isSuspicious++;
25: end if
26: requestV alueT ype ← getValueType(paremeters.value)
27: if requestV alueT ype.isSubsetOf(resultSet.T ype) then
28: sc ← getSpecialCharacterInValue(parameters.value);
29: if !sc.isSubsetOf(resultSet.AllowedSpecialCharacters) then
30: Logger.printLog(“Unauthorized Special Character for Parameter”,
getRequestInformation(request));
31: isSuspicious++;
32: end if
33: else
34: Logger.printLog(“Parameter Type Violation”, getRequestInformation(request));
35: isSuspicious++;
36: end if
37: end for
38: end if
39: if isSuspicious > 0 then
40: return TRUE;
41: else
42: return FALSE;
43: end if
44: end function

This pseudo code will return true of false to the method handleRequest in the TrafficIn-
terceptor class. If it returns true, the TrafficInterceptor will drop the request and return
an error page to the web client. Otherwise, it forwards the request to the destination web
server.

Example HTTP request:


http://www.example.com/login.php?username=admin&password=’ OR ‘1’=‘1&code=a44a
CHAPTER 7. IMPLEMENTATION 68

Extracted information:
URL: /login.php
Method: GET
Parameter #1 (Name, Value, Type, Length): username, admin, Latin characters, 5
Parameter #2 (Name, Value, Type, Length): password, ’ OR ‘1’=‘1, All, 11
Parameter #3 (Name, Value, Type, Length): code, a44a, Latin Characters & Numeric,
4

Profile Table:

Allowed
Other
URL GET POST Name Type Max Min Special
Methods
Characters
/login.php True False False username Latin 7 5
Characters
& Numeric
/login.php True False False password All 8 6 !@
/login.php True False False code Numeric 4 4
/main.php True False False NULL NULL NULL NULL NULL

Expected Result of Detection:

• Unauthorized Special Character for Parameter: the value of the parameter


“password” contains quotes and white space which are not allowed in the profile.

• Parameter Value Length Violation: The length of the parameter “password” is


11 which are more than the maximum length in the profile.

• Parameter Type Violation: The parameter type of “code” is different from that
in the profile.

7.4 Profile Database Module

The Profile Database module is implemented using MySQL database management


system. It collects protected web server’s logs and profiles. The table for logging has a
name ending with -log and the table for collecting the web profile has a name ending with
-profile. The structures of the log table and the profile table are illustrated in figure 7.6
CHAPTER 7. IMPLEMENTATION 69

and 7.7 . Suspicious Input Detection Engine can connect to the tables and read/write the
data using SQL commands.

Figure 7.6: The log table of researchtest.com

Figure 7.7: The profile table of researchtest.com

For security administrators, they can use the phpMyAdmin web application to view
and manage profiles in the database directly. For example, as displayed in figure 7.8, they
could select menu “SQL” to run SQL commands for inserting, updating, or deleting profile
records if they caused false positives. In addition, menu “Export” is allowed for exporting
the profile table in CSV or PDF format so that the security administrator can show it to
the web developer and check the correctness of the profiles. This feature helps the security
administrator to reduce the false positive rate of the proxy.
CHAPTER 7. IMPLEMENTATION 70

Figure 7.8: The user interface of the phpMyAdmin

7.5 Logger Module

Logger module is responsible for displaying system events and alerts on the Java con-
sole, as well as writing them on the log file. This module is implemented using the Logging
API in Java programs [33]. By importing java.util.logging package, the Logger module
is ready to use. Besides, the default log pattern displayed on the log file is customized as
mentioned in 6.6 Logging system, so that everyone can easily understand. Examples of
system event logs and an alert log written on the log file are presented in figure 7.9.

Figure 7.9: An example of the system event logs and the alert logs
CHAPTER 7. IMPLEMENTATION 71

7.6 Classes and Methods

This section will describe all classes and methods that were implemented following the
section 7.1 - 7.5. The ReppSi system consists of four main modules, Reverse Proxy (Lis-
tener, Sender, and Session Manager), Suspicious Input Detection Engine, Profile Database,
and Logger. These modules transform into five Java classes as presented in table 7.1.

Table 7.1: Classes and Methods of the ReppSi System

Package ReppSi
Class: ReverseProxy - Implements Listener, Sender, and Session Manager using the
framework of the Membrane Service Proxy. It is a class for starting the ReppSi’s op-
eration. This class is written by following the pseudo code 1: Proxy Preparation.
There is no method for this class.
Class: TrafficeInterceptor - Implements the Session Manager module using the frame-
work of the Membrane Service Proxy. It is responsible for intercepting the HTTP traffic,
and applying some rules to forward or reject the traffic.
Method Description
Handle the incoming request, and then return
the flow of the request. If it returns “Out-
handleRequest(exchange): Outcome
come.CONTINUE”, the request is forwards to
the destination server. If it returns “Out-
* The exchange parameter
come.RETURN”, it drops the request and starts
collects the information of the
the response process. This method is written by
HTTP request/response pair.
following the pseudo code: 2 HTTP Request
Handling.
Handle the response, and then return the
flow of the response. If it returns “Out-
handleResponse(exchange): come.CONTINUE”, the response is forwards to
Outcome the web client. This method is written by fol-
lowing the pseudo code: 3 HTTP Response
Handling.
isSupportFileType(request): Return true if the request is being sent to the
Boolean dynamic web page. Otherwise, return false.
createErrorResponse(exchange): Generate an error message for returning to the
Void web client.
CHAPTER 7. IMPLEMENTATION 72

getUrl(request): String Return the URL of the request e.g. /login.php.


Class: SuspiciousInputDetectionEngine - Implements the Suspicious Input Detection
Engine. It is the core program of the ReppSi system. Its functions include database
preparing, request logging, profile updating, and anomalous input scanning. Moreover,
it is a class connecting to the MySQL database.
Method Description
Initialize the parameters’ values, and create a
init(): void
connection to the MySQL database.
Prepare SQL statements for updating the profile
initProfiling(): void
table in the database.
Prepare SQL statements for selecting the related
profile record in the database. The profile record
initProtection(): void will be used as a security rule for detecting a sus-
picious user-supplied input that may contain an
SQL injection attack.
Prepare the database to support the operation
of the ReppSi system including profile updating.
prepareDatabase(): void This method is written by following the pseudo
code: 4, 6 Database Preparation and Pro-
file Updating.
Extract and insert the request information into
logRequest(request): void the log table. This method is written by following
the pseudo code: 5 Request Logging.
Return true if the request does not match the
profile. That is, it is suspected as an SQL injec-
isSuspiciousRequest(request):
tion attack. This method is written by following
Boolean
the pseudo code: 7 Suspicious Input Detec-
tion.
getValueType(parameter value):
Return the type of the parameter value.
String
Combine the parameter type 1 with the parame-
getNewType(type1, type2): String
ter type 2, and return the new type.
isSubsetOf(request type, Return true if the type of the request is a subset
profile type): Boolean of the type of the profile. Otherwise, return false.
getUrl(request): String Return the URL of the request e.g. /login.php.
CHAPTER 7. IMPLEMENTATION 73

getAllRequestHeaderFields(request):
Return all header fields of the request.
HeaderField[]
Return the body message of the request. Most of
getRequestBody(request): String
them are parameters of the POST request.
getParameters(request): Return parameter pairs (Name, Value) of the re-
Map<String, String> quest.
getSpecialCharacterInValue(value): Return a list of all special characters in the pa-
String rameter value.
getRequestInformation(request): Return all information of the request. It will be
String used for logging.
Class: TxtLogger - Implements the Logger module. It is a class for displaying system
event messages and alerts on the Java console, as well as writing them on the log file.
Method Description
Display the input message with the severity on
printLog(severity, message): void
the Java console, and write it on the log file
Class: TxtLogFormatter - A part of the Logger module responsible for formatting the
log messages.

* See the installation guide and the user manual of the ReppSi program in Appendix A
and B
Chapter 8

Experiments

To prove the concept of ReppSi and its behaviour-based detection system, they are
planned to test with the Moodle, the University e-Learning system. Unfortunately, due to
the limitation of the Moodle environment, the ReppSi system could not redirect the HTTP
traffic sent to the Moodle web application without disturbing the system. In addition,
testing the ReppSi system in the real environment may cause problems to the students
and the staff. Hence, the proof of the concept will be conducted with the Super Veda web
application.

Super Veda is a demo online shopping application written by Imperva. Users can
perform online purchases of various kinds of products such as books, DVDs, electronic
goods, and so on. The application was developed using JSP and designed to run on
an Apache Tomcat 6.0.18 web service. The data is stored on a MySQL 5.1.39 database
system. This application is vulnerable to many types of web application attacks. It is used
for checking various hacking techniques and web security vulnerabilities exploitation [15].

Experiments in this chapter are divided into three tests, a protection test, a perfor-
mance test, and a false positive test.

8.1 Protection Test

The main objective of the protection test is to measure the ReppSi’s capability of
protecting the web server from SQL injection attacks. The test is divided into two phases,
a learning phase, and a protection phase. In the learning phase, all HTTP requests sent
to the web application will be collected to create a profile. All requests are assumed to be

74
CHAPTER 8. EXPERIMENTS 75

legitimate request without any attack hidden inside. In the protection phase, two different
web vulnerability scanning tools are used to penetrate the ReppSi system. The result will
be compared to that from the environment without the ReppSi system deployed.

8.1.1 Experimental Setup

The network diagram of the protection test is illustrated in figure 8.1. The ReppSi
proxy and the Super Veda web application are running on the same machine, the MacBook
Air with Mac OS X 10.10 Yosemite, under the virtual environment. Both of them are
connected with the virtual switch and connect wirelessly to the web clients. The web
clients can access the Super Veda application by calling http://172.16.1.100:8100/, which
is the hostname of the ReppSi proxy. Then, the ReppSi proxy redirects all HTTP requests
to the Super Veda application, whose hostname is 172.16.1.101.

Figure 8.1: The network diagram of the protection test

8.1.2 Preparation before Testing

ReppSi requires profiles for being used as security rules when inspecting HTTP re-
quests. The profiles can be built from the HTTP requests in the learning phase. The
ReppSi’s operation mode must be set to “Profiling” by selecting mode number “0” on the
ReppSi’s java console to start collecting the information from the HTTP requests. An
example of logging the requests is shown in the next page.
CHAPTER 8. EXPERIMENTS 76

Example requests:
http://172.16.1.100:8100/login.php?username=sutheekit&password=kitcha&code=8989
http://172.16.1.100:8100/login.php?username=suthee&password=nF0rc3!&code=8989
http://172.16.1.100:8100/login.php?username=suthee22&password=1q2w3e4r&code=7550
http://172.16.1.100:8100/login.php?username=thee&password=1234567&code=2222
http://172.16.1.100:8100/login.php?username=sut224&password=1q2w3e4r$R&code=1234

Example log table after logging the requests:

Figure 8.2: An example of the log table after logging HTTP requests

Example profile table built from the log table:

Figure 8.3: An example of the profile table that digested the data from the log table

In this test, 672 HTTP requests from five web clients were collected into the database.
After logging enough information, ReppSi was restarted in order to create and update the
profile table from the data in the log table. Additionally, its operation mode was changed
to “Protection” by selecting mode number “1” on the java console. Now, the ReppSi is
in the protection mode and ready to test. A full detail of the profile table is presented in
Appendix C.3.
CHAPTER 8. EXPERIMENTS 77

8.1.3 Vulnerability Scanning Tools

Two web vulnerability scanning tools, OWASP ZAP and Subgraph Vega, are used to
test the ReppSi system. Similar to scanning the Moodle system in Chapter 5, both of them
are up-to-date software at the testing time (ZAP version 2.3.1 and Vega version 1.0). Each
scanning tool is configured to scan all web vulnerabilities in its list.

8.1.4 Results and Analysis

Before testing with the vulnerability scanners, a few SQL injection attacks were tested
in order to check whether the ReppSi system is operating properly. One of them is a classic
SQL injection attack for unauthorized access to accounts. In the /login.jsp page, there are
two user-supplied inputs for entering the user’s username and password. As presented in
figure 8.4, bypassing the authentication was tested by inputting “mickey” as a username
and “’1 OR ‘1’=‘1” as a password.

Figure 8.4: Bypassing the authentication system using SQL injection

The attack was successful. An attack could log in as “Mickey” without the knowledge
of the password. The result is shown in figure 8.5.
CHAPTER 8. EXPERIMENTS 78

Figure 8.5: The result of bypassing the authentication system using SQL injection

After deploying the ReppSi proxy, this attack was blocked due to the special character
of the password parameter did not match that in the profile. The error page was returned
to the web client as displayed in figure 8.6. Moreover, an alert was generated and written
on the log file as shown in figure 8.7.

Figure 8.6: The error page generated by ReppSi


CHAPTER 8. EXPERIMENTS 79

Figure 8.7: The alert from the log file (See more details of the log file in Appendix C.4)

OWASP ZAP

The summary results of using OWASP ZAP to scan the Super Veda application before
and after implementing the ReppSi proxy are presented in table 8.1 and 8.2 respectively.

Table 8.1: The result of scanning Super Veda by OWASP ZAP before ReppSi deployment
Alert Severity Number of Affected URLs
Cross-Site Scripting (Persistent) High 2
Cross-Site Scripting (Reflected) High 4
Remote OS Command Injection High 1
SQL Injection - Authentication Bypass High 2
SQL Injection - MySQL High 23
Application Error Disclosure Medium 1
X-Frame-Options Header Not Set Medium 58
Cookie Set without HttpOnly Flag Low 14
Password Autocomplete in browser Low 2
Private IP Disclosure Low 1
Web Browser XSS Protection Not Enabled Low 58
X-Content-Type-Options Header Missing Low 58

* See more details of the SQL injection alerts in Appendix C.5


CHAPTER 8. EXPERIMENTS 80

Table 8.2: The result of scanning Super Veda by OWASP ZAP after ReppSi deployment
Alert Severity Number of Affected URLs
SQL Injection High 2
X-Frame-Options Header Not Set Medium 58
Cookie Set without HttpOnly Flag Low 14
Password Autocomplete in browser Low 2
Web Browser XSS Protection Not Enabled Low 58
X-Content-Type-Options Header Missing Low 58

The results show obviously that ReppSi could reduce the number of the SQL injection
attacks from 25 to 2, which is 92 percent blocking rate. That means the information in
the profiles were noticeably different from the patterns of the SQL injection attacks. Only
the SQL injection attacks targeting the /dosearch.jsp page and /register.jsp page could
pass through the ReppSi’s Suspicious Input Detection Engine. However, the log file shows
that the ReppSi system could detect the attacks as presented in figure 8.8 and 8.14. After
rechecking those two SQL injection attacks by penetrating the web application again, it is
found that the ReppSi system could block both attacks. Therefore, it could not summarize
that the ReppSi system was capable of detecting and blocking the SQL injection attacks
only 92 percent.
CHAPTER 8. EXPERIMENTS 81

Figure 8.8: A comparison between the OWASP ZAP’s log and the ReppSi’s log for
/dosearch.jsp

Figure 8.9: A comparison between the OWASP ZAP’s log and the ReppSi’s log for /regis-
ter.jsp
CHAPTER 8. EXPERIMENTS 82

To find the cause why the log file indicates that the ReppSi system could block the
attacks but the result of the OWASP ZAP, in contrast, shows that the attacks could pass
through the ReppSi, the program and the log file were analyzed. After an investigation,
some records in the log file were discovered that there were many SQL exceptions generated
during the test. All exceptions were created by the suspicious input detection part of the
source code as illustrated in figure 8.10.

Figure 8.10: A comparison between the SQL exception and the source code

As displayed in figure 8.10, the SQL exception states that the operation of the source
code line number 459 was not allowed because the resultSet had closed. However, it is
impossible for the resultSet to close at that line since it was just assigned the values from
selecting the profile records from the database at the line number 457. When considering
the fact that the ReppSi proxy actually could block the pass-through attacks, it is deduced
that the concept of ReppSi with the behaviour-based detection can block all types of
SQL injection attacks generated by the OWASP ZAP. Nonetheless, the incompleteness
CHAPTER 8. EXPERIMENTS 83

of the program causes the SQL exceptions, leading to the incapability of detecting or
blocking some attacks. As a result, the attacks could pass through the ReppSi system and
compromised the protected web server.

The root cause of the SQL exceptions is assumed that the SuspiciousInputDetectio-
nEngine class for detecting the SQL injection attacks does not support multi-threading.
Even though the Membrane Service Proxy supports multi-threading, the whole program
shares the same database connection pool. When the program handles the request gen-
erated more than 200 requests per second by the OWASP ZAP, it might cause errors.
According to several tests, the numbers of the SQL exceptions were varied. They were
in the range of 213 - 256 from 3723 - 3789 of all requests, while the pass-through SQL
injection attacks were around 2 - 4 as shown in table 8.3.

* The log files from these tests also show that all pass-through attacks were detected by
the ReppSi system.

Table 8.3: The number of the OWASP ZAP requests, the SQL exceptions generated, and
the SQL injection attacks that pass through the ReppSi system
Number of SQL Number of Pass-through
Test # Number of Attacks
Exceptions SQL Injection Attacks
1 3775 256 (6.78%) 3
2 3723 239 (6.42%) 2
3 3757 213 (5.67%) 2
4 3789 241 (6.36%) 4
5 3761 219 (5.82%) 2

In addition to the SQL injection attacks, the ReppSi could detect and prevent other
kinds of web vulnerabilities such as Cross-Site Scripting and Remote OS Command Injec-
tion. These vulnerabilities, like SQL injection, are required some special characters e.g.
“<”, “>”, “;” to launch the attacks. Therefore, if the user-supplied input does not support
these characters, in other words, does not match the profile, the attacks will be blocked
automatically.

Another useful feature that raises the security level of the web server is the ReppSi’s
error page. The error page will be returned to the web client if the suspicious request is de-
tected. Additionally, if the status code of the response is an error 4xx or 5xx, the response
will be replaced by the error page in order to conceal the sensitive server information. As
displayed in table 8.2, after using the ReppSi system, the Application Error Disclosure alert
CHAPTER 8. EXPERIMENTS 84

is disappeared.

Subgraph Vega

The summary results of using Subgraph Vega to scan the Super Veda application are
presented in table 8.4 and 8.5.

Table 8.4: The summary result of scanning Super Veda using Subgraph Vega before ReppSi
deployment
Alert Severity Number of Affected URLs
Cleartext Password over HTTP High 2
Session Cookie Without Secure Flag High 1
Session Cookie Without HttpOnly Flag High 1
Cross-Site Scripting High 2
MySQL Error Detected High 8
SQL Injection High 9
Page Fingerprint Differential Detected High 5
Java Debug Output Detected Medium 10
Possible XMP Injection Medium 1
Form Password Field with Autocomplete
Low 2
Enabled
Cookie HttpOnly Flag Not Set Info 1
Character Set Not Specified Info 5
Blank Body Detected Info 1

* See more details of the SQL injection alerts in Appendix C.6


CHAPTER 8. EXPERIMENTS 85

Table 8.5: The summary result of scanning Super Veda using Subgraph Vega after ReppSi
deployment
Alert Severity Number of Affected URLs
Cleartext Password over HTTP High 2
Session Cookie Without Secure Flag High 1
Session Cookie Without HttpOnly Flag High 1
Form Password Field with Autocomplete
Low 2
Enabled
Character Set Not Specified Info 5

The results present that the ReppSi system could prevent all SQL injection attacks
generate by Subgraph Vega. Different from OWASP ZAP, there was not any SQL exception
generated by the program while scanning since Subgraph Vega launched the attacks only
around 4 - 5 requests per second. Hence, the database connection pool could manage its
resources properly.

Like the OWASP ZAP’s result, ReppSi could eliminate other kinds of attacks such as
Cross-Site Scripting and Possible XML Injection, and help the protected web server from
the leakage of sensitive server information. As shown in the table 8.4.and 8.5., ReppSi
also patched the Page Fingerprint Differential Detected and Java Debug Output Detected
vulnerabilities by its error page feature.

8.2 Performance Test

The objective of the performance test is to check the impact on the system environment
when implementing the ReppSi proxy. The impact can be determined by the process time
of the ReppSi system including the process time of the request and the process time of the
response. Both the process times will be compared between four cases.

1. No ReppSi. HTTP traffic is directly transmitted between the web client and the web
server.

2. Only Membrane Service Proxy with default configuration running as a reverse proxy
(The ReppSi without Suspicious Input Detection Engine)

3. ReppSi running in the learning phase (The operation mode is “Profiling”.)


CHAPTER 8. EXPERIMENTS 86

4. ReppSi running in the protection phase (The operation mode is “Protection”.)

The first case is a baseline case. The second one is to check the impact of the pure
Membrane Service Proxy. The third one is to check the impact of the ReppSi system when
logging the HTTP requests into the database. And the last one is to check the impact
when inspecting the HTTP requests for suspicious inputs. Each case will collect two sets
of data, the process time of the request and the process time of the response, from more
than 500 HTTP requests/responses. Each of them will include the maximum process time,
the minimum process time, and the average process time. An average response time (start
when the HTTP request is sent from the web client and finish when the client receives the
response) is also collected to see the overall impact of the ReppSi system.

8.2.1 Experimental Setup

The performance test has the same setup as the protection test.

8.2.2 Results and Analysis

Table 8.6: The summary results of the performance test


Process time of handling Process time of handling Response Time
HTTP requests (millisecond) HTTP responses (millisecond) (millisecond)
Case
Max Min Average Max Min Average Average
1 0 0 0 0 0 0 46.83
2 18 <1 1.67 <1 <1 0.2 49.05
3 22 <1 1.89 14 <1 1.72 50.80
4 39 <1 3.82 10 <1 0.36 51.31

As presented in table 8.6, case #4 has the highest average process time of the request
(3.82 ms). It is because all HTTP requests in case #4 must have been compared to the
profiles selected from the database. The bigger the profile table was, the longer time the
process spent. On the other hand, case #3 has the highest average process time of the
response (1.72 ms). When ReppSi handled the HTTP responses in the learning phase, most
of the HTTP requests were inserted into the database in order to create the comprehensive
profiles. Connecting to the database led to the delay in the process. For the average process
time of the request in case #3 (1.89 ms) and the average process time of the response in case
CHAPTER 8. EXPERIMENTS 87

#4 (0.36 ms), they are not quite different from case #2 (1.67 ms and 0.2 ms respectively).
Both of them are a little bit higher since the ReppSi system needed to check some conditions
before forwarding the traffic to the destination as shown on the source code in figure 8.11.

Figure 8.11: The source code of handling the HTTP request/response

The average process time of the request in the protection phase (3.82 ms) and the
average process time of the response in the learning phase (1.72 ms) are significantly higher
than those of the pure reverse proxy without the suspicious input detection system (1.67
ms and 0.2 ms respectively). However, when comparing all average response time of the
four cases, the maximum difference of the average response time of case #1 and case #4
is only 4.48 milliseconds that are very short. More importantly, in the real world, most
web clients connect to the web application via the Internet. The average response time
over the Internet is mostly in seconds. As displayed in figure 8.12, an example of browsing
the Moodle e-learning system from London shows that the response time is 1.279 seconds.
As a result, the 4.48-millisecond delay may not cause the user to notice the impact of the
CHAPTER 8. EXPERIMENTS 88

ReppSi system.

Figure 8.12: The response time of browsing the Moodle service from London [48]

Nevertheless, the performance test was performed with Super Veda, a tiny online
shopping application. The profile database is very small, leading to the very short process
time. In the case of enterprise-level web application, its profile database will be dramatically
larger than that of Super Veda. The delay caused by the database connection for selecting
the related profiles will be huge. Therefore, it is recommended that a system for caching
the profiles be developed, as well as the algorithm for searching the profiles be improved.

8.3 False Positive Test

The false positive test was performed after the protection test. The test used the same
experimental setup with the same profile database as the protection test. The objective of
this test is to check whether other normal HTTP requests apart from the attacks can pass
through the ReppSi system without being blocked. More than 500 legitimate requests from
five web clients were inspected by the ReppSi system. The result is shown in table 8.7.

Table 8.7: The result of the false positive test


Number of Requests Wrongly Blocked Request Affected URLs
531 1 /register.jsp
CHAPTER 8. EXPERIMENTS 89

There was only one legitimate request blocked by the ReppSi system. After checking
the log file, two alerts related to the /register.jsp page were generated as presented in figure
8.13. The ReppSi system blocked the request because unauthorized special characters had
been found in the parameter “Password1” and “Password2”. Both of them were the user-
supplied input for entering the user’s password in the process of registration as illustrated in
figure 8.14. The alert log also shows that the allowed special characters of those parameters
only consisted of “;”, “$”, and “!” whereas the input, “T3tht@lkth@!”, contained “@”.
Consequently, the ReppSi system identified the request as an attack.

Figure 8.13: The false positive alerts generated by ReppSi


CHAPTER 8. EXPERIMENTS 90

Figure 8.14: The /register.jsp page that caused the false positives

To solve the false positive problem, the security administrator is recommended to


check and modify the related profile records in the MySQL database using phpMyAdmin.
In this case, the AllowedSpecialCharacters column of the records should be updated to allow
“@” sign. Figure 8.15 and 8.16 shows the related profile records and the SQL command to
update them.
CHAPTER 8. EXPERIMENTS 91

Figure 8.15: The profile records that caused the false positives

Figure 8.16: The SQL command for updating the profile records

8.4 summary

All three tests shows the results as expected. Even though there is a problem from the
SQL exception when testing with OWASP ZAP, more than 90% of the SQL injection attacks
were detected and blocked by ReppSi. While scanning the Super Veda application with
Subgraph Vega, it could prevent all SQL injection attacks. In addition to the SQL injection
attacks, ReppSi managed to detect and block many types of web attacks, such as remote
OS command injection, cross-site scripting, and the leakage of sensitive server information
through error messages, thanks to the comprehensive profiles the ReppSi system collected
from the learning phase. Nevertheless, the profiles were not perfect, leading to the false
positive found when using the web application normally. The security administrator is
CHAPTER 8. EXPERIMENTS 92

recommended to review and modify the related profile in order to solve this problem.

Super Veda is a tiny web application for online shopping. The profile is easy to collect
and does not require a large amount of time for the learning phase. In contrast, enterprise-
level websites require huge database systems and time for building the profiles. The HTTP
requests in the learning phase might contain not only the legitimate requests but also the
bad requests. Consequently, profile reviewing process would be difficult and consumed high
man-hours. Incompleteness of the profiles may lead to being incapable of blocking SQL
injection attacks and a high false positive rate. It is recommended to deploy ReppSi with
other security systems such as an intrusion prevention system or a web application firewall in
order to comprehensively detect all kinds of SQL injection attacks. This recommendation
follows the defense-in-depth concept that helps the security administrator to strengthen
the application security. Furthermore, the high false positive rate could be minimized by
using the simulation mode, another operation mode apart from the profiling mode and the
protection mode. The simulation mode is capable of detecting all suspicious HTTP traffic
in the same way as the protection mode. However, it will not block any traffic even if it is
an attack. This mode is designed for checking the results when using the ReppSi system in
the protection mode. If false positives are spotted, the security administrator can modify
the related profiles before changing to the protection mode and beginning blocking the
suspicious traffic. The simulation mode is planned to implement in the future.
Chapter 9

Limitations and Future Work

This chapter describes limitations of both usability and security of the ReppSi system,
as well as suggestions for future improvement.

9.1 Limitations

ReppSi is developed to prove the concept of the behaviour-based detection specifically


for inspecting suspicious HTTP traffic. It might be capable of preventing many kinds of
attacks, but its primary goal is to prevent SQL injection attacks. ReppSi is a Java-base
reverse proxy application designed for educational purposes, not for commercial purposes.
That is, there are some limitations of using the program. First of all, it could protect only
one web application at a time although the Membrane Service Proxy supports multiple
destination hosts concurrently. Nonetheless, supporting only one destination host is not a
problem for proof of the concept. Secondly, as mentioned in Section 8.1 Protection Test,
ReppSi does not support multi-threading. In other words, the number of HTTP requests
per second is limited. The result of the OWASP ZAP scanning shows that it could not
handle the HTTP traffic more than 200 requests per second. This number is very low for
using in the real world environment. Finally, the user interface is not as user-friendly as
commercial proxies or well-known open source proxies. The user has to input parameters
via the command line, i.e. the Java console. Additionally, the output (the history log) is
written on a text file that is more difficult to read than the GUI.

The essential limitation of the behaviour-based detection is the learning phase. All
HTTP requests in the learning phase must be legitimate without any malicious code or

93
CHAPTER 9. LIMITATIONS AND FUTURE WORK 94

attack hidden inside. A great number of the legitimate requests lead to comprehensive
profiles that can detect anomalous web usage effectively with the low false positive rate.
Nevertheless, there are some cases that even though the profiles are built from an abundance
of the legitimate requests, the ReppSi system cannot detect SQL injection attacks. That is,
the profiles contain characters that allow the user to input SQL commands. For instance,
the parameter “password” has the parameter type “All” and special parameters allowed
for this parameter consist of “ ‘ ” (quote), “ = ” (equal sign), and “ ” (white space).
It is a norm for the password to have these special characters. As a result, if the user
enters “’ OR ‘1’=‘1” into the user-supplied input, the ReppSi system will not detect the
request as an SQL injection attack and will forward the request to the web server. The
solution for preventing this problem is that the web developer needs to limit the special
character allowed for the parameter. In the case that the web developer cannot control
the user-supplied input and the profile record led to the false negative cannot be modified,
it is recommended that other security mechanisms be implemented to cooperate with the
ReppSi system in preventing the SQL injection attacks.

9.2 Future Work

The ultimate goal of ReppSi is to be deployed in the University system so that it can
protect the online services from being attacked. Therefore, the multi-threading problem is
the first task to be solved. ReppSi should support at least 400 HTTP requests per second
so that it can be implemented in the University system and run without any problem. The
next task is that the program will be written to support multiple destination hosts in order
to protect important web services such as the library’s system and the registration system
at the same time. Moreover, GUI should be designed to help the security administrator
to easily view and manage the ReppSi’s system. After eliminating all limitations of the
ReppSi, the proxy will be tested with the Moodle e-learning system in the real environment
in order to confirm that it can protect the Moodle from SQL injection attacks.

For the performance of the ReppSi, the result of the performance test shows that the
average process time is very low (less than 5 milliseconds) compared to the response time
over the Internet. Nevertheless, due to the small size of the tested web server, the program
and the algorithm for logging and searching the data in the database might be altered to
improve the performance in the future.

For security features, the current version of the ReppSi system creates the profiles
from URLs and parameters in the HTTP request. The next version is planned to add
CHAPTER 9. LIMITATIONS AND FUTURE WORK 95

cookies to the profiles so that the ReppSi system can detect attacks that exploit the cookie
vulnerability such as cookie injection and cookie tampering. Furthermore, due to the fact
that the application source code contains the HTML forms used to collect user input (pa-
rameters), and the database structure collects the type as well as the maximum length of
the parameter, an approach for automatically creating the basic profiles from the applica-
tion source code and the database structure might be considered to reduce the time of the
learning phase. The basic profiles can use to filter some bad HTTP requests while learning
as well.
Chapter 10

Conclusion

In this research, a security assessment of the University’s e-learning system, Moodle,


and the concept of a reverse proxy running a behavior-based detection system for protect-
ing web applications from SQL injection attacks are presented. The first version of the
reverse proxy implemented to demonstrate the concept is called ReppSi (Reverse Proxy for
Preventing SQL Injection).

The assessment of the Moodle system presents that although there are some SQL
injection vulnerabilities discovered in the previous versions of the Moodle template, they
have not been found in the University’s Moodle service, thanks to the developers and the
system administrators who take care of it. However, it does not mean there are no SQL
vulnerabilities existing in the Moodle system. According to the concept of defense-in-
depth, the University’s system should have multi-layered security mechanisms so that if
an attack causes any security mechanism to fail, other mechanisms can still provide the
necessary mechanism to protect the system. Hence, the University’s system should have
an additional security system to prevent SQL injection attacks. This is the main objective
of this research.

There are many pieces of research about SQL injection prevention, but most of them
require application code modification or are deployed in the middle between a web server
and a database server. These conditions lead to an inability to implement in some environ-
ments. Therefore, ReppSi, the SQL injection prevention system designed in this research,
is deployed in front of the web server as a reverse proxy and does not need to modify the
application code. An approach used to detect SQL injection attacks of the ReppSi system
is based on the behavior-based detection. The operation is divided into two phases, the
learning phase and the protection phase. In the learning phase, the behavior-based de-

96
CHAPTER 10. CONCLUSION 97

tection system collects the characteristics of using the web application such as URLs that
the users accessed, patterns, and length of the user-supplied inputs. After that, in the
protection phase, it creates profiles as security rules to detect unauthorized (anomalous)
web usage, for example, an SQL injection attack hidden inside the HTTP request.

ReppSi is a pure Java-based reverse proxy application that can run on major operating
systems such as Windows, Mac OS X, and Linux. It uses the Membrane Service Proxy
framework to implement the reverse proxy function and uses MySQL database to store the
profiles of the protected web server. The security administrator can view and manage the
profiles using phpMyAdmin. In addition, ReppSi provides a logging system that collects
system events and alerts into a text file so that the security administrator can check the
history logs and create a security report.

ReppSi was tested by being installed in front of Super Veda, a vulnerable web ap-
plication written by Imperva. All HTTP requests sent to Super Veda were redirected to
ReppSi in order to scan for SQL injection attacks before being forwarded to the destina-
tion. OWASP ZAP and Subgraph Vega, web vulnerability scanning tools, were used to
check whether ReppSi could detect and prevent SQL injection attacks targeting the web
application or not. The results show that ReppSi could detect all kinds of the SQL in-
jection attacks generated by both scanners, but it could prevent only 92 percent of the
attacks from OWASP ZAP. It is because the ReppSi’s prevention system did not support
multi-threading so it could not handle the attacks more than 200 requests per second from
OWASP ZAP at the same time. In contrast, it could prevent 100 percent of the SQL injec-
tion attacks generated by Subgraph Vega. Apart from the SQL injection attacks, ReppSi
was capable of detecting and blocking other kinds of attacks such as cross-site scripting
and remote OS command injection. These attacks, like SQL injection attacks, required re-
quest’s parameters to inject the command code. Due to the comprehensive profiles ReppSi
collected from the learning phase, it could detect the malicious code inside the parameter
value effectively. Nonetheless, the profiles were not perfect, leading to one false positive
found when performing the false positive test. The security administrator is recommended
to review and modify the related profile in order to solve this problem. In short, a successful
rate of detecting the attacks and a false positive rate depend on correctness and accuracy
of the profiles. Additionally, for the performance issue, the delay caused by the ReppSi
system is very short compared to the average response time of the HTTP request. The
user may not notice the impact of the ReppSi system.

The ReppSi’s source code will be modified to support multi-threading in the future.
GUI is also designed to make the management user-friendly. Furthermore, the security
CHAPTER 10. CONCLUSION 98

features will be improved to assure that the profiles collected in the learning phase come
from legitimate HTTP requests. After that, it will be tested with the Moodle system in
the University’s environment in order to prove that the ReppSi system can protect the
University’s online services from SQL injection attacks.
Bibliography

[1] Acunetix, (2014). Web Applications: What are They? What of Them?. [online]
Acunetix. Available at: http://www.acunetix.com/websitesecurity/web-applications/
[Accessed 9 Apr. 2015].

[2] Bandhakavi, S., Bisht, P., Madhusudan, P. and Venkatakrishnan, V. (2007).


CANDID: Preventing Sql Injection Attacks Using Dynamic Candidate Evaluations.
In: Proceedings of the 14th ACM Conference on Computer and Communications
Security. [online] New York, NY, USA: ACM, pp.12-24. Available at:
http://doi.acm.org/10.1145/1315245.1315249 [Accessed 12 Apr. 2015].

[3] Boyd, S. and Keromytis, A. (2004). SQLrand: Preventing SQL Injection Attacks.
Springer Berlin Heidelberg, [online] 3089, pp.292-302. Available at:
http://dx.doi.org/10.1007/978-3-540-24852-1 21 [Accessed 10 Apr. 2015].

[4] Buehrer, G., Weide, B. and Sivilotti, P. (2005). Using Parse Tree Validation to
Prevent SQL Injection Attacks. In: Proceedings of 5th International Workshop on
Software Engineering and Middleware. [online] ACM, pp.106-113. Available at:
http://doi.acm.org/10.1145/1108473.1108496 [Accessed 13 Apr. 2015].

[5] Burleson, D. (1999). Oracle SAP Administration.

[6] Christensen, A., Moller, A. and Schwartzbach, M. (2003). Precise Analysis of String
Expressions. In: Proceedings of the 10th International Conference on Static Analysis.
[online] Berlin, Heidelberg: Springer-Verlag, pp.1-18. Available at:
http://dl.acm.org/citation.cfm?id=1760267.1760269.

[7] Cisco, (2013). Understanding SQL Injection. [online] Cisco. Available at:
http://www.cisco.com/web/about/security/intelligence/sql injection.html [Accessed
15 Apr. 2015].

99
BIBLIOGRAPHY 100

[8] Curtis, S. (2012). Barclays: 97 percent of data breaches still due to SQL injection.
[online] Techworld. Available at: http://www.techworld.com/news/security/barclays-
97-percent-of-data-breaches-still-due-sql-injection-3331283/ [Accessed 10 Apr.
2015].

[9] CVE Details, (2015). Moodle : Security vulnerabilities. [online] CVE Details.
Available at:
http://www.cvedetails.com/vulnerability-list/vendor id-2105/opsqli-1/Moodle.html
[Accessed 9 Apr. 2015].

[10] Det Centrale Personregister, (2013). Executive Order on the Civil Registration
System Act. CPR Civil Registration System Act.

[11] EPIC, (2014). National ID and the REAL ID Act. [online] Electronic Privacy
Information Center. Available at: https://epic.org/privacy/id cards/ [Accessed 8
Apr. 2015].

[12] Halfond, W. and Orso, A. (2005). AMNESIA: Analysis and Monitoring for
NEutralizing SQL-injection Attacks. In: Proceedings of the 20th IEEE/ACM
international Conference on Automated software engineering. [online] pp.174-183.
Available at: http://doi.acm.org/10.1145/1101908.1101935 [Accessed 11 Apr. 2015].

[13] Halfond, W., Orso, A. and Manolios, P. (2006). Using Positive Tainting and
Syntax-aware Evaluation to Counter SQL Injection Attacks. In: Proceedings of the
14th ACM SIGSOFT International Symposium on Foundations of Software
Engineering. [online] New York, USA: ACM, pp.175-185. Available at:
http://doi.acm.org/10.1145/1181775.1181797 [Accessed 11 Apr. 2015].

[14] Halfond, W., Viegas, J. and Orso, A. (2006). A Classification of SQL-Injection


Attacks and Countermeasures. In: Proceedings of the International Symposium on
Secure Software Engineering. [online] IEEE. Available at:
http://www-bcf.usc.edu/ halfond/papers/halfond06issse.pdf [Accessed 15 Apr. 2015].

[15] Imperva, (2004). Application Penetration Test Super Veda. [online] Imperva, pp.8-9.
Available at: http://www.cgisecurity.com/lib/VedaPenetrationTest.pdf [Accessed 10
Apr. 2015].

[16] INSEE, (n.d.). National Directory for the Identification of Natural Persons /
RNIPP. [online] National Institute of Statistics and Economic Studies. Available at:
http://www.insee.fr/en/methodes/default.asp?page=definitions/rnipp.htm [Accessed
8 Apr. 2015].
BIBLIOGRAPHY 101

[17] International Telecommunication Union, (2014). The World in 2014: ICT Facts and
Figures. [online] International Telecommunication Union, p.5. Available at:
http://www.itu.int/en/ITU-D/Statistics/Documents/facts/ICTFactsFigures2014-
e.pdf [Accessed 8 Apr.
2015].

[18] Java, (2015). Learn about Java Technology. [online] Available at:
http://www.java.com/en/about/ [Accessed 22 Aug. 2015].

[19] Johari, R. and Sharma, P. (2012). A Survey on Web Application Vulnerabilities


(SQLIA, XSS) Exploitation and Security Engine for SQL Injection. In:
Communication Systems and Network Technologies (CSNT), 2012 International
Conference on. [online] IEEE, pp.453-458. Available at:
http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6200667 [Accessed 15
Apr. 2015].

[20] Kemalis, K. and Tzouramanis, T. (2008). SQL-IDS: A Specification-based Approach


for SQL-injection Detection. In: Proceedings of the 2008 ACM Symposium on
Applied Computing. [online] New York, NY, USA: ACM, pp.2153-2158. Available at:
http://doi.acm.org/10.1145/1363686.1364201 [Accessed 12 Apr. 2015].

[21] Kerner, S. (2013). How Was SQL Injection Discovered?. [online] eSecurity Planet.
Available at: http://www.esecurityplanet.com/network-security/how-was-sql-
injection-discovered.html [Accessed 9 Apr.
2015].

[22] Kindy, D. and Pathan, A. (2011). A survey on SQL injection: Vulnerabilities,


attacks, and prevention techniques. In: Consumer Electronics (ISCE), 2011 IEEE
15th International Symposium on. [online] IEEE, pp.468-471. Available at:
http://ieeexplore.ieee.org/xpls/abs all.jsp?arnumber=5973873 [Accessed 14 Apr.
2015].

[23] Logan, B. (2007). Keeping Up. [online] Facebook. Available at:


https://www.facebook.com/notes/facebook/keeping-up/7899307130 [Accessed 8 Apr.
2015].

[24] Lungu, I., Velicanu, M. and Botha, I. (2009). Database Systems - Present and
Future. Informatica Economica, [online] 13(1), pp.84-99. Available at:
http://search.ebscohost.com/login.aspx?direct=true&db=bth&AN=38011631&site=ehost-
live.
BIBLIOGRAPHY 102

[25] Martin, B., Brown, M., Paller, A. and Kirby, D. (2011). CWE -2011 CWE/SANS
Top 25 Most Dangerous Software Errors. [online] Common Weakness Enumeration.
Available at: http://cwe.mitre.org/top25/index.html [Accessed 10 Apr. 2015].

[26] MathJax, (2015). MathJax. [online] Available at: https://www.mathjax.org/


[Accessed 21 Aug. 2015].

[27] Microsoft, (2015). Structured Query Language (SQL). [online] MSDN - Dev Center.
Available at: https://msdn.microsoft.com/en-
gb/library/windows/desktop/ms714670(v=vs.85).aspx [Accessed 8 Apr.
2015].

[28] Moodle, (2011). Security:SQL injection. [online] Moodle. Available at:


https://docs.moodle.org/dev/Security:SQL injection [Accessed 9 Apr. 2015].

[29] Moodle, (2015). Features. [online] Moodle. Available at:


https://docs.moodle.org/28/en/Features [Accessed 9 Apr. 2015].

[30] NAA, (2015). Benefits of digital information and records. [online] National Archives
of Australia. Available at: http://www.naa.gov.au/records-management/digital-
transition-policy/benefits-of-digital-information.aspx [Accessed 8 Apr.
2015].

[31] National Security Agency Attention, (2009). Defense in Depth. National Security
Agency Attention, pp.1-3.

[32] NHS, (2015). Your health records. [online] The NHS in England - NHS Choices.
Available at:
http://www.nhs.uk/nhsengland/thenhs/records/healthrecords/pages/overview.aspx
[Accessed 8 Apr. 2015].

[33] Oracle, (2015). Class Logger. [online] Java Platform, Standard Edition 7. Available
at: http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html
[Accessed 22 Aug. 2015].

[34] OWASP, (2013). The Ten Most Critical Web Application Security Risks. OWASP
Top 10 - 2013. [online] OWASP, pp.6-7. Available at:
http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%202013.pdf
[Accessed 12 Apr. 2015].

[35] OWASP, (2014). SQL Injection. [online] OWASP. Available at:


https://www.owasp.org/index.php/SQL Injection [Accessed 15 Apr. 2015].
BIBLIOGRAPHY 103

[36] OWASP, (2015). List of useful HTTP headers. [online] OWASP. Available at:
https://www.owasp.org/index.php/List of useful HTTP headers [Accessed 20 Aug.
2015].

[37] OWASP, (2015). OWASP Zed Attack Proxy Project. [online] OWASP. Available at:
https://www.owasp.org/index.php/OWASP Zed Attack Proxy Project [Accessed 10
Apr. 2015].

[38] Ponniah, P. (2003). Database design and development. Piscataway, NJ: Wiley-IEEE
Press.

[39] Predic8, (2015). Message Interceptors. [online] Membrane Service Proxy. Available
at: http://membrane-soa.org/service-proxy-doc/4.0/interceptors.htm [Accessed 22
Aug. 2015].

[40] SREO, (2013). Frequently Asked Questions (FAQs). [online] Student Records &
Examinations Office. Available at:
http://www.bath.ac.uk/student-records/faq/index.html#s03 [Accessed 9 Apr. 2015].

[41] Su, Z. and Wassermann, G. (2006). The Essence of Command Injection Attacks in
Web Applications. In: the 33rd ACM SIGPLAN-SIGACT Symposium on Principles
of Programming Languages. [online] ACM, pp.372–82. Available at:
http://doi.acm.org/10.1145/1111037.1111070 [Accessed 11 Apr. 2015].

[42] Subgraph, (2014). Vega Vulnerability Scanner. [online] Subgraph. Available at:
https://subgraph.com/vega/index.en.html [Accessed 10 Apr. 2015].

[43] Tajpour, A. and JorJor Zade Shooshtari, M. (2010). Evaluation of SQL Injection
Detection and Prevention Techniques. In: Computational Intelligence,
Communication Systems and Networks (CICSyN), 2010 Second International
Conference on. [online] IEEE, pp.216-221. Available at:
http://ieeexplore.ieee.org/xpls/abs all.jsp?arnumber=5615711&tag=1 [Accessed 13
Apr. 2015].

[44] University of Bath, (2015). Library Services. [online] The Library & Learning Centre.
Available at: http://www.bath.ac.uk/library/services/ [Accessed 9 Apr. 2015].

[45] Valeur, F., Mutz, D. and Vigna, G. (2005). A Learning-Based Approach to the
Detection of SQL Attacks. Detection of Intrusions and Malware, and Vulnerability
Assessment, [online] pp.123-140. Available at:
http://dl.acm.org/citation.cfm?id=2144860 [Accessed 11 Apr. 2015].
BIBLIOGRAPHY 104

[46] Verizon, (2014). 2014 Data Breach Investigations Report. [online] Verizon, pp.3-4.
Available at: http://www.verizonenterprise.com/DBIR/2014/reports/rp Verizon-
DBIR-2014 en xg.pdf [Accessed 13 Apr.
2015].

[47] Wassermann, G. and Su, Z. (2004). An Analysis Framework for Security in Web
Applications. In: Specification and Verification of Component-Based Systems. [online]
pp.70-78. Available at:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.137.7225 [Accessed 10
Apr. 2015].

[48] Web Page Test, (2015). Web Page Performance Test for moodle.bath.ac.uk. [online]
Available at: http://www.webpagetest.org/result/150830 BN K4H/1/details/
[Accessed 30 Aug. 2015].
Appendix A

Installation Guide

ReppSi is a Java-based reverse proxy application. The application supports many


operating systems such as Windows, Mac OS X, and Linux with Java Virtual Machine
installed. A Java IDE, such as Eclipse or NetBeans, with Java SE Development Kits
version 7 or higher is recommended to run the application. In addition, MySQL database
management system is required to store HTTP request logs and profiles. The process of
installation is as follows.

A.1 MySQL Installation

1. Download and install MAMP software package from https://www.mamp.info/en/


downloads/

2. Browse the phpMyAdmin application and create a database for collecting the logs
and the profiles data.

A.2 ReppSi Installation

1. Download the Membrane Proxy Service Framework version 4.0.18 from http://
mirror.predic8.com/membrane/router/membrane-service-proxy-4.0.18.zip

2. Unzip the file, and then locate the JAR file in the library directory
%MEMBRANE HOME/lib.

105
APPENDIX A. INSTALLATION GUIDE 106

Figure A.1: The library files of the Membrane Proxy Service

3. Open the Java IDE and create a project name as desired.

4. Create a package name “ReppSi”. Then, import the source code from Appendix D
into the package. There are five classes, ReverseProxy.java, SuspiciousInputDetec-
tionEngine.java, TrafficInterceptor.java, TxtLogFormatter.java, and TxtLogger.java.
(Or import ReppSi.jar from the attached CD into your project.)

Figure A.2: The hierarchy of the ReppSi project

5. Include the libraries from %MEMBRANE HOME/lib in the CLASSPATH or add it


as a Maven dependency.
APPENDIX A. INSTALLATION GUIDE 107

Figure A.3: Java build path that the Membrane libraries have been already imported

6. Configure the Membrane proxy by opening the ReverseProxy.java

• At line 19, change listenPort to the listen port of the machine (default is 8100)
• At line 23 and 24, change targetHost and targetPort to the protected web server
IP/domain name and port
• Then, compile the java file.
APPENDIX A. INSTALLATION GUIDE 108

Figure A.4: Membrane proxy configuration

7. Configure the MySQL connection by opening the SuspiciousInputDetectionEngine.java.


At line 45, change the database URL, username, and password to those that have
been configured in the MySQL installation. Then, compile the java file.

Figure A.5: MySQL connection configuration

8. Configure the location of the log file by opening TxtLogger.java. At line 31, change
the file location as desired. Then, compile the java file.

Figure A.6: Logger configuration

Now, the ReppSi system is ready.


Appendix B

User Manual

After installation, there are some parameters needed to configure. The parameters
include the listen port of the machine running ReppSi, the protected web server IP/domain
name and port, the MySQL connection, and the location of the log file. See more details
in Appendix A.2 ReppSi Installation (Step 6 - 8).

B.1 Running the ReppSi System

The operation of the ReppSi system can be started by running ReverseProxy.java.


After that, the java console shows the status of the protected web server and the database,
as well as asks the user to input the operation mode.

• Type “0”, and then press Enter to select Profiling mode

• Type “1”, and then press Enter to select Protection mode

Figure B.1: The Java console prompts the user for the operation mode

109
APPENDIX B. USER MANUAL 110

Now, the ReppSi system is running and ready to handle HTTP requests from the web
clients.

The operation can be stopped by pressing the Terminate button on the top right of
the Java console.

* It is recommended to run ReppSi in the Profiling mode at the first time so that it can
collect HTTP requests. When ReppSi collects enough the HTTP requests (the more, the
better), the ReppSi system is required to be restarted in order to update the profiles. Then,
change the operation mode to “1” Protection mode. Now, the ReppSi system is ready to
protect the web server.

B.2 MySQL Database Management

The log tables and the profile tables in the MySQL database can be viewed and
managed using the phpMyAdmin web application. It is available as long as the MAMP
application is running. The default phpMyAdmin page can be accessed via this URL:
http://localhost:8888/MAMP/index.php?page=phpmyadmin&language=English.

Figure B.2: The phpMyAdmin’s main page

Each protected web server possesses two tables, the log table and the profile table.
The log table is the one whose name ends with -log. The profile table is the one whose
name ends with -profile.
APPENDIX B. USER MANUAL 111

• Select the table to view the data inside.

• Select “SQL” tab to input an SQL command in order to modify the data such as
update the data in the profile table.

• Select “Export” tab to export the data in CSV or PDF format.

B.3 Viewing the Log File

The log file is located at the file path you configured in step 8, Appendix A.2 ReppSi
Installation. A text editor application such as Notepad or TextEdit can be used to view
the log file. An example of the log file is shown in figure B.3.
APPENDIX B. USER MANUAL 112

Figure B.3: An example of the log file


Appendix C

Raw Results Output

C.1 The Moodle E-learning System Vulnerability Scanning


by OWASP ZAP

The result of using OWASP ZAP to scan the Moodle e-learning system is presented in
table C.1. The version of the software is 2.3.1 which is the latest version of the assessment
time. It is configured to scan all types of the web vulnerabilities.

Table C.1: Summary result of scanning moodle.bath.ac.uk by OWASP ZAP


Number of False
Alert Severity
Affected URLs Positive
X-Frame-Options Header Not Set Medium 37 No
Cookie Set without HttpOnly Flag Low 6 No
Cross-Domain JavaScript Source File Inclusion Low 2 No
Web Browser XSS Protection Not Enabled Low 37 No
X-Content-Type-Options Header Missing Low 35 No

X-Frame-Options Header Not Set

Severity: Medium

Definition by OWASP [37]: X-Frame-Options header is not included in the HTTP


response to protect against “ClickJackin” attacks.

113
APPENDIX C. RAW RESULTS OUTPUT 114

Solution by OWASP [37]: Most web browsers in the present support the X-Frame-
Options HTTP header. The developer should ensure that it is set on all web pages returned
by the developer’s site. If the developer expects the page to be framed only by pages on
the developer’s server (e.g. it is part of a FRAMESET) then the developer needs to set the
header as SAMEORIGIN, otherwise if the developer never expects the page to be framed,
the developer should set DENY. ALLOW-FROM allows specific websites to frame the web
page in supported web browsers.

Affected URLs:

1. http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML

2. http://cdn.mathjax.org/mathjax/latest/config/TeX-AMS-MML_HTMLorMML.js?rev=
2.5.3

3. http://moodle.bath.ac.uk/

4. http://moodle.bath.ac.uk/blocks/bath_oue/stats.php?username=sk914

5. http://moodle.bath.ac.uk/lib/javascript.php/-1/blocks/bath_oue/js/module.
js

6. http://moodle.bath.ac.uk/lib/javascript.php/-1/lib/javascript-static.js

7. http://moodle.bath.ac.uk/lib/javascript.php/1435681425/blocks/course_overview/
module.js

8. http://moodle.bath.ac.uk/lib/javascript.php/1435681425/lib/javascript-static.
js

9. http://moodle.bath.ac.uk/login/logout.php?sesskey=2Ip9Ixv3xj

10. http://moodle.bath.ac.uk/login/logout.php?sesskey=HlSnsofSqb

11. http://moodle.bath.ac.uk/login/logout.php?sesskey=f5jFI7mpmN

12. http://moodle.bath.ac.uk/my/

13. http://moodle.bath.ac.uk/theme/javascript.php/bath_bootstrap/1435681425/
footer

14. http://moodle.bath.ac.uk/theme/styles.php/bath_bootstrap/1435681425/all
APPENDIX C. RAW RESULTS OUTPUT 115

15. http://moodle.bath.ac.uk/theme/yui_combo.php?3.13.0/anim-base/anim-base-
min.js&3.13.0/anim-color/anim-color-min.js&3.13.0/anim-xy/anim-xy-min.
js&3.13.0/anim-curve/anim-curve-min.js&3.13.0/anim-easing/anim-easing-
min.js&3.13.0/anim-node-plugin/anim-node-plugin-min.js&3.13.0/anim-scroll/
anim-scroll-min.js

16. http://moodle.bath.ac.uk/theme/yui_combo.php?3.13.0/anim-base/anim-base-
min.js&3.13.0/anim-color/anim-color-min.js&3.13.0/anim-xy/anim-xy-min.
js&3.13.0/anim-curve/anim-curve-min.js&3.13.0/anim-easing/anim-easing-
min.js&3.13.0/anim-node-plugin/anim-node-plugin-min.js&3.13.0/anim-scroll/
anim-scroll-min.js&3.13.0/datatype-xml-parse/datatype-xml-parse-min.js&
3.13.0/io-xdr/io-xdr-min.js&3.13.0/io-form/io-form-min.js&3.13.0/io-upload-
iframe/io-upload-iframe-min.js&3.13.0/queue-promote/queue-promote-min.
js&3.13.0/io-queue/io-queue-min.js&3.13.0/matrix/matrix-min.js&3.13.0/
graphics/graphics-min.js&3.13.0/cookie/cookie-min.js&3.13.0/graphics-svg-
default/graphics-svg-default-min.js&3.13.0/graphics-svg/graphics-svg-min.
js

17. http://moodle.bath.ac.uk/theme/yui_combo.php?3.13.0/cssbutton/cssbutton-
min.css

18. http://moodle.bath.ac.uk/theme/yui_combo.php?3.13.0/plugin/plugin-min.js&
3.13.0/event-mousewheel/event-mousewheel-min.js&3.13.0/event-resize/event-
resize-min.js&3.13.0/event-hover/event-hover-min.js&3.13.0/event-touch/
event-touch-min.js&3.13.0/event-move/event-move-min.js&3.13.0/event-flick/
event-flick-min.js&3.13.0/event-valuechange/event-valuechange-min.js&3.
13.0/event-tap/event-tap-min.js

19. http://moodle.bath.ac.uk/theme/yui_combo.php?m/1435681425/block_navigation/
navigation/navigation-min.js

20. http://moodle.bath.ac.uk/theme/yui_combo.php?m/1435681425/core/lockscroll/
lockscroll-min.js&m/1435681425/core/notification/notification-alert-min.
js&m/1435681425/core/notification/notification-confirm-min.js&m/1435681425/
core/notification/notification-exception-min.js&m/1435681425/core/notification/
notification-ajaxexception-min.js&m/1435681425/core/notification/notification-
min.js&3.13.0/cache-base/cache-base-min.js&m/1435681425/core/popuphelp/
popuphelp-min.js
APPENDIX C. RAW RESULTS OUTPUT 116

21. http://moodle.bath.ac.uk/theme/yui_combo.php?m/1435681425/core/lockscroll/
lockscroll-min.js&m/1435681425/core/notification/notification-alert-min.
js&m/1435681425/filter_glossary/autolinker/autolinker-min.js

22. http://moodle.bath.ac.uk/theme/yui_combo.php?m/1435681425/core/notification/
notification-confirm-min.js&m/1435681425/core/notification/notification-
exception-min.js&m/1435681425/core/notification/notification-ajaxexception-
min.js&m/1435681425/core/notification/notification-min.js&3.13.0/cache-
base/cache-base-min.js&m/1435681425/core/popuphelp/popuphelp-min.js

23. http://moodle.bath.ac.uk/theme/yui_combo.php?m/1435681425/theme_bootstrapbase/
bootstrap/bootstrap-min.js

24. http://moodle.bath.ac.uk/theme/yui_combo.php?rollup/-1/mcore-min.js

25. http://moodle.bath.ac.uk/theme/yui_combo.php?rollup/1435681425/mcore-min.
js

26. http://moodle.bath.ac.uk/theme/yui_combo.php?rollup/3.13.0/yui-moodlesimple-
min.css

27. http://moodle.bath.ac.uk/theme/yui_combo.php?rollup/3.13.0/yui-moodlesimple-
min.js

28. http://www.bath.ac.uk/common/css/global.css?colour=internal&template=page&
columns=2

29. http://www.bath.ac.uk/common/css/print.css?columns=2

30. http://www.bath.ac.uk/common/js/editpage.php

31. http://www.bath.ac.uk/common/js/exploreBar.js

32. http://www.bath.ac.uk/common/js/jquery-1.8.2.min.js

33. http://www.bath.ac.uk/common/js/pdftracking.js

34. http://www.bath.ac.uk/web/guides/sso/

35. http://www.bath.ac.uk/web/tools/sso/

36. http://www.google-analytics.com/analytics.js

37. http://www.google-analytics.com/ga.js
APPENDIX C. RAW RESULTS OUTPUT 117

Example alert of http://moodle.bath.ac.uk/

Figure C.1: The X-Frame-Options Header Not Set alert of http://moodle.bath.ac.uk/

Figure C.2: The request header of the alert

Figure C.3: The response header of the alert


APPENDIX C. RAW RESULTS OUTPUT 118

Cookie Set without HttpOnly Flag

Severity: Low

Description by OWASP [37]: A cookie has been configured without the HttpOnly flag.
That is, the cookie can be accessed by JavaScript. If an attacker runs a malicious script on
this page, the cookie will be accessible and can be transmitted to another site. Similarly,
if it is a session cookie, session hijacking might be occurred.

Solution by OWASP [37]: The developer needs to ensure that the HttpOnly flag is set
for all cookies.

Affected URLs:

1. http://moodle.bath.ac.uk/

Figure C.4: The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.uk/

2. http://moodle.bath.ac.uk/login/logout.php?sesskey=2Ip9Ixv3xj

Figure C.5: The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.uk/
login/logout.php?sesskey=2Ip9Ixv3xj
APPENDIX C. RAW RESULTS OUTPUT 119

3. http://moodle.bath.ac.uk/login/logout.php?sesskey=HlSnsofSqb

Figure C.6: The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.uk/
login/logout.php?sesskey=HlSnsofSqb

4. http://moodle.bath.ac.uk/login/logout.php?sesskey=f5jFI7mpmN

Figure C.7: The Cookie Set without HttpOnly Flag alert of http://moodle.bath.ac.uk/
login/logout.php?sesskey=f5jFI7mpmN
APPENDIX C. RAW RESULTS OUTPUT 120

5. http://www.bath.ac.uk/common/css/print.css?columns=2

Figure C.8: The Cookie Set without HttpOnly Flag alert of http://www.bath.ac.uk/
common/css/print.css?columns=2

6. http://www.bath.ac.uk/web/tools/sso/

Figure C.9: The Cookie Set without HttpOnly Flag alert of http://www.bath.ac.uk/
web/tools/sso/
APPENDIX C. RAW RESULTS OUTPUT 121

Example alert of http://moodle.bath.ac.uk/

Figure C.10: The request header of the alert

Figure C.11: The response header of the alert

Cross-Domain JavaScript Source File Inclusion

Severity: Low

Description by OWASP [37]: The pages of the affected URLs include one or more
script files from a third-party domain.

Solution by OWASP [37]: The developer needs to ensure that JavaScript source files
are loaded from only trusted sources, and the sources cannot be controlled by end users of
the application.

Affected URLs:
APPENDIX C. RAW RESULTS OUTPUT 122

1. http://moodle.bath.ac.uk/

Figure C.12: The Cross-Domain JavaScript Source File Inclusion alert of http://moodle.
bath.ac.uk/

Figure C.13: The response body of for the alert


APPENDIX C. RAW RESULTS OUTPUT 123

2. http://moodle.bath.ac.uk/my/

Figure C.14: The Cross-Domain JavaScript Source File Inclusion alert of http://moodle.
bath.ac.uk/my/

Figure C.15: The response body of the alert

Web Browser XSS Protection Not Enabled

Severity: Low

Description by OWASP [37]: Web Browser XSS Protection is not enabled or is disabled
by the configuration of the “X-XSS-Protection” HTTP response header on the web server.

Solution by OWASP [37]: The developer needs to ensure that the web browser’s XSS
filter is enabled, by setting the X-XSS-Protection HTTP response header to “1”.

Affected URLs: The same URLs as C.1 X-Frame-Options Header Not Set.
APPENDIX C. RAW RESULTS OUTPUT 124

Example alert of http://moodle.bath.ac.uk/

Figure C.16: The Web Browser XSS Protection Not Enabled alert of http://moodle.
bath.ac.uk/

Figure C.17: The request header of the alert

Figure C.18: The response header of the alert


APPENDIX C. RAW RESULTS OUTPUT 125

X-Content-Type-Options Header Missing

Severity: Low

Description by OWASP [37]: The “X-Content-Type-Options”, an Anti-MIME-Sniffing


header, was not set to “nosniff”. This allows older versions of Google Chrome and Internet
Explorer to perform MIME-sniffing on the response body, potentially causing the response
body to be interpreted and displayed as a content type other than the declared content
type.

Solution by OWASP [37]: The developer needs to ensure that the web application sets
the Content-Type header appropriately. That is, sets the X-Content-Type-Options header
to “nosniff” for all web pages.

Affected URLs: The same URLs as C.1 X-Frame-Options Header Not Set. Except http:
//www.bath.ac.uk/web/guides/sso/ and http://www.bath.ac.uk/web/tools/sso/

Example alert of http://moodle.bath.ac.uk/

Figure C.19: The X-Content-Type-Options Header Missing alert of http://moodle.bath.


ac.uk/

Figure C.20: The request header of the alert


APPENDIX C. RAW RESULTS OUTPUT 126

Figure C.21: The response header of the alert

C.2 The Moodle E-learning System Vulnerability Scanning


by Subgraph Vega

The result of using Subgraph Vega to scan the Moodle e-learning system is presented
in table C.2. The version of the software is 1.0 which is the latest version of the assessment
time. It is configured to scan all types of the web vulnerabilities.

Table C.2: Summary result of scanning moodle.bath.ac.uk by Subgraph Vega


Number of False
Alert Severity
Affected URLs Positive
Cleartext Password over HTTP High 1 No
Cross-Site Script Include High 26 No
Integer Overflow High 1 Yes
Page Fingerprint Differential Detected High 2 Yes
Local Filesystem Paths Found Medium 4 No
Directory Listing Detected Low 21 Yes
Email Addresses Found Low 26 No
Cookie HttpOnly Flag Not Set Info 1 No
X-Frame-Options Header Not Info 46 No
APPENDIX C. RAW RESULTS OUTPUT 127

Cleartext Password over HTTP

Severity: High

Description by Vega [42]: A form with a password user-supplied input is submitted


over an insecure channel (HTTP). This vulnerability could cause unauthorized disclosure
of passwords to attackers.

Solution by Vega [42]: Passwords should never be sent in the cleartext across unen-
crypted channel. The form should submit to an HTTPS target.

Affected URLs: http://moodle.bath.ac.uk/course/enrol/index.php

Figure C.22: The Cleartext Password over HTTP alert of http://moodle.bath.ac.uk/


enrol/index.php

Figure C.23: The source code of http://moodle.bath.ac.uk/enrol/index.php

Cross-Site Script Include

Severity: High

Description by Vega [42]: The content on a web server is including JavaScript file from
an unrelated domain. When this script code is fetched by a user browser and loaded into
the DOM, it will have complete control over the DOM, bypassing the protection offered
by the same-origin policy. Even if the source of the script code is trusted by the website
APPENDIX C. RAW RESULTS OUTPUT 128

operator, malicious code could be introduced if the server is ever compromised.

Solution by Vega [42]: It is strongly recommended that web servers should host their
own JavaScript locally, especially for critical applications.

Affected URLs:

Figure C.24: 26 affected URLs of the Cross-Site Script Include alerts


APPENDIX C. RAW RESULTS OUTPUT 129

Example alert of http://moodle.bath.ac.uk/

Figure C.25: The Cross-Site Script Include alert of http://moodle.bath.ac.uk/

Figure C.26: The response body of the alert

Integer Overflow

Severity: High

Description by Vega [42]: Integer overflow is a kind of buffer overflow which occur when
an integer data type exceeds its maximum value. When it occurs in programs written in
languages such as C, it contributes to security implications. For instance, unsigned integers
will be reduced, result in wrapping back to a lower numeric value. The consequence on
security depends on how the integer value is used. If it is used as the size of a data buffer,
it may lead to bypassing of size checks.
APPENDIX C. RAW RESULTS OUTPUT 130

Solution by Vega [42]: The developer should investigate the error and determine if a
vulnerability is present.

Affected URLs: http://moodle.bath.ac.uk/course/course/search.php

Figure C.27: The Integer Overflow of http://moodle.bath.ac.uk/course/search.php

Figure C.28: The request header of the alert

* This is a false positive alert.

Page Fingerprint Differential Detected

Severity: High

Description by Vega [42]: A different response page fingerprint in relation to a local file
include injection request was detected. This means that the response page content returned
by the web application has a different signature from that returned by an ordinary request,
which may indicate the existence of a local file include vulnerability. Local file includes
vulnerabilities are present when externally-supplied input is used to specify the location
APPENDIX C. RAW RESULTS OUTPUT 131

of a local filesystem resource that is requested by the web application. The differing page
fingerprint may include error messages or indicate a state change in the application in
response to the local file include injection attempt made by Vega. Differing responses may
also be indicative of a file enumeration vulnerability, which would allow an attacker to
determine if specific files exist on the system. Developers should examine the response
content and underlying code to verify whether or not a vulnerability is present. If the
vulnerability exists and precautions are not taken, such a vulnerability could allow attackers
to gain unauthorized access to sensitive information contained in local files, which may also
be leveraged in further attacks on the web application.

Solution by Vega [42]: To prevent this type of vulnerability, the developer should canon-
icalize the path of any filesystem resource that has a path composed of externally-supplied
input and then perform an authorization check prior to access. For example, the real-
path() library call will return the canonical path of the resource for PHP, Perl, and Python
programming.

Affected URLs:

1. http://moodle.bath.ac.uk/course/search.php

Figure C.29: The Page Fingerprint Differential Detected of http://moodle.bath.ac.uk/


course/search.php
APPENDIX C. RAW RESULTS OUTPUT 132

2. http://moodle.bath.ac.uk/course/view.php

Figure C.30: The Page Fingerprint Differential Detected of http://moodle.bath.ac.uk/


course/view.php

* These are false positive alerts.

Local Filesystem Paths Found

Severity: Medium

Description by Vega [42]: A possible absolute filesystem path (i.e. one that is not
relative to the web root) was detected. This information is sensitive, as it may reveal things
about the server environment to an attacker. Knowing filesystem layout can increase the
chances of success for blind attacks.

Solution by Vega [42]: Full system paths are very often found in error output. This
output should never be sent to clients on production systems. It should be redirected
to another output channel (such as an error log) for analysis by developers and system
administrators.
APPENDIX C. RAW RESULTS OUTPUT 133

Affected URLs:

1. http://moodle.bath.ac.uk/

Figure C.31: The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/

Figure C.32: The response body of the alert


APPENDIX C. RAW RESULTS OUTPUT 134

2. http://moodle.bath.ac.uk/lib/javascript.php/-1/lib/javascript-static.js

Figure C.33: The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/


lib/javascript.php/-1/lib/javascript-static.js

Figure C.34: The response body of the alert


APPENDIX C. RAW RESULTS OUTPUT 135

3. http://moodle.bath.ac.uk/my/

Figure C.35: The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/my/

Figure C.36: The response body of the alert


APPENDIX C. RAW RESULTS OUTPUT 136

4. http://moodle.bath.ac.uk//theme/yui_combo.php

Figure C.37: The Local Filesystem Paths Found alert of http://moodle.bath.ac.uk/


/theme/yui_combo.php

Figure C.38: The response body of the alert

Directory Listing Detected

Severity: Low

Description by Vega [42]: Listing directory contents when no index file is present in
a common misconfiguration. The directory contents can provide useful information to an
attacker, especially if there are files that are not meant to be accessible, such as source code
or backups. The directory listing may also provide useful information about the habits of
APPENDIX C. RAW RESULTS OUTPUT 137

the server administration and/or web developers, such as file naming convention, that could
be used to increase the probable success of brute-force or other attacks.

Solution by Vega [42]: For Apache, add “IndexIgnore *” to the directory’s .htaccess
file, or alternatively remove “Indexes” from the line “Options All Indexes FollowSymLinks
MultiViews” in the Apache configuration file. For lighttpd, change “dir-listing.activate”
parameter from “enable” to “disable” in the lighttpd configuration file.

Affected URLs:

Figure C.39: 21 affected URLs of the Directory Listing Detected alerts


APPENDIX C. RAW RESULTS OUTPUT 138

Example alert of http://moodle.bath.ac.uk/blog/index.php

Figure C.40: The Directory Listing Detected alert of http://moodle.bath.ac.uk/blog/


index.php

* These are false positive alerts.

Email Addresses Found

Severity: Low

Description by Vega [42]: Patterns that resemble email addresses in scanned content
were found. These may be user the addresses of system users, addresses inserted in user-
supplied content, or third-party addresses embedded in components of the application (such
as JavaScript libraries). Automatically scraping websites is one way that spammers and
phishers collect email addresses for their distribution lists.

Solution by Vega [42]: It is recommended that email addresses not be displayed on


exposed parts of the web application, directly or indirectly.
APPENDIX C. RAW RESULTS OUTPUT 139

Affected URLs:

Figure C.41: 26 affected URLs of the Email Addresses Found alerts


APPENDIX C. RAW RESULTS OUTPUT 140

Example alert of http://moodle.bath.ac.uk/course/view.php

Figure C.42: The Email Addresses Found alert of http://moodle.bath.ac.uk/course/


view.php

Figure C.43: The response body of the alert

Cookie HttpOnly Flag Not Set

Severity: Information

Description by Vega [42]: Vega has detected that this cookie was set without the
HttpOnly flag. When this flag is not present, it is possible to access the cookie via client-
side script code.

Solution by Vega [42]: The HttpOnly flag is a security measure that can help mitigate
the risk of cross-site scripting attacks that target session cookies of the victim. If the
HttpOnly flag is set and the browser supports this feature, attacker-supplied script code
will not be able to access the cookie.
APPENDIX C. RAW RESULTS OUTPUT 141

Affected URLs: http://moodle.bath.ac.uk/

Figure C.44: The Cookie HttpOnly Flag Not Set alert of http://moodle.bath.ac.uk/

Figure C.45: The response header of the alert

X-Frame-Options Header Not Set

Severity: Information

Description by Vega [42]: Vega has detected that the resource has not set the X-Frame-
Options HTTP response header. This header allows the resource to specify its policy with
regards to whether it may be included in frames in other domains as well as which domains
are allowed. When the header has been set, this may help to mitigate clickjacking attacks
APPENDIX C. RAW RESULTS OUTPUT 142

against browsers that support this feature. If the header has not been set, the affected
resource may be used in clickjacking attacks.

Solution by Vega [42]: Set the X-Frame-Options header to DENY, SAMEORIGIN, or


ALLOW-FROM according to policy.

Affected URLs:

Figure C.46: 46 affected URLs of the X-Frame-Options Header Not Set alerts
APPENDIX C. RAW RESULTS OUTPUT 143

Example alert of http://moodle.bath.ac.uk/

Figure C.47: The X-Frame-Options Header Not Set alert of http://moodle.bath.ac.uk/

Figure C.48: The request header of the alert

Figure C.49: The response header of the alert


APPENDIX C. RAW RESULTS OUTPUT 144

C.3 The Profile Table of the Super Veda Application

As shown in figure C.50 and C.51, the complete profile table was built from 672 HTTP
requests in the learning phase.

Figure C.50: The profile table of the Super Veda application 1


APPENDIX C. RAW RESULTS OUTPUT 145

Figure C.51: The profile table of the Super Veda application 2

C.4 Example of the Log File

Figure C.52 presents an example of the log file generated by the ReppSi system.
APPENDIX C. RAW RESULTS OUTPUT 146

Figure C.52: An example of the log file generated by the ReppSi system
APPENDIX C. RAW RESULTS OUTPUT 147

C.5 The SQL injection alerts of the Super Veda application


Scanned by OWASP ZAP (Before)

Before implementing ReppSi, there are two kinds of SQL injection vulnerabilities found
on the Super Veda application, SQL Injection - Authentication Bypass and SQL Injection
- MySQL. While scanning, the IP address of Super Veda was 172.16.1.101.

C.5.1 SQL Injection - Authentication Bypass

Affected URLs: http://172.16.1.101/login.jsp

Figure C.53: The SQL Injection - Authentication Bypass alert of Super Veda 1

Figure C.54: The SQL Injection - Authentication Bypass alert of Super Veda 2
APPENDIX C. RAW RESULTS OUTPUT 148

C.5.2 SQL Injection - MySQL

Affected URLs:

1. http://172.16.1.101/add2cart.jsp

2. http://172.16.1.101/addcomment.jsp

3. http://172.16.1.101/dosearch.jsp

4. http://172.16.1.101/login.jsp

5. http://172.16.1.101/proddetails.jsp

6. http://172.16.1.101/showproducts.jsp

7. http://172.16.1.101/postcomment.jsp

8. http://172.16.1.101/register.jsp

Example alert of http://172.16.1.101/postcomment.jsp

Figure C.55: The SQL Injection - MySQL alert of Super Veda


APPENDIX C. RAW RESULTS OUTPUT 149

Figure C.56: The response body of the SQL Injection - MySQL alert

C.6 The SQL injection alerts of the Super Veda application


Scanned by Subgraph Vega (Before)

There are also two kinds of SQL injection vulnerabilities found on the Super Veda
application by Subgraph Vega before ReppSi deployment including MySQL Error Detected
- Possible SQL Injection and SQL Injection.

C.6.1 MySQL Error Detected - Possible SQL Injection

Description by Vega [42]: Vega has detected a SQL error string known to be output by
MySQL. This can indicate a possible SQL injection vulnerability. These vulnerabilities are
present when externally-supplied input is used to construct a SQL query. If precautions are
not taken, the externally-supplied input (usually a GET or POST parameter) can modify
the query string such that it performs unintented actions. These actions include gaining
unauthorized read or write access to the data stored in the database, as well as modifying
the logic of the application.

Affected URLs:

1. http://172.16.1.101/addcomment.jsp

2. http://172.16.1.101/dosearch.jsp

3. http://172.16.1.101/login.jsp
APPENDIX C. RAW RESULTS OUTPUT 150

4. http://172.16.1.101/postcomment.jsp

5. http://172.16.1.101/proddetails.jsp

6. http://172.16.1.101/recoverpasswordsend.jsp

7. http://172.16.1.101/showproducts.jsp

Example alert of http://172.16.1.101/showproducts.jsp

Figure C.57: The MySQL Error Detected - Possible SQL Injection alert of Super Veda

Figure C.58: The response body of the MySQL Error Detected - Possible SQL Injection
alert
APPENDIX C. RAW RESULTS OUTPUT 151

C.6.2 SQL Injection

Description by Vega [42]: Vega has detected a possible SQL injection vulnerability.
These vulnerabilities are present when externally-supplied input is used to construct a
SQL query. If precautions are not taken, the externally-supplied input (usually a GET or
POST parameter) can modify the query string such that it performs unintented actions.
These actions include gaining unauthorized read or write access to the data stored in the
database, as well as modifying the logic of the application.

Affected URLs:

1. http://172.16.1.101/addcomment.jsp

Figure C.59: The SQL Injection alert of /addcomment.jsp


APPENDIX C. RAW RESULTS OUTPUT 152

2. http://172.16.1.101/dosearch.jsp

Figure C.60: The SQL Injection alert of /dosearch.jsp

3. http://172.16.1.101/login.jsp

Figure C.61: The SQL Injection alert of /login.jsp 1


APPENDIX C. RAW RESULTS OUTPUT 153

Figure C.62: The SQL Injection alert of /login.jsp 2

Figure C.63: The SQL Injection alert of /login.jsp 3


APPENDIX C. RAW RESULTS OUTPUT 154

4. http://172.16.1.101/postcomment.jsp

Figure C.64: The SQL Injection alert of /postcomment.jsp

5. http://172.16.1.101/proddetails.jsp

Figure C.65: The SQL Injection alert of /proddetails.jsp


APPENDIX C. RAW RESULTS OUTPUT 155

6. http://172.16.1.101/recoverpasswordsend.jsp

Figure C.66: The SQL Injection alert of /recoverpasswordsend.jsp

7. http://172.16.1.101/showproducts.jsp

Figure C.67: The SQL Injection alert of /showproducts.jsp


Appendix D

Source Code

This section presents Java source code of the ReppSi system that consists of five classes
including:

• ReverseProxy.java

• TrafficInterceptor.java

• SuspiciousInputDetectionEngine.java

• TxtLogger.java

• TxtLogFormatter.java

156
APPENDIX D. SOURCE CODE
D.1 ReverseProxy.java System . out . p r i n t ( ” O p e r a t i o n Mode ( P r o f i l i n g = 0 ,
Protection = 1) : ” ) ;
try {
package ReppSi ; S t r i n g i n p u t = br . r e a d L i n e ( ) ;
while ( ! i n p u t . e q u a l s ( ” 0 ” ) && ! i n p u t . e q u a l s ( ” 1 ” ) ) {
import j a v a . i o . B u f f e r e d R e a d e r ; System . out . p r i n t ( ”Wrong i n p u t . P l e a s e e n t e r t h e
import j a v a . i o . IOException ; o p e r a t i o n mode a g a i n : ” ) ;
import j a v a . i o . InputStreamReader ; i n p u t = br . r e a d L i n e ( ) ;
}
import com . p r e d i c 8 . membrane . c o r e . HttpRouter ; mode = I n t e g e r . p a r s e I n t ( i n p u t ) ;
import com . p r e d i c 8 . membrane . c o r e . r u l e s . S e r v i c e P r o x y ; } catch ( NumberFormatException e1 ) {
import com . p r e d i c 8 . membrane . c o r e . r u l e s . S e r v i c e P r o x y K e y ; e1 . p r i n t S t a c k T r a c e ( ) ;
} catch ( IOException e1 ) {
public c l a s s ReverseProxy { e1 . p r i n t S t a c k T r a c e ( ) ;
}
public f i n a l s t a t i c TxtLogger LOGGER = new TxtLogger ( ) ; i f ( mode == 0 ) LOGGER. p r i n t L o g ( TxtLogger . INFO ,
” O p e r a t i o n Mode : P r o f i l i n g ” ) ;
public s t a t i c void main ( S t r i n g [ ] a r g s ) { e l s e LOGGER. p r i n t L o g ( TxtLogger . INFO , ” O p e r a t i o n
Mode : P r o t e c t i o n ” ) ;
// l i s t e n i n g p o r t o f t h e p r o x y
int l i s t e n P o r t = 8100; // i n i t i a l c o n f i g u r a t i o n o f t h e p r o x y
S e r v i c e P r o x y K e y key = new S e r v i c e P r o x y sp = new S e r v i c e P r o x y ( key , t a r g e t H o s t ,
ServiceProxyKey ( l i s t e n P o r t ) ; targetPort ) ;
sp . g e t I n t e r c e p t o r s ( ) . add (new
// t a r g e t h o s t t h a t t h e p r o x y w i l l f o r w a r d t r a f f i c t o T r a f f i c I n t e r c e p t o r ( mode , t a r g e t H o s t , s i d e ) ) ;
String targetHost = ” 172.16.1.101 ” ;
int t a r g e t P o r t = 8 0 ; HttpRouter r o u t e r = new HttpRouter ( ) ;
LOGGER. p r i n t L o g ( TxtLogger . INFO , ” P r o t e c t e d Web try {
Server : ” + targetHost + ” : ” + targetPort ) ; r o u t e r . add ( sp ) ;
router . i n i t () ;
S u s p i c i o u s I n p u t D e t e c t i o n E n g i n e s i d e = new } catch ( E x c e p t i o n e ) {
SuspiciousInputDetectionEngine ( targetHost ) ; e . printStackTrace () ;
side . init () ; }
}
// c h o o s e mode : P r o f i l i n g = 0 , P r o t e c t i o n = 1
i n t mode = 0 ; }
B u f f e r e d R e a d e r br = new B u f f e r e d R e a d e r (new

157
InputStreamReader ( System . i n ) ) ;
APPENDIX D. SOURCE CODE
D.2 TrafficInterceptor.java i f ( mode == 1 ) {
// i n s p e c t o n l y t h e s e r v e r −s i d e programming r e q u e s t
i f ( i s S u p p o r t F i l e T y p e ( exchange . g e t R e q u e s t ( ) ) ) {
package ReppSi ; // i f t h e r e q u e s t i s s u s p i c i o u s , b l o c k t h e
r e q u e s t and r e t u r n an e r r o r page
import com . p r e d i c 8 . membrane . c o r e . exchange . Exchange ; i f ( s i d e . i s S u s p i c i o u s R e q u e s t ( exchange . g e t R e q u e s t ( ) ,
import com . p r e d i c 8 . membrane . c o r e . h t t p . Header ; exchange . getRemoteAddrIp ( ) ) ) {
import com . p r e d i c 8 . membrane . c o r e . h t t p . Request ; c r e a t e E r r o r R e s p o n s e ( exchange ) ;
import com . p r e d i c 8 . membrane . c o r e . h t t p . Response ; return Outcome .RETURN;
import }
com . p r e d i c 8 . membrane . c o r e . h t t p . Response . R e s p o n s e B u i l d e r ; }
import }
com . p r e d i c 8 . membrane . c o r e . i n t e r c e p t o r . A b s t r a c t I n t e r c e p t o r ; return Outcome .CONTINUE;
import com . p r e d i c 8 . membrane . c o r e . i n t e r c e p t o r . Outcome ; }

public c l a s s T r a f f i c I n t e r c e p t o r extends // h a n d l e t h e h t t p r e s p o n s e
AbstractInterceptor { @Override
public Outcome h a n d l e R e s p o n s e ( Exchange exchange ) {
// o p e r a t i o n mode ( P r o f i l i n g = 0 , P r o t e c t i o n = 1) // l e a r n i n g p h a s e − l o g r e q u e s t s
private i n t mode ; i f ( mode == 0 ) {
// i f t h e r e q u e s t g e t 200 or 300 r e s p o n s e code and
private S u s p i c i o u s I n p u t D e t e c t i o n E n g i n e s i d e ; u s e s s e r v e r −s i d e programming , l o g t h e r e q u e s t
for creating a profile
public T r a f f i c I n t e r c e p t o r ( i n t mode , S t r i n g // i g n o r e s t a t i c page such as html , j p g , png , mp3 ,
protectedServer , SuspiciousInputDetectionEngine mp4 , e t c .
side ) { i f ( exchange . g e t R e s p o n s e ( ) . g e t S t a t u s C o d e ( ) < 400 &&
super ( ) ; i s S u p p o r t F i l e T y p e ( exchange . g e t R e q u e s t ( ) ) ) {
t h i s . mode = mode ; // l o g r e q u e s t s t o t h e d a t a b a s e and u p d a t e
this . s i d e = s i d e ; profiles
s i d e . l o g R e q u e s t ( exchange . g e t R e q u e s t ( ) ) ;
i f ( mode == 0 ) s i d e . i n i t P r o f i l i n g ( ) ; }
else side . i n i t P r o t e c t i o n () ; }
} // p r o t e c t i o n p h a s e − r e t u r n an e r r o r page i f s t a t u s
code = 4 xx or 5 xx
// h a n d l e t h e h t t p r e q u e s t else {
@Override i f ( exchange . g e t R e s p o n s e ( ) . g e t S t a t u s C o d e ( ) >= 4 0 0 ) {
public Outcome h a n d l e R e q u e s t ( Exchange exchange ) {

158
c r e a t e E r r o r R e s p o n s e ( exchange ) ;
// p r o t e c t i o n p h a s e
APPENDIX D. SOURCE CODE
} margin−top : 10 px ; } ”
} + ”p { c o l o r : #505761; f o n t −s i z e : 12 px ;
return Outcome .CONTINUE; f o n t −f a m i l y : \” Lucida Grande \ ” , A r i a l ,
} sans − s e r i f ; f o n t −w e i g h t : normal ; margin−top :
1 0 ; l i n e −h e i g h t : 20 px ; } ”
// c h e c k w h e t h e r t h e r e q u e s t u s e s s e r v e r −s i d e + ” h1 { c o l o r : #505761; f o n t −s i z e : 30 px ;
programming f o n t −f a m i l y : \” Lucida Grande \ ” , A r i a l ,
// t h i s p r o x y s u p p o r t s asp , aspx , j s p , php , and j s sans − s e r i f ; f o n t −w e i g h t : b o l d ; l e t t e r −s p a c i n g :
private boolean i s S u p p o r t F i l e T y p e ( Request r e q u e s t ) { 0px ; width : auto ; } ”
String url = getUrl ( request ) ; + ” h2 { c o l o r : #505761; f o n t −s i z e : 16 px ;
i f ( u r l . matches ( ” ( ˆ / . + \ \ . ( asp | aspx | j s p | php | j s ) $ ) | ( ˆ / [ ˆ \ \ . ] ∗ ) ” ) ) f o n t −f a m i l y : \” Lucida Grande \ ” , A r i a l ,
return true ; sans − s e r i f ; f o n t −w e i g h t : b o l d ; margin : 0 . 8 3 em
e l s e return f a l s e ; 0 0 ; }”
} + ”−−></s t y l e >”
+ ”</head>”
// c r e a t e an e r r o r page + ”<body>”
private void c r e a t e E r r o r R e s p o n s e ( Exchange exchange ) { + ”<d i v i d =\” o u t l i n e \”>”
R e s p o n s e B u i l d e r e r r o r = Response . ok ( ) ; + ”<img
e r r o r . contentType ( ” t e x t / html ” ) ; s r c =\” h t t p : / /www. bath . ac . uk/ m a r k e t i n g / images / v i s u a l i d / l o g o s l a t e . j p g \”
e r r o r . body ( ” <!DOCTYPE html PUBLIC \”−//W3C//DTD a l t =\”\” h e i g h t =\”85\” width =\”180\”
XHTML 1 . 0 T r a n s i t i o n a l //EN\” b o r d e r =\”0\” />”
\” h t t p : / /www. w3 . o r g /TR/ xhtml1 /DTD/ xhtml1−t r a n s i t i o n a l . dtd\”>” + ”<d i v i d =\” t i t l e \”>”
+ ”<html xmlns=\” h t t p : / /www. w3 . o r g /1999/ xhtml\”>” + ”<h1>Error </h1>”
+ ”<head>” + ”</div>”
+ ”<meta http−e q u i v =\” c o n t e n t −t y p e \” + ”<d i v i d =\” t e x t \”>”
c o n t e n t =\” t e x t / html ; c h a r s e t=u t f −8\” />” + ”<h2>S u s p i c i o u s Request D e t e c t e d ! ! < / h2>”
+ ”<meta name=\” g e n e r a t o r \” c o n t e n t =\”Adobe + ”<p>This page can ’ t be d i s p l a y e d . Contact IT
GoLive \” />” s u p p o r t f o r a d d i t i o n a l i n f o r m a t i o n . </p>”
+ ”< t i t l e >Error </ t i t l e >” + ”</div>”
+ ”< s t y l e t y p e =\” t e x t / c s s \” media=\” s c r e e n \”><!−−” + ”</div>”
+ ”#o u t l i n e { p o s i t i o n : r e l a t i v e ; h e i g h t : 250 px ; + ”</body>”
width : 300 px ; margin : 18 px auto 0 ; b o r d e r : + ”</html>” ) ;
s o l i d 2px #505761; } ” S tr in g contentEncoding =
+ ”#t i t l e { l e f t : 10 px ; width : 300 px ; top : 70 px ; exchange . g e t R e q u e s t ( ) . g e t H e a d e r ( ) . g e t C o n t e n t E n c o d i n g ( ) ;
p o s i t i o n : a b s o l u t e ; v i s i b i l i t y : v i s i b l e ; }” i f ( c o n t e n t E n c o d i n g != n u l l )
+ ”#t e x t { l e f t : 10 px ; top : 120 px ; p o s i t i o n : e r r o r . h e a d e r ( Header .CONTENT ENCODING,

159
a b s o l u t e ; width : 300 px ; v i s i b i l i t y : v i s i b l e ; contentEncoding ) ;
APPENDIX D. SOURCE CODE
exchange . s e t R e s p o n s e ( e r r o r . b u i l d ( ) ) ;
}

// r e t u r n r e q u e s t URL e . g . / l o g i n . php
private S t r i n g g e t U r l ( Request r e q u e s t ) {
i n t qmark = r e q u e s t . g e t U r i ( ) . i n d e x Of ( ” ? ” ) ;
i f ( qmark < 0 ) return r e q u e s t . g e t U r i ( ) ;
e l s e return r e q u e s t . g e t U r i ( ) . s u b s t r i n g ( 0 , qmark ) ;
}

160
APPENDIX D. SOURCE CODE
D.3 SuspiciousInputDetectionEngine.java public void i n i t ( ) {
p r e I n s e r t L o g = null ;
p r e S e l e c t P r o f i l e 1 = null ;
package ReppSi ; p r e S e l e c t P r o f i l e 2 = null ;
r e s u l t S e t = null ;
import j a v a . i o . U nsupp ortedEnc odi ngExc ept ion ;
import j a v a . n e t . URLDecoder ; requestNumber = 1 ;
import java . s q l . Connection ;
import j a v a . s q l . DatabaseMetaData ; try {
import j a v a . s q l . DriverManager ; // c r e a t e c o n n e c t i o n t o t h e d a t a b a s e
import java . s q l . PreparedStatement ; C l a s s . forName ( ”com . mysql . j d b c . D r i v e r ” ) ;
import java . s q l . ResultSet ; connection =
import j a v a . s q l . SQLException ; DriverManager . g e t C o n n e c t i o n ( ” j d b c : mysql : / / l o c a l h o s t : 8 8 8 9 / r e s e a r c h ” ,
import j a v a . s q l . Statement ; ” r o o t ” , ” password ” ) ;
import j a v a . s q l . Types ; } catch ( SQLException ex ) {
import j a v a . u t i l . HashMap ; ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
import j a v a . u t i l . Map ; ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
import com . p r e d i c 8 . membrane . c o r e . h t t p . H e a d e r F i e l d ; ” SQLState : ” + ex . getSQLState ( ) ) ;
import com . p r e d i c 8 . membrane . c o r e . h t t p . Request ; } catch ( E x c e p t i o n e ) {
e . printStackTrace () ;
public c l a s s S u s p i c i o u s I n p u t D e t e c t i o n E n g i n e { }

private S t r i n g p r o t e c t e d S e r v e r ; // c r e a t e a l o g g i n g d a t a b a s e and/ or a p r o f i l i n g
d a t a b a s e i f n o t e x i s t e d / a l s o perform p r o f i l e
private C o n n e c t i o n c o n n e c t i o n ; updating
private P r e p a r e d S t a t e m e n t p r e I n s e r t L o g ; prepareDatabase ( ) ;
private P r e p a r e d S t a t e m e n t p r e S e l e c t P r o f i l e 1 ,
preSelectProfile2 ; }
private R e s u l t S e t r e s u l t S e t ;
public void i n i t P r o f i l i n g ( ) {
private i n t requestNumber ; Statement s t a t e m e n t = n u l l ;
ResultSet r e s u l t S e t = null ;
public S u s p i c i o u s I n p u t D e t e c t i o n E n g i n e ( S t r i n g try {
protectedServer ) { // a s s i g n a r e q u e s t number t o t h e h t t p r e q u e s t
this . protectedServer = protectedServer ; statement = connection . createStatement ( ) ;
}

161
APPENDIX D. SOURCE CODE
r e s u l t S e t = s t a t e m e n t . e x e c u t e Q u e r y ( ”SELECT S t r i n g s e l e c t P r o f i l e = ”SELECT
MAX( Req ) FROM ‘ ” + p r o t e c t e d S e r v e r + ”−l o g ‘ ” ) ; GET, POST, OtherMethods , Name , Type , Max , Min , A l l o w e d S p e c i a l C h a r a c t e r s
i f ( r e s u l t S e t . n e x t ( ) ) requestNumber = FROM ‘ ” + p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ ”
resultSet . getInt (1) + 1; + ”WHERE URL=? OR (URL=? AND Name=?)” ;
preSelectProfile1 =
//SQL s t a t e m e n t f o r i n s e r t i n g t h e h t t p r e q u e s t t o connection . prepareStatement ( s e l e c t P r o f i l e ) ;
the database preSelectProfile2 =
S t r i n g i n s e r t L o g = ”INSERT INTO ‘ ” + connection . prepareStatement ( s e l e c t P r o f i l e ) ;
p r o t e c t e d S e r v e r + ”−l o g ‘ ( Req , URL, Method , } catch ( SQLException ex ) {
Name , Value , Type , Length , i s C h e c k ) ” + ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
”VALUES ( ? , ? , ? , ? , ? , ? , ? , ’ 0 ’ ) ” ; ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
preInsertLog = ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
connection . prepareStatement ( insertLog ) ; ” SQLState : ” + ex . getSQLState ( ) ) ;
} catch ( E x c e p t i o n e ) {
} catch ( SQLException ex ) { e . printStackTrace () ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, }
” SQLException : ” + ex . g e t M e s s a g e ( ) ) ; }
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
” SQLState : ” + ex . getSQLState ( ) ) ; // p r e p a r e a d a t a b a s e f o r l o g g i n g and p r o f i l i n g
} catch ( E x c e p t i o n e ) { private void p r e p a r e D a t a b a s e ( ) {
e . printStackTrace () ; Statement c r e a t e L o g = n u l l ;
} finally { Statement c r e a t e P r o f i l e = n u l l ;
try { ResultSet l o g S e t = null ;
i f ( r e s u l t S e t != n u l l ) r e s u l t S e t . c l o s e ( ) ; ResultSet p r o f i l e S e t = null ;
i f ( s t a t e m e n t != n u l l ) s t a t e m e n t . c l o s e ( ) ;
} catch ( SQLException ex ) { PreparedStatement p r e I n s e r t P r o f i l e = null ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, PreparedStatement p r e U p d a t e P r o f i l e 1 = null ;
” SQLException : ” + ex . g e t M e s s a g e ( ) ) ; PreparedStatement p r e U p d a t e P r o f i l e 2 = null ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, PreparedStatement p r e S e l e c t P r o f i l e = null ;
” SQLState : ” + ex . getSQLState ( ) ) ;
} i n t numberOfRecordsUpdated = 0 ;
}
} try {
// c h e c k w h e t h e r t h e d a t a b a s e f o r l o g g i n g e x i s t s
public void i n i t P r o t e c t i o n ( ) { DatabaseMetaData md = c o n n e c t i o n . getMetaData ( ) ;
try { l o g S e t = md . g e t T a b l e s ( null , null , ” ‘ ” +

162
//SQL s t a t e m e n t f o r s e l e c t i n g profiles p r o t e c t e d S e r v e r + ”−l o g ‘ ” , n u l l ) ;
APPENDIX D. SOURCE CODE
+ ”URL v a r c h a r ( 2 5 5 ) , ”
// c r e a t e a d a t a b a s e f o r l o g g i n g i f n o t e x i s t e d + ”GET b o o l e a n , ”
i f ( ! l o g S e t . next ( ) ) { + ”POST b o o l e a n , ”
createLog = connection . createStatement () ; + ” OtherMethods b o o l e a n , ”
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO , + ”Name v a r c h a r ( 2 5 5 ) , ”
” Creating a table ‘ ” + protectedServer + + ”Type v a r c h a r ( 2 5 5 ) , ”
”−l o g ‘ f o r l o g g i n g HTTP r e q u e s t s . ” ) ; // ∗∗∗∗∗ + ”Max i n t , ”
S t r i n g c r e a t e = ”CREATE TABLE ‘ ” + + ”Min i n t , ”
p r o t e c t e d S e r v e r + ”−l o g ‘ ( ” + ” AllowedSpecialCharacters varchar (255) ) ” ;
+ ”Req i n t , ” c r e a t e P r o f i l e . executeUpdate ( c r e a t e ) ;
+ ”URL v a r c h a r ( 2 5 5 ) , ” ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO ,
+ ”Method v a r c h a r ( 2 5 5 ) , ” ” Table ‘ ” + p r o t e c t e d S e r v e r + ”− p r o f i l e ‘
+ ”Name v a r c h a r ( 2 5 5 ) , ” i s r e a d y . ” ) ; // ∗∗∗∗∗
+ ” Value v a r c h a r ( 2 5 5 ) , ” }
+ ”Type v a r c h a r ( 2 5 5 ) , ” profileSet . close () ;
+ ” Length i n t , ”
+ ” isCheck boolean ) ” ; // s t a r t p r o f i l e u p d a t i n g
createLog . executeUpdate ( c r e a t e ) ; long s t a r t T i m e = System . c u r r e n t T i m e M i l l i s ( ) ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO , ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO ,
” Table ‘ ” + p r o t e c t e d S e r v e r + ”−l o g ‘ i s ” S t a r t p r o f i l e s u p d a t i n g . . . ” ) ; // ∗∗∗∗∗
r e a d y . ” ) ; // ∗∗∗∗∗
} //SQL s t a t e m e n t f o r i n s e r t i n g a new p r o f i l e t o
// i f e x i s t e d , u p d a t e p r o f i l e the database
else { S t r i n g i n s e r t P r o f i l e = ”INSERT INTO ‘ ” +
c r e a t e P r o f i l e = connection . createStatement () ; p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ (URL, GET,
POST, OtherMethods , Name , Type , Max , Min ,
// c h e c k w h e t h e r t h e p r o f i l e d a t a b a s e e x i s t s AllowedSpecialCharacters ) ” +
p r o f i l e S e t = md . g e t T a b l e s ( null , null , ” ‘ ” + ”VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? ) ” ;
p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ ” , n u l l ) ; preInsertProfile =
connection . prepareStatement ( i n s e r t P r o f i l e ) ;
// c r e a t e t h e p r o f i l e d a t a b a s e i f n o t e x i s t e d
i f ( ! p r o f i l e S e t . next ( ) ) { //SQL s t a t e m e n t f o r u p d a t i n g an e x i s t i n g p r o f i l e
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO , in the database
” Creating a table ‘ ” + protectedServer + S t r i n g u p d a t e P r o f i l e 1 = ”UPDATE ‘ ” +
”− p r o f i l e ‘ f o r p r o f i l i n g ” ) ; // ∗∗∗∗∗ p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ SET GET=? ,
S t r i n g c r e a t e = ”CREATE TABLE ‘ ” + POST=? , OtherMethods =? , Name=? , Type=? ,

163
p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ ( ” Max=? , Min=? , A l l o w e d S p e c i a l C h a r a c t e r s =? ”
APPENDIX D. SOURCE CODE
+ ”WHERE URL=? AND (Name=? OR (Name I S NULL // u p d a t e p r o f i l e f o r t h e h t t p r e q u e s t w i t h o u t
AND ? I S NULL) ) ” ; any parameter
preUpdateProfile1 = i f ( p r o f i l e S e t . wasNull ( ) ) {
connection . prepareStatement ( updateProfile1 ) ; // p r o f i l e has a l r e a d y e x i s t e d
i f ( tempSet . n e x t ( ) ) {
S t r i n g u p d a t e P r o f i l e 2 = ”UPDATE ‘ ” + // s e t GET
p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ SET GET=? , i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” )
POST=? , OtherMethods=? ” && tempSet . g e t I n t ( ”GET” ) == 0 ) {
+ ”WHERE URL=? AND (Name=? OR (Name I S NULL preUpdateProfile2 . s e t I n t (1 , 1) ;
AND ? I S NULL) ) ” ; preUpdateProfile2 . s e t I n t (2 , 0) ;
preUpdateProfile2 = preUpdateProfile2 . s e t I n t (3 , 0) ;
connection . prepareStatement ( updateProfile2 ) ; preUpdateProfile2 . setString (4 ,
p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ;
//SQL s t a t e m e n t f o r s e l e c t i n g p r o f i l e s preUpdateProfile2 . setString (5 ,
S t r i n g s e l e c t P r o f i l e = ”SELECT p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
GET, POST, OtherMethods , Name , Type , Max , Min , A l l o w e d S p e c i a l C h a r a c t e r sp r e U p d a t e P r o f i l e 2 . s e t S t r i n g ( 6 ,
FROM ‘ ” + p r o t e c t e d S e r v e r + ”− p r o f i l e ‘ ” p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
+ ”WHERE URL=? AND (Name=? OR (Name I S NULL pr eUp dat ePro fil e2 . executeUpdate ( ) ;
AND ? I S NULL) ) ” ; numberOfRecordsUpdated++;
preSelectProfile = }
connection . prepareStatement ( s e l e c t P r o f i l e ) ; // s e t POST
i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” )
// f i n d t h e h t t p l o g s t h a t haven ’ t u p d a t e d t h e && tempSet . g e t I n t ( ”POST” ) == 0 ) {
p r o f i l e yet preUpdateProfile2 . s e t I n t (1 , 0) ;
p r o f i l e S e t = c r e a t e P r o f i l e . e x e c u t e Q u e r y ( ”SELECT preUpdateProfile2 . s e t I n t (2 , 1) ;
URL, Method , Name , Value , Type , Length FROM ‘ ” + preUpdateProfile2 . s e t I n t (3 , 0) ;
p r o t e c t e d S e r v e r + ”−l o g ‘ WHERE i s C h e c k = ’0 ’ ” ) ; preUpdateProfile2 . setString (4 ,
R e s u l t S e t tempSet = n u l l ; p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ;
while ( p r o f i l e S e t . n e x t ( ) ) { preUpdateProfile2 . setString (5 ,
preSelectProfile . setString (1 , p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ; preUpdateProfile2 . setString (6 ,
preSelectProfile . setString (2 , p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; pr eUp dat ePro fil e2 . executeUpdate ( ) ;
preSelectProfile . setString (3 , numberOfRecordsUpdated++;
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; }
tempSet = p r e S e l e c t P r o f i l e . e x e c u t e Q u e r y ( ) ; // s e t OtherMethods

164
APPENDIX D. SOURCE CODE
i f ( ! p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” ) }
&& }
! p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” ) p r e I n s e r t P r o f i l e . s e t N u l l ( 5 , Types .NULL) ;
&& tempSet . g e t I n t ( ” OtherMethods ” ) == p r e I n s e r t P r o f i l e . s e t N u l l ( 6 , Types .NULL) ;
0) { p r e I n s e r t P r o f i l e . s e t N u l l ( 7 , Types .NULL) ;
preUpdateProfile2 . s e t I n t (1 , 0) ; p r e I n s e r t P r o f i l e . s e t N u l l ( 8 , Types .NULL) ;
preUpdateProfile2 . s e t I n t (2 , 0) ; p r e I n s e r t P r o f i l e . s e t N u l l ( 9 , Types .NULL) ;
preUpdateProfile2 . s e t I n t (3 , 1) ; p r e I n s e r t P r o f i l e . executeUpdate ( ) ;
preUpdateProfile2 . setString (4 , numberOfRecordsUpdated++;
p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ; }
preUpdateProfile2 . setString (5 , }
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
preUpdateProfile2 . setString (6 , // u p d a t e p r o f i l e f o r t h e h t t p r e q u e s t t h a t has
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; a t l e a s t one parameter
pr eUp date Pro fil e2 . executeUpdate ( ) ; else {
numberOfRecordsUpdated++; // p r o f i l e has a l r e a d y e x i s t e d
} i f ( tempSet . n e x t ( ) ) {
} // s e t GET
// p r o f i l e hasn ’ t been c r e a t e d y e t i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” ) )
else { preUpdateProfile1 . s e t I n t (1 , 1) ;
p r e I n s e r t P r o f i l e . setString (1 , else preUpdateProfile1 . s e t I n t (1 ,
p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ; tempSet . g e t I n t ( ”GET” ) ) ;
i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” ) )
{ // s e t POST
p r e I n s e r t P r o f i l e . s e t I n t (2 , 1) ; i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” ) )
p r e I n s e r t P r o f i l e . s e t I n t (3 , 0) ; preUpdateProfile1 . s e t I n t (2 , 1) ;
p r e I n s e r t P r o f i l e . s e t I n t (4 , 0) ; else preUpdateProfile1 . s e t I n t (2 ,
} else { tempSet . g e t I n t ( ”POST” ) ) ;
i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” ) )
{ // s e t OtherMethods
p r e I n s e r t P r o f i l e . s e t I n t (2 , 0) ; i f ( ! p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” )
p r e I n s e r t P r o f i l e . s e t I n t (3 , 1) ; &&
p r e I n s e r t P r o f i l e . s e t I n t (4 , 0) ; ! p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” ) )
} else { preUpdateProfile1 . s e t I n t (3 , 1) ;
p r e I n s e r t P r o f i l e . s e t I n t (2 , 0) ; else preUpdateProfile1 . s e t I n t (3 ,
p r e I n s e r t P r o f i l e . s e t I n t (3 , 0) ; tempSet . g e t I n t ( ” OtherMethods ” ) ) ;

165
p r e I n s e r t P r o f i l e . s e t I n t (4 , 1) ;
APPENDIX D. SOURCE CODE
// s e t Name and o t h e r s }
tempSet . g e t S t r i n g ( ”Name” ) ; // p r o f i l e hasn ’ t been c r e a t e d y e t
i f ( tempSet . wasNull ( ) ) { else {
preUpdateProfile1 . setString (4 , p r e I n s e r t P r o f i l e . setString (1 ,
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ;
preUpdateProfile1 . setString (5 , i f ( p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”GET” ) )
p r o f i l e S e t . g e t S t r i n g ( ”Type” ) ) ; {
preUpdateProfile1 . setInt (6 , p r e I n s e r t P r o f i l e . s e t I n t (2 , 1) ;
p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ; p r e I n s e r t P r o f i l e . s e t I n t (3 , 0) ;
preUpdateProfile1 . setInt (7 , p r e I n s e r t P r o f i l e . s e t I n t (4 , 0) ;
p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ; }
preUpdateProfile1 . setString (8 , else {
g e t S p e c i a l C h a r a c t e r I n V a l u e ( p r o f i l e S e t . g e t S t r i n g ( ” Value ” )i)f)(;p r o f i l e S e t . g e t S t r i n g ( ”Method” ) . e q u a l s ( ”POST” ) )
} else { {
preUpdateProfile1 . setString (4 , p r e I n s e r t P r o f i l e . s e t I n t (2 , 0) ;
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; p r e I n s e r t P r o f i l e . s e t I n t (3 , 1) ;
preUpdateProfile1 . setString (5 , p r e I n s e r t P r o f i l e . s e t I n t (4 , 0) ;
getNewType ( tempSet . g e t S t r i n g ( ”Type” ) , } else {
p r o f i l e S e t . g e t S t r i n g ( ”Type” ) ) ) ; p r e I n s e r t P r o f i l e . s e t I n t (2 , 0) ;
preUpdateProfile1 . setInt (6 , p r e I n s e r t P r o f i l e . s e t I n t (3 , 0) ;
Math . max( tempSet . g e t I n t ( ”Max” ) , p r e I n s e r t P r o f i l e . s e t I n t (4 , 1) ;
p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ) ; }
preUpdateProfile1 . setInt (7 , }
Math . min ( tempSet . g e t I n t ( ”Min” ) , p r e I n s e r t P r o f i l e . setString (5 ,
p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ) ; p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ;
preUpdateProfile1 . setString (8 , p r e I n s e r t P r o f i l e . setString (6 ,
g e t S p e c i a l C h a r a c t e r I n V a l u e ( tempSet . g e t S t r i n g ( ” A l l o w e d S p e c p i arloCfhi laerSa ec t e. rgse”t)S.tcroi n cga(t”Type”
( p r o f i)l)e ;S e t . g e t S t r i n g ( ” Value ” ) ) ) ) ;
} preI nsertProfi le . setInt (7 ,
p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ;
preUpdateProfile1 . setString (9 , preI nsertProfi le . setInt (8 ,
p r o f i l e S e t . g e t S t r i n g ( ”URL” ) ) ; p r o f i l e S e t . g e t I n t ( ” Length ” ) ) ;
preUpdateProfile1 . setString (10 , p r e I n s e r t P r o f i l e . setString (9 ,
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; g e t S p e c i a l C h a r a c t e r I n V a l u e ( p r o f i l e S e t . g e t S t r i n g ( ” Value ” ) ) ) ;
preUpdateProfile1 . setString (11 , p r e I n s e r t P r o f i l e . executeUpdate ( ) ;
p r o f i l e S e t . g e t S t r i n g ( ”Name” ) ) ; numberOfRecordsUpdated++;
pr eUp date Pro fil e1 . executeUpdate ( ) ; }

166
numberOfRecordsUpdated++; }
APPENDIX D. SOURCE CODE
} } catch ( SQLException ex ) {
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
//SQL s t a t e m e n t f o r c h a n g i n g parameter ’ i s C h e c k ’ ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
to ’1 ’ a f t e r updating p r o f i l e s ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
c r e a t e P r o f i l e . e x e c u t e U p d a t e ( ”UPDATE ‘ ” + ” SQLState : ” + ex . getSQLState ( ) ) ;
p r o t e c t e d S e r v e r + ”−l o g ‘ SET i s C h e c k = ’1 ’ }
WHERE i s C h e c k = ’0 ’ ” ) ; }

long f i n i s h T i m e = System . c u r r e n t T i m e M i l l i s ( ) ; }
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . INFO ,
” P r o f i l e s u p d a t i n g i s done . ” + // l o g t h e incoming h t t p r e q u e s t
numberOfRecordsUpdated + ” p r o f i l e r e c o r d s public void l o g R e q u e s t ( Request r e q u e s t ) {
a r e updated . P r o c e s s i n g time i s ” + try {
( f i n i s h T i m e − s t a r t T i m e ) + ”ms” ) ; // ∗∗∗∗∗ Map<S t r i n g , S t r i n g > params =
getParameters ( request ) ;
} i f ( params . isEmpty ( ) ) {
} catch ( SQLException ex ) { p r e I n s e r t L o g . s e t I n t ( 1 , requestNumber ) ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, preInsertLog . setString (2 , getUrl ( request ) ) ;
” SQLException : ” + ex . g e t M e s s a g e ( ) ) ; preInsertLog . setString (3 , r e q u e s t . getMethod ( ) ) ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, p r e I n s e r t L o g . s e t N u l l ( 4 , Types .NULL) ;
” SQLState : ” + ex . getSQLState ( ) ) ; p r e I n s e r t L o g . s e t N u l l ( 5 , Types .NULL) ;
} catch ( E x c e p t i o n e ) { p r e I n s e r t L o g . s e t N u l l ( 6 , Types .NULL) ;
e . printStackTrace () ; p r e I n s e r t L o g . s e t N u l l ( 7 , Types .NULL) ;
} finally { p r e I n s e r t L o g . executeUpdate ( ) ;
try { } else {
i f ( l o g S e t != n u l l ) l o g S e t . c l o s e ( ) ; S t r i n g name ;
i f ( p r o f i l e S e t != n u l l ) p r o f i l e S e t . c l o s e ( ) ; String value ;
i f ( c r e a t e L o g != n u l l ) c r e a t e L o g . c l o s e ( ) ; f o r (Map . Entry<S t r i n g , S t r i n g > e n t r y :
i f ( c r e a t e P r o f i l e != n u l l ) c r e a t e P r o f i l e . c l o s e ( ) ; params . e n t r y S e t ( ) ) {
i f ( p r e S e l e c t P r o f i l e != n u l l ) name = e n t r y . getKey ( ) . t o S t r i n g ( ) ;
preSelectProfile . close () ; value = entry . getValue ( ) . t o S t r i n g ( ) ;
i f ( p r e I n s e r t P r o f i l e != n u l l )
preInsertProfile . close () ; p r e I n s e r t L o g . s e t I n t ( 1 , requestNumber ) ;
i f ( p r e U p d a t e P r o f i l e 1 != n u l l ) preInsertLog . setString (2 , getUrl ( request ) ) ;
preUpdateProfile1 . close () ; preInsertLog . setString (3 ,
i f ( p r e U p d a t e P r o f i l e 2 != n u l l ) r e q u e s t . getMethod ( ) ) ;

167
preUpdateProfile2 . close () ; p r e I n s e r t L o g . s e t S t r i n g ( 4 , name ) ;
APPENDIX D. SOURCE CODE
preInsertLog . setString (5 , value ) ; // c h e c k Method
preInsertLog . setString (6 , i f ( ( requestMethod . e q u a l s ( ”GET” ) &&
getValueType ( v a l u e ) ) ; r e s u l t S e t . g e t I n t ( ”GET” ) == 0 ) | |
preInsertLog . setInt (7 , value . length () ) ; ( requestMethod . e q u a l s ( ”POST” ) &&
p r e I n s e r t L o g . executeUpdate ( ) ; r e s u l t S e t . g e t I n t ( ”POST” ) == 0 ) | |
} ( ! requestMethod . e q u a l s ( ”GET” ) &&
} ! requestMethod . e q u a l s ( ”POST” ) &&
requestNumber++; r e s u l t S e t . g e t I n t ( ” OtherMethods ” ) == 0 ) ) {
} catch ( SQLException ex ) { ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE,
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, ” U n a u t h o r i z e d Method f o r Known URL: ” +
” SQLException : ” + ex . g e t M e s s a g e ( ) ) ; requestMethod + ” \n IP : ” + i p +
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, getRequestInformation ( request ) ) ;
” SQLState : ” + ex . getSQLState ( ) ) ; i s S u s p i c i o u s ++;
} catch ( E x c e p t i o n e ) { }
e . printStackTrace () ; }
} // no p r o f i l e matched
} else {
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE,
// r e t u r n t r u e i f t h e incomming HTTP r e q u e s t i s ” U n a u t h o r i z e d URL A c c e s s : ” + requestURL +
s u s p i c i o u s ( doesn ’ t match t h e p r o f i l e i n t h e ” \n IP : ” + i p +
database ) getRequestInformation ( request ) ) ;
public boolean i s S u s p i c i o u s R e q u e s t ( Request r e q u e s t , return true ;
String ip ) { }
int i s S u s p i c i o u s = 0 ; }
S t r i n g requestURL = g e t U r l ( r e q u e s t ) ; // i n s p e c t t h e h t t p r e q u e s t t h a t has a t l e a s t one
S t r i n g requestMethod = r e q u e s t . getMethod ( ) ; parameter
else {
Map<S t r i n g , S t r i n g > params = g e t P a r a m e t e r s ( r e q u e s t ) ; f o r (Map . Entry<S t r i n g , S t r i n g > e n t r y :
try { params . e n t r y S e t ( ) ) {
// i n s p e c t t h e h t t p r e q u e s t w i t h o u t any parameter p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 1 , ”NULL” ) ;
i f ( params . isEmpty ( ) ) { p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 2 , requestURL ) ;
p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 1 , requestURL ) ; p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 3 , e n t r y . getKey ( ) ) ;
p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 2 , ”NULL” ) ; r e s u l t S e t = p r e S e l e c t P r o f i l e 1 . executeQuery ( ) ;
p r e S e l e c t P r o f i l e 1 . s e t S t r i n g ( 3 , ”NULL” ) ; // t h e r e q u e s t URL f u l l y matches t h e p r o f i l e
r e s u l t S e t = p r e S e l e c t P r o f i l e 1 . executeQuery ( ) ; (URL + Name)
// t h e r e q u e s t URL matches t h e p r o f i l e i f ( r e s u l t S e t . next ( ) ) {

168
i f ( r e s u l t S e t . next ( ) ) { // c h e c k Method
APPENDIX D. SOURCE CODE
i f ( ( requestMethod . e q u a l s ( ”GET” ) && > 0) {
r e s u l t S e t . g e t I n t ( ”GET” ) == 0 ) | | String spListFromProfile =
( requestMethod . e q u a l s ( ”POST” ) && resultSet . getString (” AllowedSpecialCharacters ”) ;
r e s u l t S e t . g e t I n t ( ”POST” ) == 0 ) | | String replacedValue = entry . getValue ( ) ;
( ! requestMethod . e q u a l s ( ”GET” ) && for ( int i = 0 ; i <
! requestMethod . e q u a l s ( ”POST” ) && s p L i s t F r o m P r o f i l e . l e n g t h ( ) ; i ++) {
r e s u l t S e t . g e t I n t ( ” OtherMethods ” ) == i f ( s p L i s t F r o m P r o f i l e . charAt ( i ) == ’ s ’ )
0) ) { {
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE, replacedValue =
” U n a u t h o r i z e d Method f o r Known URL: ” r e p l a c e d V a l u e . r e p l a c e A l l ( ” \\ s ” ,
+ requestMethod + ” \n IP : ” + i p + ”0” ) ;
getRequestInformation ( request ) ) ; } else {
i s S u s p i c i o u s ++; replacedValue =
} r e p l a c e d V a l u e . r e p l a c e ( s p L i s t F r o m P r o f i l e . charAt ( i ) ,
’0 ’ ) ;
// c h e c k Type & A l l o w e d S p e c i a l C h a r a c t e r s }
S t r i n g requestValueType = }
getValueType ( e n t r y . g e t V a l u e ( ) ) ; replacedValue =
i f ( ! i s S u b s e t O f ( requestValueType , r e p l a c e d V a l u e . c o n c a t ( ”A0” ) ;
r e s u l t S e t . g e t S t r i n g ( ”Type” ) ) ) { i f ( getValueType ( r e p l a c e d V a l u e ) . e q u a l s ( ” A l l ” ) )
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE, {
” Parameter Type V i o l a t i o n : ” + ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE,
e n t r y . getKey ( ) + ”=” + ” Unauthorized S p e c i a l Character
entry . getValue ( ) + ” ( ” + f o r Parameter : ” + e n t r y . getKey ( )
r e s u l t S e t . g e t S t r i n g ( ”Type” ) + ” ) \n + ”=” + e n t r y . g e t V a l u e ( ) + ” ( ” +
IP : ” + i p + resultSet . getString (” AllowedSpecialCharacters ”)
getRequestInformation ( request ) ) ; + ” ) \n IP : ” + i p +
i s S u s p i c i o u s ++; getRequestInformation ( request ) ) ;
} else { i s S u s p i c i o u s ++;
i f ( ( requestValueType . e q u a l s ( ” S p e c i a l }
Characters ” ) | | }
requestValueType . e q u a l s ( ” Latin & }
Special Characters ” ) | |
r e q u e s t V a l u e T y p e . e q u a l s ( ” Numeric & // c h e c k Max & Min
Special Characters ” ) | | i f ( entry . getValue ( ) . length ( ) >
r e q u e s t V a l u e T y p e . e q u a l s ( ” A l l ” ) ) && r e s u l t S e t . g e t I n t ( ”Max” ) | |

169
r e s u l t S e t . g e t S t r i n g ( ” AllowedSpecialCharacters ” ) . length ( ) entry . getValue ( ) . length ( ) <
APPENDIX D. SOURCE CODE
r e s u l t S e t . g e t I n t ( ”Min” ) ) { }
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE, }
” Parameter Value Length V i o l a t i o n : ” + }
e n t r y . getKey ( ) + ”=” + } catch ( SQLException ex ) {
entry . getValue ( ) + ” ( ” + ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
r e s u l t S e t . g e t S t r i n g ( ”Max” ) + ” , ” + ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
r e s u l t S e t . g e t S t r i n g ( ”Min” ) + ” ) \n IP : ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING,
” + ip + ” SQLState : ” + ex . getSQLState ( ) ) ;
getRequestInformation ( request ) ) ; } catch ( E x c e p t i o n e ) {
i s S u s p i c i o u s ++; e . printStackTrace () ;
} }
}
// no p r o f i l e matched i f ( i s S u s p i c i o u s > 0 ) return true ;
else { e l s e return f a l s e ;
p r e S e l e c t P r o f i l e 2 . s e t S t r i n g ( 1 , requestURL ) ;
p r e S e l e c t P r o f i l e 2 . s e t S t r i n g ( 2 , ”NULL” ) ; }
p r e S e l e c t P r o f i l e 2 . s e t S t r i n g ( 3 , ”NULL” ) ;
R e s u l t S e t tempSet = // r e t u r n a t y p e o f t h e parameter v a l u e
p r e S e l e c t P r o f i l e 2 . executeQuery ( ) ; private S t r i n g getValueType ( S t r i n g v a l u e ) {
// t h e r e q u e s t URL p a r t i a l l y matches t h e int type = 0 ;
p r o f i l e (URL) i f ( v a l u e . l e n g t h ( ) == 0 ) return ” Blank ” ;
i f ( tempSet . n e x t ( ) ) { else {
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger .WARNING, i f ( v a l u e . matches ( ” . ∗ [ a−zA−Z ] . ∗ ” ) ) t y p e +=1;
”Unknown Parameter : ” + e n t r y . getKey ( ) i f ( v a l u e . matches ( ” . ∗ [ 0 − 9 ] . ∗ ” ) ) t y p e +=2;
+ ” \n IP : ” + i p + i f ( v a l u e . matches ( ” . ∗ [ \ \ s ; & \ \ + \ ” \ ’ \ \ ( \ \ )%<>\\\\/\\−#\\$ :@\\ˆ \ \ | \ \ . \ \ ∗ ! , ˜ \ \ [ \ \
getRequestInformation ( request ) ) ; t y p e +=4;
i s S u s p i c i o u s ++; switch ( t y p e ) {
} case 1 : return ” L a t i n C h a r a c t e r s ” ;
// t h e r e q u e s t URL doesn ’ t match even t h e URL case 2 : return ” Numeric ” ;
else { case 3 : return ” L a t i n C h a r a c t e r s & Numeric ” ;
ReverseProxy .LOGGER. p r i n t L o g ( TxtLogger . SEVERE, case 4 : return ” S p e c i a l C h a r a c t e r s ” ;
” U n a u t h o r i z e d URL A c c e s s : ” + case 5 : return ” L a t i n & S p e c i a l C h a r a c t e r s ” ;
requestURL + ” \n IP : ” + i p + case 6 : return ” Numeric & S p e c i a l C h a r a c t e r s ” ;
getRequestInformation ( request ) ) ; case 7 : return ” A l l ” ;
return true ; default : return ” L a t i n C h a r a c t e r s ” ;
} }

170
i f ( tempSet != n u l l ) tempSet . c l o s e ( ) ; }
APPENDIX D. SOURCE CODE
} i f ( typeOfProfile . equals (” All ”) | |
ty peOfRe quest . e q u a l s ( ” Blank ” ) ) return true ;
// combine 2 parameter t y p e s t o g e t h e r else {
private S t r i n g getNewType ( S t r i n g type1 , S t r i n g t y p e 2 ) { i f ( t ype OfR equ est . e q u a l s ( ” L a t i n C h a r a c t e r s ” ) &&
i f ( type1 . e q u a l s ( ” All ” ) | | type2 . e q u a l s ( ” All ” ) ) ( typeOfProfile . equals ( ” Latin Characters ” ) | |
return ” A l l ” ; typeOfProfile . equals ( ” Latin Characters &
else { Numeric ” ) | | t y p e O f P r o f i l e . e q u a l s ( ” L a t i n &
S t r i n g value1 = ”” ; S p e c i a l C h a r a c t e r s ” ) ) ) return true ;
i f ( t y p e 1 . e q u a l s ( ” L a t i n C h a r a c t e r s ” ) ) v a l u e 1 = ”A” ; i f ( t ype OfR equ es t . e q u a l s ( ” Numeric ” ) &&
i f ( t y p e 1 . e q u a l s ( ” Numeric ” ) ) v a l u e 1 = ” 0 ” ; ( t y p e O f P r o f i l e . e q u a l s ( ” Numeric ” ) | |
i f ( type1 . e q u a l s ( ” S p e c i a l Characters ” ) ) value1 = typeOfProfile . equals ( ” Latin Characters &
”!”; Numeric ” ) | | t y p e O f P r o f i l e . e q u a l s ( ” Numeric &
i f ( t y p e 1 . e q u a l s ( ” L a t i n C h a r a c t e r s & Numeric ” ) ) S p e c i a l C h a r a c t e r s ” ) ) ) return true ;
v a l u e 1 = ”A0” ; i f ( t ype OfR equ es t . e q u a l s ( ” S p e c i a l C h a r a c t e r s ” ) &&
i f ( type1 . e q u a l s ( ” Latin & S p e c i a l Characters ” ) ) ( typeOfProfile . equals ( ” Special Characters ” ) | |
v a l u e 1 = ”A! ” ; typeOfProfile . equals ( ” Latin & S p e c i a l
i f ( t y p e 1 . e q u a l s ( ” Numeric & S p e c i a l C h a r a c t e r s ” ) ) C h a r a c t e r s ” ) | | t y p e O f P r o f i l e . e q u a l s ( ” Numeric
value1 = ” 0! ” ; & S p e c i a l C h a r a c t e r s ” ) ) ) return true ;
S t r i n g value2 = ”” ; i f ( t ype OfR equ est . e q u a l s ( ” L a t i n C h a r a c t e r s &
i f ( t y p e 2 . e q u a l s ( ” L a t i n C h a r a c t e r s ” ) ) v a l u e 2 = ”A” ; Numeric ” ) && t y p e O f P r o f i l e . e q u a l s ( ” L a t i n
i f ( t y p e 2 . e q u a l s ( ” Numeric ” ) ) v a l u e 2 = ” 0 ” ; C h a r a c t e r s & Numeric ” ) ) return true ;
i f ( type2 . e q u a l s ( ” S p e c i a l Characters ” ) ) value2 = i f ( t ype OfR equ est . e q u a l s ( ” L a t i n & S p e c i a l
”!”; C h a r a c t e r s ” ) && t y p e O f P r o f i l e . e q u a l s ( ” L a t i n &
i f ( t y p e 2 . e q u a l s ( ” L a t i n C h a r a c t e r s & Numeric ” ) ) S p e c i a l C h a r a c t e r s ” ) ) return true ;
v a l u e 2 = ”A0” ; i f ( t ype OfR equ est . e q u a l s ( ” Numeric & S p e c i a l
i f ( type2 . e q u a l s ( ” Latin & S p e c i a l Characters ” ) ) C h a r a c t e r s ” ) && t y p e O f P r o f i l e . e q u a l s ( ” Numeric
v a l u e 2 = ”A! ” ; & S p e c i a l C h a r a c t e r s ” ) ) return true ;
i f ( t y p e 2 . e q u a l s ( ” Numeric & S p e c i a l C h a r a c t e r s ” ) ) return f a l s e ;
value2 = ” 0! ” ; }
return getValueType ( v a l u e 1 . c o n c a t ( v a l u e 2 ) ) ; }
}
} // r e t u r n a l i s t o f t h e s p e c i a l c h a r a c t e r s i n t h e v a l u e
private S t r i n g g e t S p e c i a l C h a r a c t e r I n V a l u e ( S t r i n g
// r e t u r n t r u e i f t y p e o f t h e r e q u e s t i s s u b s e t o f t y p e value ) {
of i t s p r o f i l e S t r i n g s p L i s t = ”” ;
private s t a t i c boolean i s S u b s e t O f ( S t r i n g i f ( v a l u e . matches ( ” . ∗ [ \ \ s ] . ∗ ” ) ) s p L i s t =

171
typeOfRequest , S t r i n g t y p e O f P r o f i l e ) { spList . concat ( ” s ” ) ;
APPENDIX D. SOURCE CODE
i f ( v a l u e . matches ( ” . ∗ [ ; ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ ] . ∗ ” ) ) s p L i s t =
spList . concat ( ” ; ” ) ; spList . concat ( ” ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ & ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ | ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”&” ) ; spList . concat ( ” | ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ \ + ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ . ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”+” ) ; spList . concat ( ” . ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ ” ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ ∗ ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ” \” ” ) ; s p L i s t . concat ( ”∗” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ ’ ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ ! ] . ∗ ” ) ) s p L i s t =
spList . concat ( ” \ ’ ” ) ; spList . concat ( ” ! ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ ( ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ ‘ ] . ∗ ” ) ) s p L i s t =
spList . concat ( ” ( ” ) ; spList . concat ( ” ‘ ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ ) ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ ˜ ] . ∗ ” ) ) s p L i s t =
spList . concat ( ” ) ” ) ; s p L i s t . concat ( ”˜” ) ;
i f ( v a l u e . matches ( ” . ∗ [ % ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ , ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”%” ) ; spList . concat ( ” , ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ < ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ [ ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”<” ) ; spList . concat ( ” [ ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ > ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ ] ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”>” ) ; spList . concat ( ” ] ” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ \ \ \ ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ { ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ” \\ ” ) ; s p L i s t . concat ( ”{” ) ;
i f ( v a l u e . matches ( ” . ∗ [ / ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ } ] . ∗ ” ) ) s p L i s t =
s p L i s t . concat ( ”/” ) ; s p L i s t . concat ( ”}” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ \ − ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ = ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”−” ) ; s p L i s t . c o n c a t ( ”=” ) ;
i f ( v a l u e . matches ( ” . ∗ [ # ] . ∗ ” ) ) s p L i s t = i f ( v a l u e . matches ( ” . ∗ [ \ \ ? ] . ∗ ” ) ) s p L i s t =
s p L i s t . c o n c a t ( ”#” ) ; spList . concat ( ”?” ) ;
i f ( v a l u e . matches ( ” . ∗ [ \ \ $ ] . ∗ ” ) ) s p L i s t = return s p L i s t ;
s p L i s t . concat ( ”$” ) ; }
i f ( v a l u e . matches ( ” . ∗ [ : ] . ∗ ” ) ) s p L i s t =
spList . concat ( ” : ” ) ; // r e t u r n parameter p a i r s ( name , v a l u e )
i f ( v a l u e . matches ( ” . ∗ [ @ ] . ∗ ” ) ) s p L i s t = private Map<S t r i n g , S t r i n g > g e t P a r a m e t e r s ( Request
s p L i s t . c o n c a t ( ”@” ) ; request ) {
i f ( v a l u e . matches ( ” . ∗ [ \ \ ˆ ] . ∗ ” ) ) s p L i s t = Map<S t r i n g , S t r i n g > p a r a m e t e r = new HashMap<S t r i n g ,
s p L i s t . concat ( ”ˆ” ) ; S t r i n g >() ;

172
S t r i n g method = r e q u e s t . getMethod ( ) ;
APPENDIX D. SOURCE CODE
S t r i n g [ ] p a i r s = null ; }
i f ( method . e q u a l s ( ”GET” ) ) {
i f ( r e q u e s t . g e t U r i ( ) . i n d e x Of ( ” ? ” ) < 0 | | // r e t u r n a l l h e a d e r f i e l d s o f t h e r e q u e s t ( name , v a l u e )
r e q u e s t . g e t U r i ( ) . i n d e x Of ( ”=” ) < 0 ) return private H e a d e r F i e l d [ ]
parameter ; g e t A l l R e q u e s t H e a d e r F i e l d s ( Request r e q u e s t ) {
else pairs = H e a d e r F i e l d f i e l d [ ] = new
r e q u e s t . getUri ( ) . s u b s t r i n g ( r e q u e s t . getUri ( ) . indexOf ( ”?” ) HeaderField [ r e q u e s t . getHeader ( ) . g e t A l l H e a d e r F i e l d s ( ) . l e n g t h ] ;
+ 1 ) . s p l i t ( ”&” ) ; System . a r r a y c o p y ( r e q u e s t . g e t H e a d e r ( ) . g e t A l l H e a d e r F i e l d s ( ) ,
} e l s e i f ( method . e q u a l s ( ”POST” ) ) { 0 , f i e ld , 0 , f i e l d . length ) ;
i f ( getRequestBody ( r e q u e s t ) . i n d e x Of ( ”=” ) < 0 ) return f i e l d ;
return p a r a m e t e r ; }
e l s e p a i r s = getRequestBody ( r e q u e s t ) . s p l i t ( ”&” ) ;
} // r e t u r n a l l i n f o r m a t i o n i n t h e HTTP r e q u e s t f o r
for ( S t r i n g p a i r : p a i r s ) { logging
i n t i n d e x = p a i r . in d e x Of ( ”=” ) ; private S t r i n g g e t R e q u e s t I n f o r m a t i o n ( Request r e q u e s t ) {
try { // p r i n t s t a t u s code , d e s t i n a t i o n , URL, method
p a r a m e t e r . put ( URLDecoder . d ec od e ( p a i r . s u b s t r i n g ( 0 , S t r i n g i n f o = ”\ t D e s t i n a t i o n : ” + p r o t e c t e d S e r v e r +
i n d e x ) , ”UTF−8” ) , ” \tURL : ” + g e t U r l ( r e q u e s t ) + ” \ tMethod : ” +
URLDecoder . d ec od e ( p a i r . s u b s t r i n g ( i n d e x + 1 ) , r e q u e s t . getMethod ( ) ;
”UTF−8” ) ) ;
} catch ( Unsupp orted Enc odi ng Exc ept io n e ) { // p r i n t h e a d e r f i e l d s
e . printStackTrace () ; HeaderField f i e l d [ ] =
} getAllRequestHeaderFields ( request ) ;
} f o r ( i n t i = 0 ; i < f i e l d . l e n g t h ; i ++) i n f o = i n f o +
return p a r a m e t e r ; ” \n ” + f i e l d [ i ] . getHeaderName ( ) + ” : ” +
} f i e l d [ i ] . getValue ( ) ;

// r e t u r n r e q u e s t URL e . g . / l o g i n . php // p r i n t parameter


private S t r i n g g e t U r l ( Request r e q u e s t ) { Map<S t r i n g , S t r i n g > params = g e t P a r a m e t e r s ( r e q u e s t ) ;
i n t qmark = r e q u e s t . g e t U r i ( ) . i n d e x Of ( ” ? ” ) ; i f ( params . isEmpty ( ) ) i n f o = i n f o + ( ” \n Parameter :
i f ( qmark < 0 ) return r e q u e s t . g e t U r i ( ) ; None” ) ;
e l s e return r e q u e s t . g e t U r i ( ) . s u b s t r i n g ( 0 , qmark ) ; else {
} i n f o = i n f o + ” \n Parameter : ” ;
f o r (Map . Entry<S t r i n g , S t r i n g > e n t r y :
// r e t u r n r e q u e s t body ( f o r POST method ) params . e n t r y S e t ( ) ) {
private S t r i n g getRequestBody ( Request r e q u e s t ) { i n f o = i n f o + e n t r y . getKey ( ) + ” = ” +

173
return r e q u e s t . getBodyAsStringDecoded ( ) ; entry . getValue ( ) + ” , ” ;
APPENDIX D. SOURCE CODE
}
}
i n f o = i n f o + ” \n
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−” ;
return i n f o ;
}

174
APPENDIX D. SOURCE CODE
D.4 TxtLogger.java } catch ( S e c u r i t y E x c e p t i o n e ) {
e . printStackTrace () ;
} catch ( IOException e ) {
package ReppSi ; e . printStackTrace () ;
}
import java . i o . IOException ; }
import java . u t i l . l o g g i n g . ConsoleHandler ;
import java . u t i l . logging . FileHandler ; public void p r i n t L o g ( S t r i n g l e v e l , S t r i n g msg ) {
import java . u t i l . l o g g i n g . Logger ; i f ( l e v e l . e q u a l s ( ” warning ” ) ) {
l o g g e r . warning ( msg ) ;
public c l a s s TxtLogger { } else {
i f ( l e v e l . e q u a l s ( ” s e v e r e ” ) ) l o g g e r . s e v e r e ( msg ) ;
private Logger l o g g e r ; e l s e l o g g e r . i n f o ( msg ) ;
private TxtLogFormatter f o r m a t t e r ; }
private ConsoleHandler cHandler ; }
private FileHandler fHandler ;
}
public f i n a l s t a t i c S t r i n g INFO = ” i n f o ” ;
public f i n a l s t a t i c S t r i n g WARNING = ” warning ” ;
public f i n a l s t a t i c S t r i n g SEVERE = ” s e v e r e ” ;

public TxtLogger ( ) {
l o g g e r = Logger . g e t L o g g e r ( TxtLogger . c l a s s . getName ( ) ) ;
logger . setUseParentHandlers ( false ) ;

f o r m a t t e r = new TxtLogFormatter ( ) ;

c H a n d l e r = new C o n s o l e H a n d l e r ( ) ;
cHandler . setFormatter ( formatter ) ;
l o g g e r . addHandler ( c H a n d l e r ) ;

try {
// l o c a t i o n o f t h e l o g f i l e
f H a n d l e r = new
F i l e H a n d l e r ( ” / U s e r s / Thee / Desktop / t x t l o g g e r . t x t ” ,
true ) ;
fHandler . setFormatter ( formatter ) ;

175
l o g g e r . addHandler ( f H a n d l e r ) ;
APPENDIX D. SOURCE CODE
D.5 TxtLogFormatter.java S t r i n g B u i l d e r b u i l d e r = new S t r i n g B u i l d e r ( 1 0 0 0 ) ;
b u i l d e r . append ( d f . f o r m a t (new Date ( ) ) ) . append ( ” ” ) ;
b u i l d e r . append ( ” [ ” ) . append ( r e c o r d . g e t L e v e l ( ) ) . append ( ” ]
package ReppSi ; ”) ;
b u i l d e r . append ( formatMessage ( r e c o r d ) ) ;
import java . util . Date ; b u i l d e r . append ( ” \n” ) ;
import java . util . l o g g i n g . Formatter ; return b u i l d e r . t o S t r i n g ( ) ;
import java . util . l o g g i n g . Handler ; }
import java . util . l o g g i n g . LogRecord ;
import java . text . DateFormat ; public S t r i n g getHead ( Handler h ) {
import java . text . SimpleDateFormat ; return super . getHead ( h ) ;
}
public c l a s s TxtLogFormatter extends Formatter {
public S t r i n g g e t T a i l ( Handler h ) {
private s t a t i c f i n a l DateFormat d f = new return super . g e t T a i l ( h ) ;
SimpleDateFormat ( ”dd−MM−yyyy HH:mm: s s ” ) ; }

public S t r i n g f o r m a t ( LogRecord r e c o r d ) { }

176

You might also like