Mitigating program security vulnerabilities: Approaches and challenges

46
11 Mitigating Program Security Vulnerabilities: Approaches and Challenges HOSSAIN SHAHRIAR and MOHAMMAD ZULKERNINE, Queen’s University, Kingston, Canada Programs are implemented in a variety of languages and contain serious vulnerabilities which might be exploited to cause security breaches. These vulnerabilities have been exploited in real life and caused damages to related stakeholders such as program users. As many security vulnerabilities belong to program code, many techniques have been applied to mitigate these vulnerabilities before program deployment. Unfortunately, there is no comprehensive comparative analysis of different vulnerability mitigation works. As a result, there exists an obscure mapping between the techniques, the addressed vulnerabilities, and the limitations of different approaches. This article attempts to address these issues. The work extensively compares and contrasts the existing program security vulnerability mitigation techniques, namely testing, static analysis, and hybrid analysis. We also discuss three other approaches employed to mitigate the most common program security vulnerabilities: secure programming, program transformation, and patching. The survey provides a comprehensive understanding of the current program security vulnerability mitigation approaches and challenges as well as their key characteristics and limitations. Moreover, our discussion highlights the open issues and future research directions in the area of program security vulnerability mitigation. Categories and Subject Descriptors: D 2.5 [Software Engineering]: Testing and Debugging—Testing tools; code inspections and walk-throughs; monitors; diagnostics General Terms: Security, Reliability Additional Key Words and Phrases: Program security vulnerability mitigation, vulnerability testing, static analysis, hybrid analysis, secure programming, program transformation, patching ACM Reference Format: Shahriar, H. and Zulkernine, M. 2012. Mitigating program security vulnerabilities: Approaches and chal- lenges. ACM Comput. Surv. 44, 3, Article 11 (June 2012), 46 pages. DOI = 10.1145/2187671.2187673 http://doi.acm.org/10.1145/2187671.2187673 1. INTRODUCTION Today’s programs are complex and accessible to almost every user. These programs are implemented in a wide variety of languages and run on different execution en- vironments that include language processors, browsers, and databases. Programs are developed and tested using a rich set of tools and techniques before actual deployment to ensure that they meet specific requirements in terms of functionality, quality, and performance. This work is partially supported by the Natural Sciences and Engineering Research Council of Canada (NSERC) and an Ontario Graduate Scholarship (OGS). Authors’ addresses: H. Shahriar (corresponding author) and M. Zulkernine, School of Computing Queen’s University, Kingston, ON, Canada; email: [email protected]. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies show this notice on the first page or initial screen of a display along with the full citation. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of this work in other works requires prior specific permission and/or a fee. Permissions may be requested from Publications Dept., ACM, Inc., 2 Penn Plaza, Suite 701, New York, NY 10121-0701 USA, fax +1 (212) 869-0481, or [email protected]. c 2012 ACM 0360-0300/2012/06-ART11 $10.00 DOI 10.1145/2187671.2187673 http://doi.acm.org/10.1145/2187671.2187673 ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Transcript of Mitigating program security vulnerabilities: Approaches and challenges

11

Mitigating Program Security Vulnerabilities:Approaches and Challenges

HOSSAIN SHAHRIAR and MOHAMMAD ZULKERNINE, Queen’s University, Kingston, Canada

Programs are implemented in a variety of languages and contain serious vulnerabilities which might beexploited to cause security breaches. These vulnerabilities have been exploited in real life and causeddamages to related stakeholders such as program users. As many security vulnerabilities belong to programcode, many techniques have been applied to mitigate these vulnerabilities before program deployment.Unfortunately, there is no comprehensive comparative analysis of different vulnerability mitigation works.As a result, there exists an obscure mapping between the techniques, the addressed vulnerabilities, andthe limitations of different approaches. This article attempts to address these issues. The work extensivelycompares and contrasts the existing program security vulnerability mitigation techniques, namely testing,static analysis, and hybrid analysis. We also discuss three other approaches employed to mitigate the mostcommon program security vulnerabilities: secure programming, program transformation, and patching. Thesurvey provides a comprehensive understanding of the current program security vulnerability mitigationapproaches and challenges as well as their key characteristics and limitations. Moreover, our discussionhighlights the open issues and future research directions in the area of program security vulnerabilitymitigation.

Categories and Subject Descriptors: D 2.5 [Software Engineering]: Testing and Debugging—Testing tools;code inspections and walk-throughs; monitors; diagnostics

General Terms: Security, Reliability

Additional Key Words and Phrases: Program security vulnerability mitigation, vulnerability testing, staticanalysis, hybrid analysis, secure programming, program transformation, patching

ACM Reference Format:Shahriar, H. and Zulkernine, M. 2012. Mitigating program security vulnerabilities: Approaches and chal-lenges. ACM Comput. Surv. 44, 3, Article 11 (June 2012), 46 pages.DOI = 10.1145/2187671.2187673 http://doi.acm.org/10.1145/2187671.2187673

1. INTRODUCTION

Today’s programs are complex and accessible to almost every user. These programsare implemented in a wide variety of languages and run on different execution en-vironments that include language processors, browsers, and databases. Programs aredeveloped and tested using a rich set of tools and techniques before actual deploymentto ensure that they meet specific requirements in terms of functionality, quality, andperformance.

This work is partially supported by the Natural Sciences and Engineering Research Council of Canada(NSERC) and an Ontario Graduate Scholarship (OGS).Authors’ addresses: H. Shahriar (corresponding author) and M. Zulkernine, School of Computing Queen’sUniversity, Kingston, ON, Canada; email: [email protected] to make digital or hard copies of part or all of this work for personal or classroom use is grantedwithout fee provided that copies are not made or distributed for profit or commercial advantage and thatcopies show this notice on the first page or initial screen of a display along with the full citation. Copyrights forcomponents of this work owned by others than ACM must be honored. Abstracting with credit is permitted.To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of thiswork in other works requires prior specific permission and/or a fee. Permissions may be requested fromPublications Dept., ACM, Inc., 2 Penn Plaza, Suite 701, New York, NY 10121-0701 USA, fax +1 (212)869-0481, or [email protected]© 2012 ACM 0360-0300/2012/06-ART11 $10.00

DOI 10.1145/2187671.2187673 http://doi.acm.org/10.1145/2187671.2187673

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:2 H. Shahriar and M. Zulkernine

Nevertheless, these programs contain vulnerabilities1 that might be exploited in-tentionally or unintentionally to cause security breaches. Vulnerabilities are flaws inprograms that allow attackers to expose, alter, disrupt, or destroy sensitive information[Dowd et al. 2007]. Approximately 50% of all security bugs (or vulnerabilities) occurat program code level [Okun et al. 2007]. These vulnerabilities can be exploited by at-tackers. Program vulnerabilities (i.e., vulnerabilities that arise due to implementationerrors in code) have been addressed in academia and industry for more than twentyyears. Still, we observe different security breach (or vulnerability) reports throughmany publicly available databases such as the Open Source Vulnerability Database[OSVDB 2010] and Common Vulnerabilities and Exposures [CVE 2010]. A numberof surveys report significant financial losses by individuals and organizations due toattacks exploiting vulnerabilities [Symantec 2008; Gordon et al. 2004]. Therefore, mit-igating program security vulnerabilities is extremely important.

If we look into the literature, we notice that many mitigation techniques are appliedto the program code before their deployment. These techniques are being evolvedwith novel attack techniques along with program usages (e.g., standalone programversus client server-based program), implementation languages (e.g., procedural,object-oriented, scripting), and language processors (e.g., script engines, SQL databaseengines). Unfortunately, there is no effort to review these techniques in a compar-ative way. In the past, several empirical studies have attempted to compare toolsand techniques for mitigating program security vulnerabilities [Kratkiewickz andLippmann 2005; Pozza et al. 2006; Okun et al. 2007; Zister et al. 2004; Fonseca et al.2007; Wilander and Kamkar 2003]. However, these studies have focused on analyzingworks for a single or few vulnerabilities or comparing approaches related to oneparticular mitigation technique. As a result, we have an obscure mapping between thetechniques, the addressed vulnerabilities, and the limitations of different approaches.

In this article, we survey program (“code-level”) security vulnerability mitigationapproaches to address these issues. We perform a comparative analysis of programsecurity vulnerability mitigation approaches with respect to the three most commontechniques: testing, static analysis, and hybrid analysis. Moreover, for the sake of com-pleteness, we briefly discuss the secure programming guideline related works and thetechniques employed in the maintenance stage (program transformation and patch-ing). We discuss vulnerabilities that are “directly exploitable” and result in “securitybreaches” in terms of confidentiality, integrity, and availability. We compare and con-trast the mitigation approaches based on their features. We also identify open issues foreach of the techniques. Our analysis indicates that solutions for program vulnerabilitymitigation have been influenced not only by traditional program analysis techniques,but also by the diversity of attack mechanisms. Moreover, current approaches havesome limitations with respect to vulnerability coverage and programming languages.

The article is organized as follows. Section 2 provides an overview of the five mostcommon vulnerabilities appearing in today’s programs. We analyze program security-,vulnerability-, and mitigation-related works based on testing, static analysis, andhybrid analysis in Sections 3, 4, and 5, respectively. Section 6 discusses the effortson secure programming, program transformation, and patching techniques. Finally,Section 7 draws some conclusions.

2. PROGRAM SECURITY VULNERABILITIES

Program security vulnerabilities are specific flaws in program code that result in se-curity breaches such as sensitive information leakage, modification, and destruction.

1The italic letters are used when we define related terminologies, introduce any of our proposed classificationfeatures, and explain program code examples.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:3

1. void foo (char *src) { 2. int i; 3. char buf [16]; 4. for (i=0; i<strlen(src); i++) 5. buf[i] = src[i]; 6. return; 7. }

Fig. 1. C code snippet of foo function vulnerable to BOF.

Attacks are successful exploitations of vulnerabilities. There are many program secu-rity vulnerabilities which might be exploited by attackers. However, we restrict ourdiscussion with respect to five vulnerabilities that may be present in program codebased on Common Weakness Enumeration (CWE) [CWE 2009]. These include BufferOverFlow (BOF), Format String Bug (FSB), SQL Injection (SQLI), Cross Site Script-ing (XSS), and Cross Site Request Forgery (CSRF). We choose them because they arethe most frequently discovered vulnerabilities in programs (“code level”) and “directlyexploitable”. Note that several vulnerabilities can be classified as a single source of thesame problem. For example, SQLI, XSS, and CSRF can be classified as “insecure in-teraction between components” based on a high-level taxonomy of CWE. Nevertheless,the wide differences in the exploitation mechanisms, severity of damages, and exist-ing mitigation efforts have motivated us to discuss these vulnerabilities individually.Moreover, we believe that mitigating these vulnerabilities can stop the exploitationof other vulnerabilities in programs such as buffer underflow and numeric overflow[OWASP 2010b].

2.1. Buffer Overflow

A Buffer OverFlow (BOF) vulnerability allows writing data to a program buffer exceed-ing the allocated size and overwriting the content of the neighboring memory locations[One 1996]. BOF might be present in programs having unsafe library function calls(e.g., ANSI C), lack of null characters at the end of buffers, buffer accesses throughpointers and aliases, logic errors (off by one), and insufficient checks before accessingbuffers. One of the most subtle BOF vulnerabilities might be present in programs thatperform pointer-intensive operations and generate pointer addresses through pointerarithmetic. For example, p = p + 4 results in a pointer p to point to a new locationfour bytes apart from the current location. If a read operation is performed througha pointer dereference (i.e., ∗p) and the new memory location does not belong to validmemory regions, a program may show many unexpected behaviors.

Exploitations of BOFs depend on the memory regions where buffers are located.These might include stack, heap, block started by symbol (also known as bss), anddata segments. Here, bss and data segments contain static or global data buffers thatare uninitialized and initialized, respectively. We discuss two major variations of BOFattacks in the following: stack-based and heap-based.

2.1.1. Stack-Based BOF Attack. In a stack-based BOF attack, the location of a bufferresides in the stack memory region. We provide an example of C code snippet (thefunction foo) in Figure 1 which is vulnerable to stack-based BOF. The buffer declaredat line 3 (buf ) is located in the stack region and has 16 bytes of memory for readingand writing operations. The valid location of this buffer is between buf[0] and buf[15].Lines 4 and 5 copy the src buffer into buf using a for-loop. However, the code is vulner-able as there is no checking on destination buffer length. As a result, the loop allowscopying more than the capacity of buf. To understand the effect of an overflow, weconsider a snapshot of the stack frame of the function foo shown in Figure 2 (adapted

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:4 H. Shahriar and M. Zulkernine

Buffer copy direction -----> buf [0] … … buf [15] i sfp ret src [ ][ ][ ][ ][ ] <----- Stack growth direction

Fig. 2. Stack layout of foo function.

from One [1996]). The stack stores the argument of foo (src), the return address (ret),the saved frame pointer (sfp), and declared variables (i and buf ), followed by the loopcounter (i). Note that the direction of stack growth and buffer copy is opposite to eachother. We assume that both ret and sfp occupy four bytes, whereas i occupies twobytes.

Storing an input of 17 bytes length (pointed by src) in the buf results in one byteoverflow. This corrupts the neighboring variable i and leads to further unexpectedbehaviors by the program. However, an attacker usually corrupts the return addressto execute injected code through buffer. This is known as a “return address clobbering”or “direct code injection” attack [Erlingsson 2007]. An attacker injects a payload whichcan modify the content of ret to point to the beginning address of the buffer (i.e., theaddress of buf[0]). In this case, the src buffer should be 26 bytes (16 bytes for the buf,two bytes for i, four bytes for both sfp and ret) to overwrite ret. The injected code cancontain a shell code (e.g., “/bin/sh”) to launch a remote shell with the root privilege.Note that several conditions need to be met to perform a successful attack such asallowing code execution from a stack segment, presence of no null character in theinjected payload, and allowing an input of sufficient length to reach the location ofret.

A program might not allow copying an input to a buffer which can modify the returnaddress. An attacker still may discover an alternative way to execute arbitrary code byoverwriting the frame pointer (i.e., sfp) [Klog 1999]. The sfp represents the stack topof the caller function of foo. An attacker modifies the sfp of foo to point to a location ofthe buffer. As a result, the first four bytes of the buffer are considered as a new savedframe pointer and the next four bytes are considered as the return address for thecaller of foo. The content of the new return address now points to the location of thebuffer containing injected code. The foo function returns to its caller as usual. However,when the caller returns, the injected code is executed.

Many existing countermeasures prevent code injections due to BOF attacks by con-verting stack segments from executable to nonexecutable [PaX 2003]. However, attack-ers still bypass such defenses. For example, a BOF attack can modify a return addresswith a known system library function call address. In this case, the buffer contains thearguments for the function calls. This variation of attack is known as “return-to-libc”or “jump-to-libc” [Erlingsson 2007]. Note that both saved frame pointer overwritingand return-to-libc are known as “indirect code injection” attacks.

2.1.2. Heap-Based BOF Attack. BOF attacks can be performed by overflowing databuffers located in the heap memory region. A typical attack overflows a neighboringfunction pointer which stores the address of a function. Figure 3 shows a C code snippet(foo2) which allocates two buffers (buf1 and buf2) at lines 2 and 3. These buffers arefreed at the end of the program (lines 6 and 7). Line 4 declares a pointer to a function(sum) which adds two integer arguments and returns the addition. Line 5 is vulnerableto BOF (the strcpy function call) which can corrupt not only the neighboring variable(buf2), but also the function pointer (sum). The function pointer corruption results inunexpected behaviors when the function is actually invoked (not shown in the examplecode snippet). An attacker can modify the function address with the location of injected

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:5

1. void foo2 (char *src) { 2. char *buf1 = malloc (32); 3. char *buf2 = malloc (32); 4. int (*sum) (int, int); 5. strcpy (buf1, src); 6. free (buf1); 7. free (buf2); 8. }

Fig. 3. C code snippet of foo2 function containing two heap-based buffers.

<------ chunk1 -----> <----- chunk2 -----> [prev size][cur size][buf1 … ][prev size][cur size][buf2 … ] ….. [fret-12] a1

Fig. 4. Heap memory layout of buf1 and buf2.

<----- chunk1 -----> <----- chunk 2 ----->

[prev size][cur size][shell code ][prev size][set LSB 1][fwd pointer][bk pointer] ….. [fret-12] a1

Fig. 5. Heap memory layout after overflowing buf1.

code which results in executing arbitrary code when the function is called. This is avery basic form of heap-based BOF attack.

Sophisticated heap-based attacks do not even rely on the presence of function point-ers in program code. These attacks can indirectly execute injected code by leveragingthe known working mechanism of malloc and free functions as well as memory man-agement information (or metainformation) stored in the beginning of allocated and freememory blocks (or chunks). This information can be obtained from publicly availablespecifications for memory managers such as “dlmalloc” [Leah 2000].

An allocated memory chunk contains the size of previous and current chunks followedby the area to store user-supplied data (i.e., a chunk size is more than an actualallocation request in program code). In contrast, the metainformation of a free chunkcontains the size of a current chunk and two pointers (forward and backward) to pointother free chunks in a doubly linked list. Moreover, when a chunk is freed, the memorymanager checks whether the next chunk is also free or not. If it is free, then it iscoalesced with the first chunk. As a result, the forward and backward pointers of thesecond free chunk are updated with the forward and backward pointers of the firstchunk, respectively. The least significant bit of the current size of a chunk is examinedto know whether it is free or not.

We provide an example of a heap-based BOF attack that allows executing injectedcode in buf1 during the free function call at line 6 of Figure 3. We show the heap memorylayout for two allocated memory chunks named chunk1 and chunk2, which correspondto buf1 and buf2, respectively in Figure 4 (adopted from Younan et al. [2005]). Here, theprev size and the cur size indicate the size of previous and current chunks, respectively.We assume that the cur size, prev size, fwd pointer, and bk pointer are four bytes eachbased on the structure of a free chunk. Moreover, a1 and fret indicate the locationsof buf1[0] and the return address of the free function call, respectively. Thus, fret-12indicates the memory location which is located 12 bytes before fret. Figure 5 shows the

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:6 H. Shahriar and M. Zulkernine

<----- chunk1 -----> <----- chunk 2 -----> [prev size][cur size][shell code ][prev size][set LSB 1][fwd pointer][bk pointer] ….. [a1 ] a1

Fig. 6. Heap memory layout after the unlink macro call.

layout during an attack that overflows buf1. The payload of buf1 contains the shell code,and it is large enough to modify the metainformation of chunk2. The cur size field ofchunk2 is modified to set the least significant bit as 1. As a result, chunk2 is consideredas a free chunk. Moreover, the content of buf2 needs to be replaced with forward (fwd)and backward (bk) pointers. The fwd and bk pointers are set to the locations of (fret-12)and the injected shell code, respectively.

During the free function call of buf1 (line 6 of Figure 3), a macro (known as unlink)first identifies that chunk2 is free and coalesces the fwd and bk pointers of chunk2 withchunk1. The effect of coalescing is shown in Figure 6. The first operation “chunk2->fwd->bk = chunk2->bk” sets the value of the forward pointer of chunk2 as a1.This is because chunk2->fwd->bk is the same as *(chunk2->fwd+12) (adding fourbytes for prev size, cur size, and fwd pointer) which is *(fret-12+12). The locationpointed by chunk2->bk has already been set to a1. Thus, fret stores the location ofa1. The return address of the free function call is replaced with the location of in-jected code in buf1. As a result, when the free function returns, the injected code isexecuted.

Several other variations of heap-based BOF attacks execute arbitrary injected codeby corrupting function pointers that are present in complex data structures (e.g., structin C) and vtable (a list of function pointers).

2.2. Format String Bug

Format String Bug (FSB) vulnerabilities imply invoking format functions (e.g., theformat functions of the ANSI C standard library [Huss 1997] with user-supplied formatstrings that might contain arbitrary format specifiers (e.g., %s). As a result, the numberof specifiers becomes more than the number of arguments, which allows arbitraryreading and writing in format function stacks. For example, a simple printf(“%d”, i)function call prints the value of i to the console, where i is an integer variable. However,the printf(“%d”) function call results in printing an arbitrary integer value. Moreover,a mismatch between a format specifier and its corresponding argument results inunexpected behaviors. For example, the function call printf(“%s”, i) results writinga string to the console where the string location is considered as the value of i. Ifattack cases are crafted carefully, it is possible to perform malicious activities suchas establishing root shells and overwriting Global Offset Tables (GOT) that containfunction addresses [Teso 2001; Silva 2005].

2.3. SQL Injection

SQLI vulnerabilities are present in programs that generate SQL [ISO 1992] querieswith invalidated user-supplied inputs. The inputs contain arbitrary SQL queries whichalter intended queries. The vulnerability can be exploited through SQL injection at-tacks that might cause unexpected results such as authentication bypassing and infor-mation leakage. We provide an example of an SQLI attack by using the code snippetof a server-side program written in Java Servlet as shown in Figure 7. Lines 2 and 3extract user-supplied information from the Login and Password fields into the sLoginand sPassword variables, respectively. The user input is not filtered and a dynamicSQL query is generated in lines 5 and 6. Let us assume that a user provides valid

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:7

1. String LoginAction (HttpServletRequest request, ...) throws IOException { 2. String sLogin = getParam (request, “Login”); 3. String sPassword = getParam (request, “Password”); 4. java.sql.ResultSet rs = null; 5. String qry = “select member_id, member_level from members where ”; 6. qry = qry + “member_login = ’” + sLogin + “’ and member_password = ’” + sPassword + “’”; 7. java.sql.ResultSet rs = stat.executeQuery (qry); 8. if (rs.next ()) { // Login and password passed 9. session.setAttribute (“UserID,” rs.getString (1)); … }

Fig. 7. Java servelet code snippet for authentication.

member login and member password, which are “guest” and “secret,” respectively. Then,the query generated at line 6 appropriately becomes “select member id, member levelfrom members where member login =’guest’ and member password = ’secret’”. Thedatabase engine executes the query at line 7, and the user is authenticated with avalid UserID at line 9. A malicious user can supply the input “’ or 1 = 1 – – ” inthe first field and leave the second input field blank. The resultant query becomes“select member id, member level from members where member login =” or 1 = 1 – –’and member password =””. The query is a tautology as the portion after the symbol“– –” is ignored by the database engine (“– –” is a comment symbol). Therefore, anattacker avoids the authentication by executing this query. There are several commonSQLI attack types such as tautologies, union queries, illegal/logical incorrect queries,piggybacked queries, stored procedures, inference attacks, and alternate encodings (orHex-encoded queries) [Halfond et al. 2006b].

2.4. Cross Site Scripting (XSS)

XSS vulnerabilities allow the generation of dynamic Hyper Text Markup Language[W3C 1999] contents with invalidated inputs which might contain HTML tags andJavaScript code. These inputs are interpreted by browsers while rendering Web pages.As a result, the intended behavior of generated web pages alters through visible (e.g.,creation of pop-up windows) and invisible (e.g., cookie bypassing) symptoms. XSS at-tacks circumvent traditional security mechanisms employed by browsers such as sameorigin policy, sandbox, and signed script.

There are three types of XSS attacks: stored, reflected, and Document Object Model(DOM)-based [Klein 2005; Zuchlinski 2003]. Generally, the injected code or payloadresides in the repository of a trusted Web site for a stored attack. In contrast, forother attack types (i.e., reflected), the payload is not stored in a persistent storageof a trusted Web site. Rather, the payload is often generated unintentionally by avictim or present in a third-party Web site. We illustrate the attacks with an exampleprogram named guestbook that can be accessed with a URL www.guestbook.com. Thesecond column of Table I shows three code snippets that perform three functionalitiesof guestbook. These are: (i) displaying a posted comment by using a PHP variable $msg,(ii) showing an error message, if a given file name is not found by using a PHP variable$ GET(‘fname’), and (iii) greeting a user with his name by using a JavaScript variablename. Here, echo is a PHP function that generates HTML contents; $ GET(‘fname’)is a PHP variable that retrieves the value of fname parameter; and document.URLis a JavaScript function that provides the current URL of an HTML page. The threefunctionalities are vulnerable to stored, reflected, and DOM-based attacks, respectively.The corresponding example attack cases are shown in the third column of Table I.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:8 H. Shahriar and M. Zulkernine

Table I. Example Program Code and XSS Attacks

Attack type Code snippet of guestbook Attack code exampleStored Comment: <? echo $ msg; ?> <script>alert(‘xss’);</script>Reflected <? echo $ GET(‘fname’); ?> Not found. www.guestbook.com?

fname = <script>alert(‘xss’);</script>DOM-based var name = document.URL.indexOf (“name = “) + 5;

document.write (“Hello” + name);www.guestbook.com#name = <script>alert(‘xss’);</script>

Stored XSS attacks occur when dynamic HTML contents are generated from the un-sanitized information stored in persistent data storages (e.g., files, databases) and theinformation contains JavaScript or HTML code. For example, the guestbook program re-trieves a user comment from a database and writes it to HTML output (i.e., echo $msg).If the $msg variable contains script code (i.e., <script>alert(‘xss’)</alert>) and is sentto a browser without filtering, a user observes an unexpected dialog box with the textxss. Although this is a simple form of attack, it is possible to perform malicious attacks.For example, the script code <script>document.location = ‘http://malicious.com/?’ +document.cookie </script> transfers the cookie information to a remote server (i.e.,http://malicious.com) that is controlled by an attacker. If an attacker gets the cookieinformation and a victim is still logged on, the attacker can send arbitrary HTTP re-quests with the valid cookie. Note that document is a standard object defined in DOMspecification [DOM 1998] that is created when browser generates an HTML page. Theobject has a tree-like representation that can be used to traverse all the HTML tagsand their attribute values with JavaScript.

In a reflected attack, the supplied code from a user is sent back by a serverprogram in the response page. The second example supplies the script code (i.e.,<script>alert(‘xss’);</script>) through a URL parameter named fname (file name). Thecode snippet shows an error message, if an input file name is not found. The file nameis sent back (reflected) to a browser and written as dynamic HTML content withoutfiltering. As a result, the script content of the fname is executed by a browser.

A JavaScript code segment that processes inputs based on DOM objects (e.g., doc-ument.URL) is vulnerable to XSS attacks [Klein 2005]. This is known as DOM-based XSS attacks. Unlike stored and reflected attacks, the injected code is notsent to a server-side program. In the third example (i.e., www.guestbook.com#name=<script>alert(‘xss’);</script>), a user name is passed through the name parame-ter of a URL. The parameter is retrieved with the document.URL.indexOf functionand written as HTML through the DOM method document.write. As a result, analert message shows up instead of a user name. Note that the name parameter inthe URL is preceded by a special symbol ‘#’. The symbol prohibits a browser to sendany information supplied after it. The HTML specification considers ‘#’ as a fragmentsymbol.

2.5. Cross Site Request Forgery (CSRF)

CSRF attacks allow performing unwanted actions in trusted Web sites by launchingvalid HTTP requests from browsers without a client’s knowledge [CWE 2010]. A CSRFvulnerability may arise, if a server program performs a request based on session in-formation (e.g., cookie, session id) sent from a browser. Session information is storedin browsers for a long time and added automatically while issuing requests. Moreover,browsers add session information automatically to GET type requests when loading im-ages and frames, submitting forms, clicking links, or redirecting pages. Thus, a serverprogram cannot differentiate between a request generated by a legitimate user and anattacker.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:9

Table II. Example Program Code Snippets of an Email Address Change

Server side codeClient side code (www.xyz.com/change.html) (www.xyz.com/editprofile.php)1. <HTML> 1. if (!valid($ SESSION[‘username’])) {2. <BODY> 2. echo “invalid session detected!”;3. <FORM action = “editprofile.php” method = “POST”> 3. exit;4. <INPUT type = “hidden” name = “action” value =

“setemail”>4.}

5. <INPUT type = “text” name = “email” value = ““> 5. if ($ POST[‘action’] = = ‘setemail’){6. <INPUT type = “submit” value = “Change Email

Address”>6. update profile($ POST[‘email’]);

7. </FORM> 7.}8. <BODY>

9. </HTML>

There are two types of CSRF attack: reflected and stored [Burns 2005]. In a reflectedCSRF vulnerability, the injected payload is hosted in a program other than a trustedserver program. Thus, a victim is exposed to an attack when he/she logs on to a serverprogram and browses to a different Web site (or program) simultaneously. In a storedCSRF vulnerability, the malicious code is stored within the trusted server programrepositories.

We provide example code snippets that are vulnerable to CSRF attacks in Table II.Let us assume that a user is logged on to a Web site (www.xyz.com) that storeshis/her profile. The profile includes a contact email address which has the initial [email protected]. The client side (the left column of Table II) provides an HTML interface(change.html) to change the email address of a logged on user legitimately. A newemail address provided by a user at line 5 is updated by the server-side script namededitprofile.php (i.e., the action field of Line 3). Note that the request of the emailaddress change is sent to editprofile.php by a hidden field (action and setemail) at line 4.The server-side code snippet is shown in the second column of Table II. It first checksif the request is associated with a valid session (line 1). If the session is not valid, thenthe program shows an error message and terminates (lines 2–4). Otherwise, the sessionis identified as valid (line 5), and the request is performed by calling the update profilefunction at line 6. The function is supplied with the new email address argument($POST[‘email’]).

If a user supplies the new email address as [email protected], the legitimate request be-comes http://www.xyz.com/editprofile?action=setemail&[email protected]. Thebrowser adds the session information (or cookie) in the request before sending to theserver program. Let us assume that the user is logged on to www.xyz.com as well asan instant messenger program. An attacker sends him a message containing a hy-perlink http://www.xyz.com/editprofile?action=setemail &[email protected]. If theuser clicks on the link, then his profile gets modified. The contact email address getschanged to [email protected]. As a result, the user is a victim of a reflected CSRF attack. Inpractice, CSRF attacks not only modify profiles, but also perform other forms of severedamages such as unauthorized financial transactions and sensitive information dele-tions. To become a victim of a stored CSRF, the malicious link would be stored in thepersistent storage of the victim program. It is common to find many such Web-basedprograms using persistent storages such as blogs and message boards.

2.6. Summary

We have discussed the five worst vulnerabilities that can be found in programswhich are implemented in a variety of languages. A mapping between programminglanguages and vulnerabilities is shown in Table III. The first seven languages are highlevel, whereas the last two (x86 assembly code and byte code) are intermediate code

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:10 H. Shahriar and M. Zulkernine

Table III. A Mapping between Programming Languages andVulnerabilities

Languages BOF FSB SQLI XSS CSRFC Y Y N N NC++ Y Y N N NJava N N Y Y YJSP N N Y Y YPHP N N Y Y YASP N N Y Y YJavaScript N N Y Y Nx86 assembly code Y Y N N NByte code N N Y Y Y

generated by compilers. From the table, we notice that programs implemented in anyof these languages might contain a large subset of the vulnerabilities (denoted as “Y”in table cells). Programs implemented in C and C++ are not vulnerable to Web-basedattacks (e.g., SQLI, XSS, and CSRF) as they are less common in implementingWeb-based programs. Rather, Java, PHP, JSP, and ASP are used to implementWeb-based programs which contain vulnerabilities. JavaScript programs are executedby client-side browsers. JavaScript programs contribute to Web-based vulnerabilitiesdue to improper validation of inputs. The cells containing “N” in the table indicate thatno vulnerability has been identified for the corresponding languages. Intermediateprograms generated from the source-code may inherit vulnerabilities. For instance,if a C program contains a BOF vulnerability, the corresponding machine-dependantx86 assembly code (generated by compiler and linker) also contains the samevulnerability.

Some vulnerabilities (e.g., BOF, FSB, SQLI) result in observable abnormal behaviorssuch as program crashes and error messages. Several vulnerabilities (e.g., XSS andCSRF) are difficult to identify through observable behaviors. Note that SQLI, XSS, andCSRF are denoted as Web-based vulnerabilities. BOF, SQLI, XSS, and CSRF are knownas injection vulnerabilities as attacks inject arbitrary code. We discuss the mitigationtechniques employed for the vulnerabilities in Sections 3–6.

3. TESTING

Testing is one of the most proactive program security vulnerability mitigation tech-niques before releasing programs [Mathur 2008]. In general, a program under test isprovided inputs, executed, and computed outputs are matched with expected outputs.If there is a mismatch between the computed and expected outputs, then the programimplementation does not comply with a desired requirement for a particular input.Testing requirements might be expressed in terms of functionality, performance, andquality. The pioneer works in program testing have focused on developing test casegeneration based on program code coverage (e.g., branch, loop, data flow, condition),program model coverage (e.g., states and transitions of a finite state machine), andcommon mistakes performed by programmers (e.g., fault-based testing and mutationanalysis) [Zhu et al. 1997]. However, as security of programs is getting an increas-ing level of attention in recent years, we notice many program security vulnerabilitytesting techniques have emerged. McGraw and Potter [2004] have described programsecurity vulnerability testing as a misunderstood task which is often considered asdeveloping secured firewall rules and port scanning in networks. Program security canbe tested based on risk assessment results, requirements, and design errors. However,we restrict our discussion on security testing due to the limitations of programminglanguages, libraries, APIs, and logic errors.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:11

We first show an analogy between software testing and program security vulner-ability testing in Section 3.1. In Section 3.2, we compare and contrast the relatedvulnerability testing works based on the following five features: test case generationmethod, source of test case, test level, test case input type, and vulnerability coverage.Out of these five features, test case generation is the most important step in securityvulnerability testing. Thus, we are motivated to classify existing program security test-ing approaches based on the test case generation techniques in Sections 3.3–3.9. Theseinclude fault injection, attack signature, mutation analysis, static analysis, search, pro-gram modification, and constraint bypassing-based techniques. Finally, we summarizeand discuss open issues in Section 3.10.

3.1. Software Testing vs. Program Security Testing

Like traditional software testing, we consider program security vulnerability testingas a process containing three major steps: identify testing requirements and coverage,generate test cases, and execute test cases [Shahriar and Zulkernine 2009a].

In the first step, appropriate security requirements are identified based on functionalrequirements. Our study considers requirements in terms of security breaches thatoccur through the implementation languages, APIs, environment variables, processors,and malformed inputs used by programs. In traditional testing, test coverage implieswhether generated test cases can cover a particular objective related to a programartifact. For example, a program may be tested in a way such that all branches presentin the source-code are tested, or a finite state machine can be used to generate testcases to cover all transition pairs. Similarly, vulnerability testing approaches often setsuch goal in advance. For example, a program should be tested for detecting all BOFand SQLI vulnerabilities.

In the second step, test cases are generated by using program artifacts (e.g., source-code) and interacting environments (e.g., protocol data unit) in a systematic way. Asubsequent issue that needs to be addressed by testers is to define the oracle for eachtest case. Unlike traditional software testing, the end computational results performedby programs do not play a significant role for determining oracles (successful attacks)in program security vulnerability testing. In most of the cases, program states andresponse messages are used to identify the presence or absence of attacks.

In the final stage, test cases are run against implementations and programs are as-sessed based on predefined oracles to identify vulnerabilities. In particular, it is checkedwhether a response matches with known attack symptoms. Overall, the program secu-rity vulnerability testing process is analogous to a traditional software testing process,except each of the stages is handled differently.

3.2. Comparison of Program Security Vulnerability Testing Approaches

In this section, we perform a comparative analysis of program security vulnerabilitytesting works from the literature based on five criteria: test case generation method,source of test case, test level, test case input type, and vulnerability coverage. Table IVshows a summary of the comparison, while we provide detailed descriptions for eachcriterion in the following.

3.2.1. Test Case Generation Method. It implies how a source of test case is convertedto a set of test cases. It is interesting to note that most of the traditional softwaretesting techniques have been used or leveraged to conduct test case generation forsecurity testing. These include fault injection [Jorgensen 2003, Zhang et al. 2008; Duand Mathur 2000; Ghosh et al. 1998], attack signature [Huang et al. 2003; Kals et al.2006], mutation analysis [Shahriar and Zulkernine 2008a], static analysis [Xu et al.2008; Kiezun et al. 2009], search technique [Grosso et al. 2008], program modification

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:12 H. Shahriar and M. Zulkernine

Table IV. Comparison Summary of Program Security Vulnerability Testing Works

Test case generation Source of test Test case inputWork method case Test level type VulnerabilityJorgensen

[2003]Fault injection (inject

lexical, syntactic, andsemantic faults)

Valid datastream

Black box File BOF

Shahriar andZulkernine[2008a,2010a]

Mutation analysis (injectvulnerabilities in code)

Source code (Cprogram)

White box String orcomplex datatypecontainingstring

BOF

Xu et al. [2008] Static analysis (solvepath constraints ofprograms)

Source code andAPI

White box String orcomplex datatypecontainingstring

BOF

Zhang et al.[2008]

Fault injection (modifyinput fields of PDU)

Valid PDU Black box Sequence of PDU BOF, FSB

Shahriar andZulkernine[2008b]

Mutation analysis (injectvulnerabilities in code)

Source code (Cprogram)

White box String orcomplex datatypecontainingformat string

FSB

Haugh andBishop [2003]

Static analysis(interesting functioncoverage)

Source code (Cprogram)

White box String orcomplex datatypecontainingstring

BOF

Huang et al.[2003]

Attack signature (injectattack inputs in HTMLforms)

HTML form Black box URL SQLI and XSS

Junjin [2009] Attack signature (replacebenign test cases withattack inputs)

Executable code(Java bytecode)

Black box URL SQLI

Kals et al.[2006]

Attack signature (injectattack inputs in HTMLforms)

HTML form Black box URL SQLI, XSS

Kiezun et al.[2009]

Static analysis (solvepath constraints),attack signature(replace non malicioustest cases with attacktest cases)

Source code(PHP code)

Hybrid URL SQLI and XSS

Shahriar andZulkernine[2008c]

Mutation analysis (injectvulnerabilities in code)

Source code(JSP code)

Hybrid URL SQLI

Shahriar andZulkernine[2009b]

Mutation analysis (injectvulnerabilities in code)

Source code(PHP code)

Hybrid URL or sequenceof URL

XSS

McAllister et al.[2008]

Attack signature (replacenon malicious testcases with attack testcases)

User session Black box Sequence of URL XSS

Vilela et al.[2002]

Mutation analysis (injectvulnerabilities in code)

Source code (Cprogram)

White box String orcomplex datatypecontainingstring

BOF

Tal et al. [2004] Fault injection (based onProtocol syntax)

Valid PDU Black box PDU BOF

Allen et al.[2006]

Fault injection (based onprotocol specification)

Valid PDU Black box PDU BOF

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:13

Table IV. (Continued)

Tappendenet al. [2005]

Attack signature (crawlweb pages and addattack test cases ininput forms)

HTML form Black box URL BOF, SQLI

Kim et al.[2008]

Fault injection (extractfile format and modifyfile tags or records)

Input file(HTML, WMF)

Black box Input file BOF

Ghosh et al.[1998]

Fault injection (inprogram variables)

Program state(variable)

Black box String orcomplex datatypecontainingstring

BOF

Du and Mathur[2000]

Fault injection (in directand indirectenvironment variables)

Programenvironment

Black box Global variable,network input,file, socket

BOF

Breech andPollock [2005]

Program modification(through compiler)

Source code (Cprogram)

Black box Modifiedprogram

BOF

Offutt et al.[2004]

Constraint bypassing(inputs in responsepages)

Source code(HTML)

Black box URL SQLI, XSS

Grosso et al.[2008]

Search technique (geneticalgorithm)

Source code (Cprogram)

White box String orcomplex datatypecontainingstring

BOF

Cadar et al.[2006]

Static analysis (symbolicexecution and solvingpath constraints)

Source code (Cprogram)

White box String orcomplex datatypecontainingstring

BOF

[Breech and Pollock 2005], and constraint bypassing [Offutt et al. 2004]. We discussthese methods in Sections 3.3–3.9.

3.2.2. Source of Test Case. This criterion identifies what artifacts of programs or envi-ronments are used for generating test cases. These include source-code of programs,[Shahriar and Zulkernine 2008a; Haugh and Bishop 2003], vulnerable APIs (e.g., ANSIC library functions) [Xu et al. 2008], valid protocol data units [Zhang et al. 2008; Talet al. 2004], valid data streams [Jorgensen 2003], user sessions [McAllister et al. 2008],executable program code [Junjin 2009], runtime states of programs [Ghosh et al. 1998],and program environments [Du and Mathur 2000]. Here, runtime state of a programincludes declared variable values of a program. A user session indicates an executionpath of a program that is traversed while performing a functionality. Program environ-ment includes a broader range of inputs that are generated from files, networks, andprocessors. Attack templates are attack signatures that result in unintended behaviorsin programs.

3.2.3. Test Level. It indicates whether security vulnerability testing of a program isperformed in a white-box or a black-box manner. Most of the testing approaches employblack-box testing [Jorgensen 2003; Huang et al. 2003; Junjin 2009]. Some approachesexplore white-box testing mechanisms [Grosso et al. 2008; Haugh and Bishop 2003].Very few techniques apply hybrid testing (a combination of white-box and black-boxtesting) [Shahriar and Zulkernine 2009b]. In a hybrid testing, program artifacts areused to generate test cases that are run and analyzed in a black-box manner.

3.2.4. Test Case Input Type. This feature describes what constitutes a test case in pro-gram security vulnerability testing. Table IV shows that test case input types vary not

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:14 H. Shahriar and M. Zulkernine

only on data received by programs and its surrounding environments, but also on vul-nerabilities. For example, exploiting BOF vulnerabilities involves generating strings ofparticular lengths, or complex data types containing strings [Shahriar and Zulkernine2008a; Xu et al. 2008]. Similarly, test cases for exposing FSB vulnerabilities requirestrings (or complex data types) containing format specifiers [Shahriar and Zulkernine2008b]. However, SQLI and XSS vulnerability exploitations require URLs with appro-priate parameters and values [Huang et al. 2003; Junjin 2009; Kals et al. 2006; Kiezunet al. 2009; Shahriar and Zulkernine 2008c, 2009b]. Moreover, a sequence of URLs[Shahriar and Zulkernine 2009b] or PDUs [Allen et al. 2006; Tal et al. 2004] mightform just one test case since all of them must be applied to programs to exploit vulner-abilities. For example, to perform a stored XSS attack, at least two URLs are requiredto form one test case: one for storing a malicious script and the other to download apage containing that script.

3.2.5. Vulnerability Coverage. This feature indicates what particular vulnerability an ap-proach tests. From Table IV, it is obvious that BOF, SQLI, and XSS vulnerabilities havebeen addressed by many testing approaches. We also note that very few approachestest multiple vulnerabilities such as SQLI and XSS [Kiezun et al. 2009].

3.3. Fault-Injection-Based Test Case Generation

Fault injection is one of the most widely used test case generation techniques suit-able for performing black-box-based testing. The objective is to corrupt input dataand variables, execute programs with corrupted data and variables, and observe un-expected responses to conform vulnerabilities. We divide fault-injection-based securityvulnerability testing works into three types based on the target of corruption: in-put data, environment, and program state. We describe them in the following threesubsections.

3.3.1. Corrupting Input Data. In this technique, input data processed by programs aremodified in ways such that the desired lexical, syntactic, or semantic structures becomemalformed. The resultant input data are supplied to a program under test to revealvulnerabilities through abnormal behaviors. For example, Jorgensen [2003] corruptsvalid data stream at lexical (i.e., character) level, syntactic (i.e., lexically correct andsyntactically incorrect), and semantic (e.g., changing a date format) levels. Tal et al.[2004] capture Protocol Data Units (PDUs), modify data fields of these PDUs, thensend them back to the server and observe the server program’s responses. Kim et al.[2008] corrupt the semantic structure of HTML files and vector image files by replacingone tag with another and modifying the fields of records, respectively.

Several works corrupt input data while maintaining the semantic meaning of asequence of input data. For example, Zhang et al. [2008] test a file transfer protocolprogram by first identifying a valid command packet sequence. They generatemalformed packets (e.g., filling packets with large-sized strings, special format stringssuch as %s and %n) that are valid according to protocol specification, but may not beprocessed properly by target programs. Similarly, Allen et al. [2006] construct a setof valid messages (or packets) into blocks based on a protocol specification. They keepmessage sequences intact and apply fuzzing in message fields to generate corruptedinputs.

3.3.2. Corrupting Environment. In this technique, environment variables of programsare modified. These include environment variables during program initialization(e.g., configuration file) and execution (e.g., file system inputs, network packets). Wenote that input data corruption techniques also modify files and network packets.However, these techniques modify the lexical, syntactic, or semantic structures. In

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:15

contrast, environment variable corruption techniques modify the attributes of inputs[Du and Mathur 2000]. For example, a file might be modified in terms of existence(e.g., file can be deleted), permission (read or write permissions may be toggled), andownership attributes. A configuration file points to a list of directories for performingsearches. A corruption technique might alter the sequence of directories to test securityvulnerabilities.

3.3.3. Corrupting Program State. In this approach, an executable program state is mod-ified to check whether program code can handle vulnerabilities or not. A programstate includes data variables that control program execution and sensitive locationswhere the program stores values such as function return addresses [Ghosh et al. 1998].The modified states result in security violations. Thus, a program shows anomalousbehaviors if the implementation does not handle security violations appropriately.

3.4. Attack-Signature-Based Test Case Generation

This is the second most widely used test case generation approach, where test casesare generated by replacing some (or all) parts of a normal input with attack signatures.The attack signatures are developed from the experience and vulnerability reports. Wenotice that this approach is applied widely to Web-based programs. We divide security-vulnerability-testing-related works employing attack-signature-based test case gener-ation methods into two categories based on how Web pages are traversed. These includerequest and response and use-case-based test case generation.

3.4.1. Request and Response. In this method, a crawler requests a Web page and cap-tures the response page. In the response page, it identifies input fields (e.g., HTMLforms) which are filled and submitted with malicious inputs. This process enables atester to reach all pages where attack inputs can be injected and observe the response ofmalicious inputs. Vulnerabilities in client- or server-side programs are observed basedon the error messages. For example, Huang et al. [2003] and Kals et al. [2006] applyrequest- and response-based Web page crawling to generate test cases (or URLs) todiscover SQLI and XSS vulnerabilities. Programs are executed to check attack occur-rences by replacing valid test cases with attack inputs (i.e., substituting URL parametervalues with an attack inputs) [Junjin 2009; Kiezun et al. 2009].

A variation of the approach is to apply a set of programmable APIs to performcrawling. These APIs enable a tester to emulate browsers such as form submissionand page redirection. In particular, input form fields can be accessed and modified toinject attack input test cases. The modified form can be submitted and checked forthe presence of vulnerabilities in the response pages through customized assertions.Tappenden et al. [2005] develop a set of programmable APIs named HTTPUnit to detectSQLI vulnerabilities in Web-based programs for agile environments (i.e., testing anddevelopment occur simultaneously).

3.4.2. Use Case. Traditional request- and response-based testing approaches identifyvulnerabilities at the interface level of programs. They often fail to reach inner logics ofprogram code which might open the doors for attacks and are hard to test with black-boxtesting approaches. To alleviate this problem, a use-case-based approach first appliesinteractive user inputs to perform functionalities of programs. This ensures breadthtesting of a program’s code. Later, URLs containing user inputs are reapplied to performthe same functionalities. However, malicious test cases are injected instead of user-supplied benign values. This ensures testing the depth of program logics. McAllisteret al. [2008] apply this approach to discover reflected and stored XSS vulnerabilities inWeb-based programs.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:16 H. Shahriar and M. Zulkernine

3.5. Mutation-Analysis-Based Test Case Generation

Mutation is a fault-based testing technique that is intended to show that an implemen-tation is free from faults [DeMillo et al. 1978]. The major step of a mutation analysis isto define a set of operators (known as mutation operators) which describe the rules ofinjecting faults. In the context of security testing, mutation operators modify programcode to inject vulnerabilities. The modified programs are called mutants. A mutant issaid to be killed or distinguished if at least one test case can produce different outputbetween a mutant and the original implementation. Otherwise, the mutant is live. Ifno test case kills a mutant, then it is either equivalent to an original implementationor a new test case needs to be generated to kill the live mutant. Generating new testcases enhances the fault detection ability of a test suite. The adequacy of a test suite ismeasured by a Mutation Score (MS), which is the ratio between the number of killedmutants and the total number of nonequivalent mutants. Note that there is a subtledifference between fault-injection-based testing that employs mutation operators andmutation-based analysis. In a mutation analysis, the end objective is to assess the qual-ity of a test suite. However, a fault injection technique is guided by mutation operatorswith the objective of testing the presence of vulnerabilities in programs by observinganomalous behaviors.

The pioneer research of applying mutation analysis for vulnerability detectionhas been performed by Vilela et al. [2002] where they assess test suite’s qualityfor detecting BOF vulnerabilities in C programs. However, their approach doesnot consider BOF vulnerabilities due to ANSI C library functions (e.g., strcpy) andlanguage-specific features (e.g., absence of the null character at the end of a buffer).Later, Shahriar and Zulkernine [2008a, 2010a] propose mutation operators to assesstest suite quality for detecting BOF caused by these issues. Moreover, Shahriar andZulkernine [2008b] propose mutation operators to inject faults in ANSI C formatfunctions. Furthermore, they propose mutation operators for adequate testing ofSQLI [Shahriar and Zulkernine 2008c] and XSS [Shahriar and Zulkernine 2009b]vulnerabilities in Web-based programs implemented in JSP and PHP, respectively.

3.6. Static-Analysis-Based Test Case Generation

This approach generates test cases by analyzing program source-code without execut-ing2. The analysis relies on the symbolic execution of program code, where programinputs are assumed to hold arbitrary values represented by symbols [King 1976]. Inthe context of security testing, the main idea is to extract path constraints and updatesymbolic values present in path conditions with known values at different statements.The symbolic values are updated with known values based on initialized variables orderived values from inputs. While a path ends or a vulnerable statement is reached,a current path constraint is solved with a custom constraint solver to obtain a set ofconcrete input values. Most of the symbolic execution-based test case generation ap-proaches have been applied to detect BOF vulnerabilities in C programs [Cadar et al.2006; Xu et al. 2008]. In these cases, symbolic assignments are preformed for programstatements present along feasible paths that include either sensitive memory accesses[Cadar et al. 2006] or potential invalid memory addresses related to pointer variables[Xu et al. 2008]. Symbolic execution-based analysis has been applied to generate SQLIand XSS vulnerabilities in Web-based programs [Kiezun et al. 2009].

A variation of the static-analysis-based test case generation approach employs “in-teresting function coverage” information to guide test case generation. For example,Haugh and Bishop [2003] develop a Systematic Testing of Buffer Overflow (STOBO)

2The detailed description of static analysis techniques is provided in Section 4.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:17

tool which instruments a given input program file to warn whether more test cases arerequired or not. The approach discovers BOF vulnerabilities caused by unsafe libraryfunction calls (e.g., memcpy, strcpy).

3.7. Search-Based Test Case Generation

If the test input space for discovering vulnerabilities is huge and identification ofvulnerability revealing test cases is time consuming, a practical approach is to apply asearch-based technique [McMinn 2004] as a way of generating test cases. For example,discovering BOF with test cases having large-sized strings fits well for applying thesearch-based test case generation technique. In general, a technique applies a suitablesearch algorithm where a random input is chosen as the initial solution. The solution isevolved over a number of times unless an objective function value remains unchanged.

One of the most widely used search techniques applied for program security testingis a genetic algorithm. The major variations in genetic algorithms while generating testcases occur in two important stages: fitness function and mutation operator. The fitnessfunction guides the generation of test cases so that vulnerability exploitations arerevealed. However, depending on testing objectives, fitness functions vary. For example,Grosso et al. [2008] define a fitness function to generate BOF test cases which focuses onprogram code coverage (e.g., vulnerable statement with unsafe ANSI C library functioncalls). Mutation operators depend on the testing objective. For example, Grosso et al.[2008] apply a mutation operator, where a numeric value is randomly incremented, anda string is appended with a random string. Such an approach allows the generation oftest cases to quickly reveal BOF attacks.

3.8. Program-Modification-Based Test Case Generation

In this technique, program instructions are modified by leveraging dynamic compilertechniques which allow accessing intermediate program code before being executedby CPUs. The technique tests programs that have vulnerability exploitation detectionmechanisms included. Moreover, it can detect subtle vulnerabilities that otherwisemight go undetected due to modification of program states (e.g., memory layout) bycompilers. For example, a compiler may apply default padding after an allocated buffer,which prohibits confirming the presence of one-byte BOF with test cases. Breech andPollock [2005] develop a testing framework based on a dynamic compiler that can testprograms by injecting attack code (e.g., modifying the return address of a function) inbasic blocks (i.e., a sequence of code with no branching).

3.9. Constraint-Bypassing-Based Test Case Generation

The main idea of this technique is to generate inputs to bypass filtering mechanismsemployed in a program. The approach can be applied to Web-based programs, wherescript code can be written by programmers to filter malicious inputs at browsers. Forexample, Offutt et al. [2004] propose three levels of bypass testing for Web-based pro-grams to discover client-side vulnerabilities such as SQLI and XSS. These include:(i) value-level (e.g., violating built-in length of inputs), (ii) parameter-level (e.g., vio-lating relationships among parameters), and (iii) control-flow-level (e.g., applying backand refresh buttons) testing.

3.10. Summary and Open Issues

From the comparative study, we notice that current approaches are limited to testingfew vulnerability types such as BOF, SQLI, and XSS. Thus, future research should fo-cus on discovering other vulnerabilities that might be present in programs such as FSBand CSRF. Moreover, every test case generation method has a narrow perspective oftesting program security vulnerabilities. For example, fault-based techniques provide

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:18 H. Shahriar and M. Zulkernine

us limited or no information related to vulnerability and code coverage. Therefore,future research directions may combine a fault-based technique with other techniques(e.g., static analysis) to improve the situation. Current fault-based approaches are lim-ited to corrupting input data, environment variables, and program states. We believethat many unknown vulnerabilities can be discovered by injecting faults on programartifacts such as control and data flows. We also notice that attack-signature-basedtest case generation has been improved by combining static analysis. However, theirscope is limited to Web-based programs and Web-based vulnerabilities. A search-basedtechnique has been applied to generate test cases only for testing BOF vulnerabilities.Future research should explore employing the search techniques for generating testcases for other vulnerabilities. Program modification techniques can also be exploredfor Web-based programming paradigms (e.g., modifying client-side program state).

4. STATIC ANALYSIS

A common proactive approach to detect security vulnerabilities in program code isto perform static analysis [Chess and McGraw 2004]. The approach examines inputprogram code, applies specific rules or algorithms (also known as inference), and de-rives a list of vulnerable code present in a program that might result in successfulexploitations. The advantage of performing static analysis is that it does not requireexecuting program code. As a result, the analysis ignores the issues related to pro-gram executions such as the reachability of vulnerable code and the generation ofinput test cases to traverse the vulnerable code. The pioneer static analysis techniques(e.g., control flow, data flow, interprocedural analysis) have been developed mainly forcompiler-generated code optimizations, and they are not intended for detecting secu-rity vulnerabilities in program code. As security breaches have become widespread inprogramming communities, many tools and techniques have been developed to applystatic analysis for discovering vulnerabilities in program code [Viega et al. 2002; Weberet al. 2001; Flawfinder 2010].

In the following subsection, we perform a comparative analysis of static analysisworks based on the following seven aspects: inference type, analysis sensitivity, analysislevel, completeness, soundness, vulnerability coverage, and programming languagesupported in the analysis [Shahriar and Zulkernine 2010c]. The effectiveness of anystatic analysis depends on how accurate an inference technique is in discoveringpotential vulnerable code. Thus, we are motivated to classify current static-analysis-related works based on the underlying inference techniques into four types: tainteddata-flow-based, constraint-based, annotation-based, and string-pattern-matching-based techniques. We describe these inference techniques in Sections 4.2–4.5. Wediscuss open issues in Section 4.6.

4.1. Comparative Analysis of Static Analysis Approaches

Table V provides a comparative summary of the static analysis works related to pro-gram security based on seven aspects. We now discuss these features in the followingsubsections.

4.1.1. Inference Type. The core part of any static analysis is to infer potential vulner-abilities by scanning program code. We divide inference types into four categories asshown in Table V. These are tainted data flow [Jovanovic et al. 2006; Lam et al. 2008;Livshits and Lam 2005; Wassermann and Su 2007], constraint [Le and Soffa 2008;Weber et al. 2001; Xie et al. 2003], annotation [Dor et al. 2003; Hackett et al. 2006;Evans and Larochelle 2002], and string-pattern-matching-based [Tevis and Hamilton2006; Viega et al. 2002; Dekok 2007] approaches. We discuss these inference types inSections 4.2–4.5.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:19

Tabl

eV.

Com

paris

onS

umm

ary

ofS

tatic

Ana

lysi

sA

ppro

ache

sfo

rM

itiga

ting

Sec

urity

Vul

nera

bilit

ies

Wor

kIn

fere

nce

type

An

alys

isse

nsi

tivi

tyA

nal

ysis

leve

lC

ompl

eten

ess

Sou

ndn

ess

Vu

lner

abil

ity

cove

rage

Lan

guag

eD

oret

al.[

2003

]A

nn

otat

ion

Poi

nts

-to

Intr

a-pr

oced

ura

lYe

sN

oB

OF

CH

acke

ttet

al.

[200

6]A

nn

otat

ion

N/A

Inte

r-pr

oced

ura

lN

oN

oB

OF

C

Le

and

Sof

fa[2

008]

Con

stra

int

Con

text

,pat

hIn

ter-

proc

edu

ral

No

No

BO

FC

Tev

isan

dH

amil

ton

[200

6]

Str

ing

patt

ern

mat

chin

gN

/AS

tate

men

tN

oN

oB

OF

x86

Vie

gaet

al.

[200

2]S

trin

gpa

tter

nm

atch

ing

N/A

Tok

enN

oN

oB

OF

C,C

++

Web

eret

al.

[200

1]C

onst

rain

tC

onte

xt,c

ontr

olfl

owS

yste

mde

pen

den

cegr

aph

No

No

BO

FC

Xie

etal

.[20

03]

Con

stra

int

Con

text

,pat

h,

poin

ts-t

oIn

tra-

proc

edu

ral,

inte

r-pr

oced

ura

lYe

s3N

oB

OF

C

Jova

nov

icet

al.

[200

6]T

ain

ted

data

flow

Con

text

,con

trol

flow

Inte

r-pr

oced

ura

lN

oN

oS

QL

I,X

SS

PH

P

Lam

etal

.[20

08]

Tai

nte

dda

tafl

owC

onte

xt,p

oin

ts-t

oS

tate

men

tN

oYe

sS

QL

I,X

SS

Java

Liv

shit

san

dL

am[2

005]

Tai

nte

dda

tafl

owC

onte

xt,p

oin

ts-t

oS

tate

men

tN

oYe

sS

QL

I,X

SS

Java

Was

serm

ann

and

Su

[200

8]T

ain

ted

data

flow

N/A

Intr

a-pr

oced

ura

lN

oN

oX

SS

PH

P

Sh

anka

ret

al.

[200

1]T

ain

ted

data

flow

N/A

Intr

a-pr

oced

ura

l,in

ter-

proc

edu

ral

No

No

FS

BC

Ch

enan

dW

agn

er[2

007]

Tai

nte

dda

tafl

owC

onte

xt,fi

eld

Sta

tem

ent

No

No

FS

BC

,C++

Dek

ok[2

007]

Str

ing

patt

ern

mat

chin

gN

/AS

tate

men

tN

oN

oF

SB

C

Was

serm

ann

and

Su

[200

7]T

ain

ted

data

flow

N/A

Intr

a-pr

oced

ura

lN

oYe

sS

QL

IP

HP

(Con

tin

ued

)

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:20 H. Shahriar and M. Zulkernine

Tabl

eV.

(Con

tinue

d)

Wor

kIn

fere

nce

type

An

alys

isse

nsi

tivi

tyA

nal

ysis

leve

lC

ompl

eten

ess

Sou

ndn

ess

Vu

lner

abil

ity

cove

rage

Lan

guag

eF

law

fin

der

[201

0]S

trin

gpa

tter

nm

atch

ing

Con

text

Tok

enN

oN

oB

OF,

FS

BC

,C++

Wag

ner

etal

.[2

000]

Con

stra

int

N/A

Sta

tem

ent

No

No

BO

FC

Xie

and

Aik

en[2

006]

Tai

nte

dda

tafl

owC

onte

xt,c

ontr

olfl

owB

lock

,in

tra-

proc

edu

ral,

inte

r-pr

oced

ura

l

No

No

SQ

LI,

XS

SP

HP

Eva

ns

and

Lar

och

elle

[200

2]

An

not

atio

nC

ontr

olfl

owS

tate

men

tN

oN

oB

OF,

FS

BC

Tri

ppet

al.[

2009

]T

ain

ted

data

flow

Con

text

,fiel

d,po

ints

-to

Inte

r-pr

oced

ura

lN

oYe

sS

QL

I,X

SS

Java

,JS

P

Sot

irov

[200

5]T

ain

ted

data

flow

Val

ue

ran

geS

tate

men

t,da

tafl

ow,

inte

r-pr

oced

ura

lYe

sN

oB

OF

C

Gan

apat

hy

etal

.[2

003]

Con

stra

int

Con

text

,poi

nts

-to

Sys

tem

depe

nde

nce

grap

hN

oN

oB

OF

C

Yan

get

al.[

2003

]A

nn

otat

ion

Flo

wIn

tra-

proc

edu

ral,

Inte

r-pr

oced

ura

lN

oN

/AB

OF

C

Ash

craf

tan

dE

ngl

er[2

002]

Tai

nte

dda

tafl

owN

/AIn

tra-

proc

edu

ral,

Inte

r-pr

oced

ura

lN

oN

oB

OF

C

3T

he

auth

ors

repo

rtfa

lse

posi

tive

war

nin

gsdu

eto

the

erro

rin

thei

rim

plem

ente

dco

nst

rain

tso

lver

.We

beli

eve

that

thes

eer

rors

are

corr

ecta

ble

and

inde

pen

den

tof

thei

ror

igin

alap

proa

ch.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:21

4.1.2. Analysis Sensitivity. A common problem for a static analysis approach is that itgenerates false positive warnings to be examined manually. To reduce the numberof false positives or false negatives, an approach takes advantage of precomputed in-formation based on program code. Such information helps to perform more accuratedetection of vulnerabilities. We denote the dependency of such precomputed informa-tion as analysis sensitivity. From the third column of Table V, we notice that most of theanalysis techniques apply some kinds of sensitivity. We identify six types of sensitivity:control flow [Weber et al. 2001; Jovanovic et al. 2006; Evans and Larochelle 2002],path [Le and Soffa 2008; Xie et al. 2003], context [Le and Soffa 2008; Jovanovic et al.2006; Lam et al. 2008; Livshits and Lam 2005; Xie and Aiken 2006], field (or instance)[Tripp et al. 2009; Chen and Wagner 2007], points-to [Lam et al. 2008; Livshits andLam 2005], and value range [Sotirov 2005].

An approach is control flow sensitive if it performs an inference technique basedon statement execution sequence with respect to a control flow graph. Applying flowsensitivity decreases false positive warnings. For example, Weber et al. [2001] improvethe approach of Wagner et al. [2000] by employing a flow-sensitive analysis.

Program execution paths that can be derived from a control flow graph might notbe feasible. Sometimes, infeasible paths can be determined statically. If an analysisexplicitly excludes infeasible paths, we denote it as path sensitive. For example, Leand Soffa [2008] detect BOF vulnerabilities that are reachable within feasible programpaths. Xie et al. [2003] detect BOF due to pointer dereferences and buffer indexes infeasible program paths based on control flow graphs.

A context-sensitive analysis approach differentiates multiple call sites of a functionwith respect to supplied arguments. In contrast, a context-insensitive analysis ignoresmultiple calls of the same function with different arguments. Context insensitivity mayresult in some false positive warnings. For example, a program has two vulnerablelibrary function calls of strcpy (dest, src). In this case, the function copies the bufferpointed by src to the buffer pointed by dest. The first function call has a src stringwhose value is provided by a user, and the second call contains a constant stringwhose length can be determined statically to be less than that of the dest buffer. Acontext-insensitive analysis reports both of them as vulnerable. However, a context-sensitive analysis Flawfinder [2010] finds the former call as vulnerable and the latteras nonvulnerable.

An approach is said to be field (or instance) sensitive if different members of in-stantiated objects are considered as separate variables [Chen and Wagner 2007]. Fieldsensitivity allows reducing false positive warnings. For example, an object data type(e.g., struct of C language) has two member variables of character buffer. One of thebuffers contains untrusted data, while the other contains trusted data. Without fieldsensitivity, the entire instance of the structure would be considered untrusted (ortainted) as member variables are not distinguished.

A points-to analysis identifies a set of memory objects that might be pointed by agiven pointer variable present in program code. Points-to analysis itself is another di-rection of research and interested readers can consult the literature related to points-toanalysis [Hind 2001]. We restrict our discussion on four concepts that are relevant andused in detecting vulnerabilities: flow-sensitive, flow-insensitive, context-sensitive,and context-insensitive points-to analysis. In a flow-sensitive points-to analysis,a program’s control flow is taken into account. In contrast, in a flow-insensitivepoints-to analysis, statements can be analyzed in any order. Obviously, a flow-sensitivepoints-to analysis is more accurate than that of a flow-insensitive analysis. In acontext-sensitive points-to analysis, function calls accepting pointer type argumentsor returning pointers are analyzed separately. In contrast, in a context-insensitivepoints-to analysis, these function calls are considered identical. It is more appropriate

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:22 H. Shahriar and M. Zulkernine

to apply context-sensitive points-to analysis than context-insensitive analysis toobtain more precise information.

From Table V, we note that very few techniques apply points-to analysis (e.g., flow-insensitive points-to analysis [Dor et al. 2003]). Most of the BOF detection approaches(as shown in Table V) do not incorporate points-to analysis explicitly. However, someapproaches employ general assumption on pointer data types. For example, Wagneret al. [2000] assume that a pointer to a structure variable might point to all othersimilar structure variables present in a program. The assumption results in a hugenumber of false positive warnings. Xie et al. [2003] consider a limited number of pointerinformation such as a pointer pointing to a buffer and relative distance from the basesize of a buffer. However, if a pointer points to an unknown type of memory object,their analysis does not include such information. As a result, some real BOF might beundetected. Points-to analysis can be used to reduce false negatives (i.e., detect morevulnerabilities that would otherwise remain undetected). For example, Ganapathyet al. [2003] apply points-to analysis information while generating constraints onbuffers that are being dereferenced by pointer variables. As a result, function callshaving pointer to buffer arguments can be analyzed for detecting BOF vulnerabilities.

A value range analysis provides a lower and upper bound of a variable. The infor-mation is useful when function calls are supplied with unsanitized arguments thatrepresent buffer sizes. These arguments result in vulnerabilities, if their boundariesexceed expected ranges. For example, the value range analysis discovers that the upperbound of the size argument of memcpy function call is MAXINT (maximum value of aninteger). An approach might generate a BOF warning in this case [Sotirov 2005].

We notice that several works ignore sensitivity for the sake of achieving the highestlevel of scalability [Wagner et al. 2000]. The resultant insensitivity allows an approachto analyze large-scale programs that contain millions of lines of code. In contrast,adding sensitivity brings not only the benefit of increased precision in an analysis, butalso reduced a false positive rate in the warnings. Note that several works do not ex-plicitly discuss sensitivity or insensitivity that are indicated as N/A in Table V [Hackettet al. 2006; Tevis and Hamilton 2006; Viega et al. 2002; Wassermann and Su 2008].

4.1.3. Analysis Level. This feature indicates the representation of program code atwhich static analysis is performed. From Table V, we notice that static analysis hasbeen performed for different representations of programs. These include program to-ken [Viega et al. 2002; Flawfinder 2010], statement [Weber et al. 2001; Lam et al. 2008;Livshits and Lam 2005], block [Xie and Aiken 2006], intraprocedural [Dor et al. 2003;Wassermann and Su 2007, 2008], interprocedural [Tripp et al. 2009; Hackett et al.2006; Jovanovic et al. 2006], and System-Dependence Graph (SDG) [Ganapathy et al.2003] levels. Several works combine multiple granularities such as intraproceduraland interprocedural [Xie et al. 2003; Xie and Aiken 2006; Shankar et al. 2001].

A compiler performs lexical analysis which tokenizes program source-code to identifykeywords, variables, functions, etc. These tokens are used to detect vulnerabilities.

In a statement-level analysis, vulnerabilities are inferred by analyzing programstatements. Several works analyze the executable program code such as x86 [Tevisand Hamilton 2006]. However, such executable code is usually deassembled first tomake partially readable before performing an analysis at the statement level.

In an intraprocedural analysis, a program is analyzed based on either a control flowgraph or a data flow graph. Several works apply intraprocedural analysis to form asummary of sensitive variables [Dor et al. 2003] or specific conditions that are relatedto vulnerabilities [Xie et al. 2003].

An interprocedural analysis examines a function body as well as other function callsites present in the function by accessing the called functions. It is common to avoid

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:23

analyzing the same function multiple times by following a bottom-up analysis based ona call graph of a program (e.g., Xie et al. [2003]). In a call graph, each node representsa unique function and a directed edge from node a to b indicates that the functionrepresented as node a contains an invocation of the function represented by the node b.

In a System-Dependence Graph (SDG), a node represents a program point (e.g.,statement), and an edge represents dependency between two program points whichcan be two types: control flow and data flow. Note that a data flow analysis attempts tocompute the values of a data variable at different program points.

4.1.4. Completeness. An approach is said to be complete if it generates no false posi-tive warnings [Chen and Wagner 2007]. Table V shows that very few techniques arecomplete [Dor et al. 2003; Sotirov 2005]. However, the completeness depends on boththe underlying assumptions in an analysis and the types of vulnerabilities addressed.For example, Dor et al. [2003] detect all BOF vulnerabilities present in a programcaused by only string variables. However, they do not consider BOF vulnerabilities dueto pointers and aliases. Sotirov [2005] is complete under the assumption that mostBOF vulnerabilities occur through a set of known unsafe library function calls thataccept tainted arguments.

In practice, it is hard to develop an analysis technique that results in no false positivewarnings. We identify four common reasons that might contribute to an incompleteanalysis: analysis sensitivity, result interpretation, absence of semantic analysis, andassumption on program code.

Inference approaches based on insensitive analysis of control flow [Ganapathy et al.2003; Tevis and Hamilton 2006; Viega et al. 2002; Wagner et al. 2000; Livshits and Low2005; Flawfinder 2010; Dekok 2007], context [Evans and Larochelle 2002; Shankaret al. 2001], path [Wassermann and Su 2008], and points-to [Hackett et al. 2006;Weber et al. 2001] result in conservative analysis and generate a high number offalse positive warnings. Moreover, the imprecision of analysis sensitivity (e.g., flow-insensitive points-to analysis) contributes to false positive warnings [Tripp et al. 2009;Lam et al. 2008; Livshits and Lam 2005].

The result interpretation of an analysis can be blamed for false positive warnings.For example, the approach of Le and Soffa [2008] provides a set of program paths whichdo not include safe and infeasible paths. Thus, it is likely that some of the suspectedpaths in the set are not vulnerable.

If an approach solely relies on lexical analysis (i.e., absence of semantic analysis),false positive warnings are generated [Tevis and Hamilton 2006; Viega et al. 2002;Flawfinder 2010]. For example, all the unsafe ANSI C library function calls can bethought of as BOF vulnerabilities. However, an unsafe function call present inside acomment [Viega et al. 2002] cannot be exploited.

An analysis approach assumes that programmers write specific patterns of code inimplementations. The breaking of these assumptions results in false positive warnings.For example, reusing the same variable might lead to false positive warnings. A buffervariable might contain malicious inputs followed by a nonmalicious input before usingthe variable content (e.g., writing to an output console) [Chen and Wagner 2007]. Thebuffer is suspected to be vulnerable in the first usage and it remains suspected for therest of the program code. A program can also be written in an unusual way by storingmalicious data instead of terminating programs immediately which might result in afalse positive warning [Xie and Aiken 2006]. Moreover, a function might conditionallytake a kernel pointer instead of a user supplied pointer [Yang et al. 2003], where kernelpointer arguments are not vulnerable. Furthermore, an approach may rely on correctimplementation of functionalities (e.g., validation of inputs stored in buffers [Dor et al.2003]).

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:24 H. Shahriar and M. Zulkernine

Sometimes, assumptions are made on the effects of code which lead to false positivewarnings. An approach might not consider the effect of custom sanitization functions[Jovanovic et al. 2006]. The lack of consideration to the effect of arbitrary type castingof sensitive variables generates false positive warnings. For example, PHP allows avariable containing a malicious string be assigned a boolean value which is nonmali-cious [Wassermann and Su 2007]. Moreover, a program might type cast a signed integervariable to an unsigned integer variable. An unsigned integer should be checked onlyfor the upper bound before using the integer as an index of an array. An analysis canignore the type casting effect and generate a false positive warning while using anunsigned buffer index with no lower-bound value checking [Ashcraft and Engler 2002].

4.1.5. Soundness. An approach is sound if it has no false negatives [Chen and Wagner2007]. In other words, the approach does not leave any program vulnerability unre-ported. Table V shows that a very small number of works claim to be sound [Tripp et al.2009; Lam et al. 2008; Livshits and Lam 2005]. However, it depends both on vulnerabil-ity types and assumptions in their analyses. For example, a query-based analysis [Lamet al. 2008; Livshits and Lam 2005] is sound as long as the specified queries accuratelyrepresent vulnerability patterns. The approach of Tripp et al. [2009] is sound providedthat a user-specified maximum node limit (in a call graph analysis) allows reaching alltainted sinks.

The reasons for the approaches’ unsoundness vary widely. We classify the reasonsinto four types: language features, analysis sensitivity, result interpretation, and thescope of the problem.

Data types supported in programming languages might not be considered in theanalysis approaches. For example, the approach of Wagner et al. [2000] is not soundas their analysis does not generate warnings of BOF vulnerabilities caused by pointerarithmetic or complex data structures (e.g., union in C) having buffers as membervariables. The approach of Hackett et al. [2006] does not support global pointers andstructure fields having pointer data types. A recursive function call might be analyzedusing just a single pass while constructing a function’s summary in PHP which mightleave potential SQLI and XSS vulnerabilities unreported [Xie and Aiken 2006]. Theapproaches of Shankar et al. [2001] and Chen and Wagner [2007] are not sound as theydo not support tainted data flow analysis for the integer buffer data type. An integerarray containing a malicious a format string can be converted to a buffer characterfollowed by supplying it to a format function. No FSB warning would be reported inthose approaches.

Some approaches do not employ analysis sensitivity which introduces false negatives,for example, lack of points-to analysis [Le and Soffa 2008; Tevis and Hamilton 2006;Viega et al. 2002; Weber et al. 2001; Flawfinder 2010; Dekok 2007].

Some works only generate warnings if their analysis can infer certainly that vul-nerabilities are present in programs. This allows users to interpret results with highconfidence at the cost of missing actual vulnerabilities present in program code. Forexample, the approach by Xie et al. [2003] does not generate warnings, if their analysiscannot infer that accessing a buffer is unsafe.

To make an analysis approach manageable, some works explicitly limit their scopeof detection for a limited number of vulnerability types present in program code. Thus,they can be considered as not sound with respect to the unaddressed vulnerabilitytypes. For example, BOF might be present due to unsafe ANSI C library function calls,pointer arithmetic, accessing buffers through arbitrary buffer indexes and pointers,lack of null characters at the end of buffers, and user-defined functions containingflaws. Dor et al. [2003] detect all BOF vulnerabilities present in a program causedby only string variables and those accessed after null characters. The approach of

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:25

Evans and Larochelle [2002] cannot discover BOF caused by arbitrary buffer indexesand pointers. Xie et al. [2003] assume that most pointer arithmetic and conditionalexpressions present in branches and loops are linear. Thus, their approach does notreport BOF vulnerabilities that might occur through loops or branches containingnonlinear arithmetic. The approach of Wassermann and Su [2008] detects only storedand reflected XSS attacks and does not analyze program code generated at browsers toidentify DOM-based XSS attacks. Ashcraft and Engler [2002] assume that an integer-variable-bound checking must be present before accessing a buffer through the integerindex variable. However, they allow a variable to compare with any numbers as opposedto a correct value. Thus, a real BOF present in a program might not be identified.

4.1.6. Vulnerability Coverage. This feature indicates what vulnerabilities are detectedby an approach. From Table V, it is obvious that BOF, FSB, SQLI, and XSS have beenaddressed by existing approaches [Dor et al. 2003; Viega et al. 2002; Weber et al. 2001;Xie et al. 2003]. However, no work has addressed CSRF vulnerabilities and very fewapproaches can detect multiple vulnerabilities [Tripp et al. 2009; Jovanovic et al. 2006;Evans and Larochelle 2002].

4.1.7. Language. This feature highlights the programming languages that are sup-ported by an analysis approach. We notice that most techniques analyze programsimplemented in C and Java languages [Dor et al. 2003; Hackett et al. 2006; Viegaet al. 2002; Xie et al. 2003]. A number of works analyze server-side programs writtenin scripting languages such as ASP and PHP [Jovanovic et al. 2006; Wassermann andSu 2007]. Very few approaches analyze executable code [Tevis and Hamilton 2006].

4.2. Tainted Data-Flow-Based Technique

In this technique, input variables are marked as tainted and their propagations aretracked. Warnings are generated if tainted inputs or values derived from tainted inputsare used in sensitive operations. We divide tainted data-flow-based works into fourcategories based on the tainting mechanism: static data type, implicit, grammar-based,and query-based tainting. They are described in the following subsections.

4.2.1. Static Data Type Tainting. In this technique, tainted information is marked by ex-tending variable type information. This is also known as a type qualifier approach.The approach takes advantage of statically declared data types supported by pro-gramming languages. In particular, the technique requires adding new labels to datavariables which might represent vulnerable (“tainted”) or nonvulnerable (“untainted”)input sources. Then the approach checks whether a labeled source or any value derivedfrom a labeled source participates in sensitive operations (e.g., a data buffer containinguser-supplied inputs is passed to a format function call) or not. If such a case is iden-tified, a vulnerability warning is generated. For example, Shankar et al. [2001] andChen and Wagner [2007] detect FSB vulnerabilities, if tainted format strings are usedin format function calls. Their approaches label trustworthy function parameters as“untainted” and untrustworthy parameters as “tainted” initially. For example, Shankaret al. [2001], find that the main function of a program might be marked as follows intmain (int argc, tainted char *argv[]).

Type checking is a popular approach to infer vulnerabilities. In a traditional typechecking system, errors are reported by a compiler if the type of a variable or expressionmismatches with the expected one. However, in a type qualifier system, warningsare raised if a variable’s type in an expression mismatches with an expected typeaccording to a qualifier lattice. A qualifier lattice is developed by a programmer beforean analysis that represents subtyping relationships among different variables. Thesubtyping relationship is analogous to the relationship between a class and a subclass of

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:26 H. Shahriar and M. Zulkernine

object-oriented programming [Shankar et al. 2001]. For example, if Q is a subclass ofP (expressed as Q < P), then an object of class Q can be used whenever an object ofclass P is expected, but not vice versa. In the context of vulnerability detection, thesubtyping “untainted char < tainted char” can be used to detect FSB. It indicates thatan expression (e.g., a format function parameter labeled as “untainted”) expecting anuntainted variable generates a warning if a tainted variable is passed. However, if anuntainted variable is supplied, no warning is generated.

4.2.2. Implicit Tainting. In this technique, program variables are not explicitly labeledas tainted. This approach is suitable for languages where there are no static typedeclarations in the code (e.g., PHP). The tainted information flow is performed basedon precomputed program information such as data flow and control flow graph. Forexample, Jovanovic et al. [2006] mark data as tainted if they are derived from userinputs (e.g., HTTP requests). They apply data flow analysis to identify locations wheresuspected tainted data reach to sensitive sinks.

A variation of the approach is to pass tainted information from one level to another.For example, Xie and Aiken [2006] apply three levels of static analysis based on thecontrol flow graph of a given program. They summarize and pass information fromblock to intraprocedural and intraprocedural to interprocedural levels. Basic blocks aresimulated by symbolic execution to form summaries such as error set (input variablesthat must be sanitized) and untainted sets (locations for each successor of a block).This information is applied to perform intraprocedural analysis which summarizesa function such as sanitized values (set of parameters and global variables that aresanitized on function exit). The summaries obtained from intraprocedural analysis areapplied to interprocedural analysis. The interprocedural analysis generates warningsif any unsanitized variable is applied to a sensitive operation such as SQL querygeneration.

Implicit tainting has been applied to programs written in typed languages suchas Java and JSP (e.g., taint analysis for Java or TAJ [Tripp et al. 2009]). Tainteddata can be tracked using a variation of a slicing algorithm known as hybrid thinslicing. The slice captures statements relevant to tainted data flows. It is a forwardslicing from a statement s which identifies a set of statements that are data-dependanton s. The analysis is performed by a set of security rules of the form (S1, S2, S3),where S1, S2, and S3 represent a tainted or untrusted source, a sanitizer, and a sink,respectively. A sink is a pair of a method name and a set of parameters that arevulnerable to injection attacks. The approach checks whether a source is passed to asink without sanitization or not. Compared to other taint-based approaches, the slicingalong with points-to analysis of objects can discover vulnerabilities in programs thathave reflection (a technique where a method can be invoked by Class.forName andMethod.invoke properties in Java) and object containers (e.g., HashMap).

Ashcraft and Engler [2002] also apply a tainted data-flow-based technique to detectBOF vulnerabilities by identifying tainted integer variables (derived from networkpackets, user data) that are used as array indexes, loop bounds, and length parametersof sensitive functions (e.g., memcpy).

4.2.3. Grammar-Based Tainting. Tainted data flow can be tracked by grammar produc-tion rules where nonterminals can be marked as tainted. These nonterminals areuser-supplied inputs. This approach requires normalizing program source-code intoStatic Single Assignment (SSA) form. In an SSA form, each statement is expressedas an assignment statement where the left-hand side sets a variable at most once.For example, a PHP statement “echo $out” that outputs the value of variable output(out) can have SSA form as “data1 = out” [Wassermann and Su 2008]. Here, data1 isintroduced as part of SSA which can be further transformed as a production rule like

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:27

“data1 → out”. Now, data1 is a nonterminal for the production rule and out might beeither a terminal or nonterminal. The grammar rules obtained from SSA implicitlyencode data flow information among nonterminals.

While generating grammar production rules, nonterminals are marked as tainted ifthey are obtained from user inputs. The resulted rules form an extended context-freegrammar. The core part of an approach involves performing string analysis for san-itization routines by modeling their operations through finite state transducers (i.e.,finite state machines where transitions result outputs). If tainted inputs are sanitized,the outputs are expressed as regular expressions. Moreover, tainted markings are re-moved from the related rules to make a context-free grammar. The regular expressiongenerated by a context-free grammar and by a sanitization routine is intersected toidentify another regular expression that is allowed by a program. If part of attack sig-natures or malicious scripts can be constructed from an intersected regular expression,then a warning is generated. Wasserman and Su apply this approach to detect SQLI[Wassermann and Su 2007] and XSS [Wassermann and Su 2008] vulnerabilities.

4.2.4. Query-Based Tainting. All the taint-based techniques discussed so far provide nooptions to testers or programmers to check vulnerabilities of their choices. Query-based tainting is a step forward to mitigate this limitation. In this technique, a queryspecifies source objects and rules to transform sources to sink objects. A source objectcontains supplied inputs. A derived object uses a source object and propagates througha path which might reach to a sink object. A sink object is considered tainted if it isderived from zero or more times from a source object. Lam et al. [2005, 2008] developthe Program Query Language which allows programmers to specify queries relatedto vulnerable information flow. They apply the technique to discover SQLI and XSSvulnerabilities in Web-based programs.

4.3. Constraint-Based Technique

The Constraint-Based Technique (CBT) generates safety constraints from programcode whose violations imply vulnerabilities. Constraints are propagated and updatedwhile traversing a program. A program can be traversed based on system-dependencegraphs [Weber et al. 2001] and control flow graphs [Xie et al. 2003; Xie and Aiken2006]. At the end, the analysis identifies whether any solution of a set of obtainedconstraints exists or not. Obtaining a solution indicates that an exploitation is possiblethrough input values. Constraint solvers are used to compute input values which violateconstraints. Most works leverage integer type constraint solvers for detecting BOFvulnerabilities [Weber et al. 2001; Xie et al. 2003; Wagner et al. 2000].

CBT has been applied for procedural languages which have static data types and richdata structures that cause vulnerabilities. Several works have applied CBT techniquesto detect BOF vulnerabilities in C programs. We divide constraint-based techniquesinto three categories for BOF detection: integer range analysis, symbolic execution,and demand-driven.

4.3.1. Integer Range Analysis. The idea of this technique is to formulate constraints byscanning each program statement containing buffer declarations and buffer-relatedoperations. Each constraint is expressed in terms of a pair of integer ranges (bufferallocation size and current size of a buffer) for each buffer defined or accessed. For eachbuffer, a set of constraints is solved to find a range of allocation and current size, whichcan be denoted as [a, b] and [c, d], respectively. Here, [a, b] implies that allocation sizeof a buffer can vary from a bytes to b bytes, and [c, d] implies that current size of abuffer can vary from c bytes to d bytes. The two ranges can be analyzed to identifynonvulnerable (i.e., b > c) and vulnerable (i.e., b ≤ c) statements.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:28 H. Shahriar and M. Zulkernine

Wagner et al. [2000] first apply integer range analysis to detect BOF vulnerabilities.Later, Weber et al. [2001] improved Wagner’s method by applying a flow-sensitiveanalysis of BOF to reduce the number of false positive warnings. In addition, theydetect BOF due to global variable usages, function calls, and recursions. Ganapathyet al. [2003] generate constraints on buffer sizes and allocations using an SDG andsolve the constraints using linear programming.

4.3.2. Symbolic Value Analysis. In this technique, a constraint contains program vari-ables and whenever possible their values are assigned. Otherwise, they are consideredas symbolic values. Xie et al. [2003] apply symbolic value analysis to detect BOF vul-nerabilities caused by invalid buffer indexes, pointer dereferences, and invalid functionarguments (buffer addresses and sizes). They traverse a call graph of a program usinga bottom-up approach, where a function is analyzed through a Control Flow Graph(CFG). During the CFG analysis, at every access to arrays, pointer dereferences, andfunction calls, safety constraints (negation of valid conditions) are generated. More-over, constant relations (e.g., x = 4) and symbolic constraints between variables (e.g.,x < y) are captured and propagated. At every potentially dangerous access of arrays,pointer dereferences, or call to routines, a custom constraint solver is used to evaluatethe values against safety constraints. A warning is generated if a solution can be foundfor a safety constraint.

4.3.3. Demand-Driven. Most constraint-based techniques limit their scopes by provid-ing a list of warnings based on built-in constraint generation, propagation, and solutionmechanisms. However, a recent direction is to provide a programmer the option to for-mulate queries on vulnerable program locations. This is also denoted as demand-drivenanalysis. The approach relies on constraint generation, which starts from a locationspecified by developers. The end output can be a set of prioritized paths that mighttrigger BOF.

Le and Soffa [2008] apply this approach to detect different types of paths (e.g.,infeasible, safe, user-input-dependant, vulnerable) vulnerable to BOF. A user specifiesqueries to know whether: (i) buffer accesses at particular program points are safe, and(ii) user inputs can write to buffers. The queries are expressed with constraints in termsof buffer sizes, supplied string lengths, and flag values (to represent constant stringvalues). The queries are propagated along program paths in backward directions (i.e.,starting from the point of query to the beginning of a program’s main function call)through interprocedural and context-sensitive analyses. If queries can be resolved bychecking whether a declared buffer size is less than the supplied input values, a BOFwarning is generated.

4.4. Annotation-Based Technique

In an annotation-based technique, program code is annotated with desired propertiesin terms of pre- and postconditions. Annotations can be specified at both function pro-totype declaration [Dor et al. 2003; Hackett et al. 2006; Evans and Larochelle 2002]and statement level [Evans and Larochelle 2002]. After a piece of code is annotated,an algorithm checks whether data variables can be used safely based on the anno-tated conditions or not. In this case, a function call site is evaluated to check whetherit conforms to specified preconditions or not. If preconditions are satisfied at the callsite, the function body is further examined to ensure that the implementation meetsspecified postconditions. If a precondition cannot be resolved from a previous state-ment’s postcondition, then a warning message is generated. Warnings generated by anapproach might be prioritized based on how well the constraints for accessing buffersare understood. For example, no condition to access a buffer is listed at the top of a

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:29

warning list, whereas buffer access based on a condition on buffer length is placed atthe bottom of a warning list.

Annotation-based approaches generate constraints from the specified pre- and post-conditions. However, these constraints are evaluated to be true or false to identifywhether a program location is free from vulnerability or not. In contrast, a constraint-based approach solves a set of constraints for further analysis. We also note that tainteddata flow analysis might rely on annotating program code such as function prototypes[Sotirov 2005]. However, these annotations are not involved in generating constraintslike the annotation-based approaches. Rather, the annotation facilitates comparing anexpected data type (annotated) with an identified data type (through static analysis)to infer vulnerabilities.

Annotations can be specified by expressions supported by an implementation lan-guage. For example, Dor et al. [2003] detect all string manipulation errors that leadto BOF vulnerabilities by specifying contracts (or annotations) through C expressions.Contracts include preconditions, postconditions, and specific side-effects. After addingannotations, a source-to-source semantic preserving transformation of a given pro-cedure is performed. The converted program code generates errors if contracts areviolated. However, the pre- and postconditions expressed through implementation lan-guage expressions can detect limited types of BOF vulnerabilities such as accesses tobuffers after the null-termination bytes.

Several works have detected a wide range of BOF vulnerabilities either by introduc-ing an annotation language or by extending an implementation language. For example,Hackett et al. [2006] develop an annotation language named SAL that allows express-ing buffer annotations to describe buffer interfaces through pointers. The annotationof buffer variables might include usage (e.g., a buffer passed to a function and readfrom), optional (e.g., pointer can be NULL), extent of an initialization (i.e., a lowerinitialization bound), and capacity (i.e., a lower capacity bound). In contrast, Evansand Larochelle [2002] annotate function parameters, return values, global variables,and structure fields inside tagged comments in C programs. For example, the /*@not-null@*/ tag before a parameter indicates that any value passed to the parametershould not be NULL. BOF vulnerabilities are detected by adding pre- and postcondi-tions to user-defined and ANSI C library functions. For example, the library functionstrcpy(s1, s2) copies the source buffer s2 to the destination buffer s1. The precondition/*@requires maxSet(s1) ≥ maxRead(s2)@ ∗ / generates an error message, if it cannotbe satisfied at the call site by a checker. Here, the precondition indicates that themaximum index value that can safely access s1 (maxSet(s1)) during a write operationmust be greater than or equal to the maximum index value that can safely accesss2(maxRead(s2)) during a read operation.

An annotation language that provides flexibility and features to annotate largeamount of source-code can reduce the burden of annotating program code. Yang et al.[2003] develop an annotation language named MECA in this direction. For example,the statement “annot tainted annotates ($variable)” specifies that tainted annotation tobe used to bind to any local and global variable, a function’s parameter, and the returnvalue of a function. MECA can bind multiple annotations with a variable (e.g., checkingboth src and dest pointer parameters with the len parameter in a memcpy(dest, src, len)function call). Moreover, the language allows expressing conditional annotations (e.g.,annotate a variable as tainted based on specific parameters of function calls).

4.5. String-Pattern-Matching-Based Technique

The pioneer static analysis approaches [Tevis and Hamilton 2006; Viega et al. 2002;Flawfinder 2010; Dekok 2007] are based on a simple string pattern matching tech-nique. These approaches rely on a known set of library function calls that might cause

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:30 H. Shahriar and M. Zulkernine

vulnerabilities. A set of rules are developed which represent the signature of vulnera-ble code patterns. In this technique, program code is tokenized and scanned to identifyvulnerable patterns of strings that represent vulnerable function calls and arguments.For example, ITS4 [Viega et al. 2002] and Flawfinder [2010] analyze tokenized pro-gram code to detect potential vulnerabilities. Dekok [2007] detects FSB vulnerabilitiesin printf family functions by examining patterns of vulnerable format function callswhich include the format string supplied through variables and format strings suppliedas the last argument.

A recent variation of the string-pattern-matching-based technique is to scan ex-ecutable program code to detect vulnerable function calls. For example, Tevis andHamilton [2006] analyze Portable Executable (PE) files that run on Windows NT/XPto detect BOF vulnerabilities. They detect BOF vulnerabilities by identifying the pres-ence of vulnerable ANSI C library function names in a symbol table and the occurrenceof zero filled regions of 50 bytes or more. These regions can be used to load maliciouscode during BOF attacks.

4.6. Summary and Open Issues

We notice that introducing analysis sensitivity and performing analysis on finer gran-ular levels of program code results in better detection of vulnerabilities. Most of thecurrent approaches lack completeness, soundness, or both of the properties. Analysisprecision and scalability is a trade-off factor in current analysis approaches. Many ap-proaches suffer high false positive rates. Future static analysis approaches may focusin several directions such as addressing the vulnerabilities which are underresearchedand improving the completeness and soundness properties. We also notice that most ofthe analysis techniques are geared towards high-level languages such as C, Java, andPHP. Few works perform static analysis at intermediate object code and executablecode level. Thus, new analysis techniques for programs should be developed in othercommon languages such as ASP and JavaScript.

From the discussions on inference techniques, we note that each inference mecha-nism is valuable from certain perspectives. For example, the annotation-based mecha-nism is useful to verify that certain vulnerabilities are not present, whereas demand-driven and query-based tainting can help locating prioritized vulnerabilities that mustbe addressed immediately. Our study indicates that constraint, annotation, and string-pattern-matching-based inferences currently detect a limited type of vulnerabilitiessuch as BOF, FSB, and SQLI. Thus, future works should improve the current techniquesfor detecting other vulnerability types such as XSS and CSRF. New approaches canalso combine multiple techniques to detect unaddressed vulnerabilities and increasedetection accuracies. Another research direction is to apply appropriate analysis leveland sensitivity for different inference techniques. Moreover, performing static analysisbased on the presence of improper sanitization APIs can be investigated further fordifferent vulnerabilities.

5. HYBRID ANALYSIS

Although static analysis techniques detect vulnerable code in programs, they all suffera common disadvantage which is numerous false warning reports. As a result, a testeror programmer has to spend significant amounts of time for examining warnings withactual input test cases. Thus, merely depending on the static analysis results mightnot be practically feasible to detect and fix all suspected vulnerabilities in large-scaleprograms. Many approaches have attempted to improve this situation by automaticallyexamining suspected vulnerable code. These approaches combine static analysis tech-niques with complementary dynamic analysis techniques [Ernst 2003]. In this case, adynamic analysis is intended to verify the actual exploitation of vulnerable code with

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:31

input test cases. A dynamic analysis is an active analysis technique where programstates are observed to confirm vulnerability exploitations [Guo 2006]. Program statesinclude a wide range of entities during a program execution such as the values of de-clared variables, structure fields, and contents of memory locations. The combinationof static and dynamic analysis is known as a hybrid analysis technique.

In general, a hybrid analysis technique strives to avail the advantages of both staticand dynamic analyses. The static analysis identifies the locations of program codethat need to be analyzed during program executions to verify actual exploitations ofvulnerabilities. This reduces the number of suspected vulnerabilities reported by astatic analysis technique that need to be examined further. Note that the vulnerabilitymitigation capability of any hybrid analysis technique fairly depends on the inferencetechnique of a static analysis. For example, a static analysis might not identify programcode as vulnerable. As a result, the subsequent dynamic analysis cannot find anysecurity breaches in that code. Moreover, obtaining or generating required test casesthat can reach the vulnerable locations during a program execution might not bedirectly addressed by a hybrid analysis technique. Rather, complementary mitigationtechniques such as test case generation can address that issue.

In the following section, we compare hybrid analysis works that mitigate programsecurity vulnerabilities based on seven features: dynamic analysis objective, programstate utilization, static inference, analysis level, static information, vulnerability cover-age, and language addressed. Note that the lack of discussion on “completeness” and“soundness” of the underlying static analysis techniques by the original authors of therelated works prevents us to include these features in our comparative discussions.The most important step for a hybrid analysis is to actively examine program enti-ties to confirm suspected vulnerabilities based on dynamic analysis objectives. Theobjectives are related to program states at runtime. Thus, we are motivated to classifyhybrid analysis works based on dynamic analysis objectives into four types: programoperation, code structure integrity, code execution flow, and unwanted value. They aredescribed in Sections 5.2–5.5. Finally, we discuss open issues in Section 5.6.

5.1. Comparison of Hybrid Analysis Approaches

We compare hybrid analysis works based on seven features: dynamic analysis objective,program state utilization, static inference, analysis level, static information, vulner-ability coverage, and language addressed. A summary of the comparison is shown inTable VI, while we describe these features in the following paragraphs.

5.1.1. Dynamic Analysis Objective. This feature describes what attribute of a programis checked to detect attacks during a dynamic analysis phase. As can be seen fromTable VI, program operation [Aggarwal and Jalote 2006; Castro et al. 2006], codestructure integrity [Halfond et al. 2005; Wei et al. 2006], code execution flow [Balzarottiet al. 2007], and unwanted value [Johns and Beyerlein 2007; Lucca et al. 2004] areexamined in different hybrid approaches. Program operation checks whether memoryallocations, releases, and accesses are performed in valid memory regions or not. Thecode structure integrity attribute validates the known structure of program code in adynamic analysis. The code execution flow checks whether an intended program pathcan be altered or not without modifying related program states such as session id andcookie. The unwanted value attribute checks the presence of unwanted values in pro-gram inputs and outputs. We provide the details of these objectives in Sections 5.2–5.5.

5.1.2. Program State Utilization. To detect an attack, a program state needs to becompared with a known program state under attack. These known states are derivedthrough information extraction or addition of program sources. We denote suchderivation characteristics as program state utilization. Depending on the types of

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:32 H. Shahriar and M. Zulkernine

Tabl

eV

I.C

ompa

rison

Sum

mar

yof

Hyb

ridA

naly

sis

Wor

kson

Pro

gram

Sec

urity

Vul

nera

bilit

ies

Dyn

amic

anal

ysis

Pro

gram

stat

eV

uln

erab

ilit

yW

ork

obje

ctiv

eu

tili

zati

onS

tati

cin

fere

nce

An

alys

isle

vel

Sta

tic

info

rmat

ion

cove

rage

Lan

guag

eA

ggar

wal

and

Jalo

te[2

006]

Pro

gram

oper

atio

n(u

nsa

fefu

nct

ion

call

s)

Add

itio

n(s

usp

icio

us

scor

esfo

rpo

inte

rsan

dal

iase

s)

Tai

nte

dda

tafl

owS

tate

men

t,co

ntr

olfl

owF

un

ctio

nca

lls

hav

ing

poin

ter

and

alia

sar

gum

ents

BO

FC

Cas

tro

etal

.[20

06]

Pro

gram

oper

atio

n(m

emor

yre

ad)

Ext

ract

ion

(all

owab

lede

fin

itio

nse

t)

Un

tain

ted

data

flow

Dat

afl

owL

ist

ofva

riab

les

that

mig

ht

mod

ify

valu

esB

OF,

FS

BC

Ku

mar

etal

.[20

09]

Pro

gram

oper

atio

n(m

emor

yre

adan

dw

rite

)

Ext

ract

ion

(bas

ean

dsi

zeof

allo

cate

dm

emor

ybl

ocks

)

Str

ing

patt

ern

mat

chin

gS

tate

men

tM

emor

yal

loca

tion

tabl

e(M

AT

)B

OF

x86

Mon

gaet

al.[

2009

]U

nw

ante

din

put

(met

ach

arac

ters

)

Add

itio

n(s

tore

tain

tla

bels

ofu

ntr

ust

edin

puts

)

Tai

nte

dda

tafl

owIn

ter-

proc

edu

ral

con

trol

flow

Pro

gram

path

san

dst

atem

ents

that

mod

ify

sen

siti

vesi

nks

SQ

LI,

XS

SP

HP

Bal

zaro

ttie

tal

.[2

007]

Cod

eex

ecu

tion

flow

Ext

ract

ion

(val

idpr

ogra

mpa

ths)

Un

tain

ted

data

flow

Intr

a-pr

oced

ura

l,in

ter-

proc

edu

ral

Mod

ule

view

san

din

ten

ded

wor

kflow

sS

QL

I,X

SS

PH

P

Hal

fon

det

al.

[200

5]C

ode

stru

ctu

rein

tegr

ity

(SQ

L)

Ext

ract

ion

(val

idS

QL

quer

ym

odel

s)

Str

ing

patt

ern

mat

chin

gS

tate

men

tV

alid

SQ

Lqu

ery

mod

els

SQ

LI

JSP

Hal

fon

det

al.

[200

6a]

Cod

est

ruct

ure

inte

grit

y(S

QL

)A

ddit

ion

(mar

kh

ard

code

dst

rin

gs)

Str

ing

patt

ern

mat

chin

gS

tate

men

tT

rust

edst

rin

gsS

QL

IJa

vaby

teco

deJo

hn

san

dB

eyer

lein

[200

7]U

nw

ante

dva

lue

(in

ject

edsc

ript

code

)

Add

itio

n(r

epla

cekn

own

code

wit

hto

ken

s)

Str

ing

patt

ern

mat

chin

gS

tate

men

tP

rogr

amm

erw

ritt

ensc

ript

code

SQ

LI,

XS

SP

HP

Wei

etal

.[20

06]

Cod

est

ruct

ure

inte

grit

y(S

QL

)E

xtra

ctio

n(F

SM

ofqu

erie

sw

ith

out

inpu

ts)

Str

ing

patt

ern

mat

chin

gC

ontr

olfl

owgr

aph

Iden

tify

SQ

Lqu

erie

sS

QL

IN

/A

Mu

thu

pras

ann

aet

al.[

2006

]C

ode

stru

ctu

rein

tegr

ity

(SQ

L)

Ext

ract

ion

(SQ

L-F

SM

)S

trin

gpa

tter

nm

atch

ing

Inte

r-pr

oced

ura

lS

QL

fin

ite

stat

em

ach

ine

(SQ

L-F

SM

)S

QL

IJa

va

Lu

cca

etal

.[20

04]

Un

wan

ted

valu

e(m

eta

char

acte

rs)

Add

itio

n(e

xpec

ted

outp

ut

mes

sage

s)T

ain

ted

data

flow

Con

trol

flow

grap

hT

ain

ted

sou

rces

and

sen

siti

vesi

nks

XS

SA

SP

Rin

gen

burg

and

Gro

ssm

an[2

005]

Pro

gram

oper

atio

n(f

orm

atfu

nct

ion

call

s)

Ext

ract

ion

(val

idm

emor

yad

dres

ses)

Str

ing

patt

ern

mat

chin

gD

ata

flow

Wh

ite

list

edm

emor

ylo

cati

ons

FS

BC

Yon

gan

dH

orw

itz

[200

3]P

rogr

amop

erat

ion

(mem

ory

read

orw

rite

)

Add

itio

n(t

aggi

ng

mem

ory

loca

tion

s)S

trin

gpa

tter

nm

atch

ing

Sta

tem

ent

Un

safe

poin

ter

dere

fere

nce

san

dle

giti

mat

em

emor

y

BO

FC

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:33

vulnerabilities and dynamic analysis objectives, we divide program state utilizationinto two categories: information extraction [Castro et al. 2006; Balzarotti et al. 2007;Halfond et al. 2005] and information addition [Aggarwal and Jalote 2006; Monga et al.2009; Johns and Beyerlein 2007]. The third column of Table VI shows the category ofprogram state utilization for each of the work along with particular information.

Program code can be analyzed to extract useful information to detect attacks dur-ing a dynamic analysis phase. For example, Ringenburg and Grossman [2005] extractwhitelists to prevent FSB attacks that write to invalid memories through malicious%n specifiers. Castro et al. [2006] extract a reaching definition instruction set for ev-ery variable usage. A definition table is updated on every memory write operation(i.e., definition). The table can detect BOF and FSB attacks which define variablesnot included in the reaching definition instruction set. Balzarotti et al. [2007] extractall valid paths that a user traverses during a program’s execution. During code injec-tion attacks, these paths might not be traversed. Halfond et al. [2006a] mark trustedstrings in programs which are mainly hard-coded strings written by programmers andinclude SQL keywords, operators, and literals. These trusted strings help to detectSQLI attacks by checking whether certain parts of SQL queries include trusted stringsor not. Valid SQL query models are extracted through Finite State Automata (FSA)[Wei et al. 2006; Muthuprasanna et al. 2006] and NonDeterministic Finite Automata(NDFA) [Halfond et al. 2005] to detect SQLI vulnerabilities.

Information can be added in program code which can be retrieved later and comparedwith a future program state to detect attack. Aggarwal and Jalote [2006] assign a sus-picion score for pointers which are declared locally in functions or passed as argumentsto detect BOF. Yong and Horwitz [2003] mark memory allocation and free operations,global, and static variables with “appropriate” and “inappropriate” to tag legitimate andillegitimate memory locations, respectively, in a dynamic analysis. Lucca et al. [2004]add expected output messages to confirm XSS attacks in suspected files (or pages).These files are supplied with attack input cases and checked for expected responses.Monga et al. [2009] detect XSS in PHP-based programs by adding tainted labels to un-trusted input sources and these labels are propagated to variables derived from thesesources during computation. Program output locations are checked for the presence ofmalicious metacharacters in tainted variables. Kumar et al. [2009] add a Memory Allo-cation Table (MAT) to keep track of memory blocks and sizes to be used later for detect-ing BOF vulnerabilities. Johns and Beyerlein [2007] identify keywords in programmer-written script code and replace them with masks (random tokens). The masked key-words are unmasked before generating responses to prevent code injection exploits.

5.1.3. Static Inference. This feature indicates the underlying inference mechanismby which a location is identified as vulnerable without executing the code. Wereuse the same categorization for inference mechanisms that have been discussed inSections 4.2–4.5 (i.e., tainted data flow, constraint, annotation, and string patternmatching). Unlike traditional static analysis techniques, where inference mechanismsare applied to detect vulnerable code, a hybrid analysis often applies a lightweightstatic analysis, which primarily discovers information flow.

Table VI shows that three types of inference techniques are used: tainted data flow,string pattern matching, and untainted data-flow-based analysis. Tainted data flowand string-pattern-matching-based techniques have been discussed in Section 4. Here,we discuss untainted data-flow-based inference that has been used in several works[Castro et al. 2006; Balzarotti et al. 2007]. Untainted data flow represents the extractionof legitimate information that is valid in sensitive program operations (e.g., SQL queryexecution). For example, Castro et al. [2006] identify legitimate instruction sets thatcan define the value of a variable. Balzarotti et al. [2007] identify intended workflows

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:34 H. Shahriar and M. Zulkernine

by connecting valid views or program paths. The common characteristic between anuntainted and a tainted data flow is that both of them track flows of data. However,an untainted data-flow-based technique tracks valid data, whereas a tainted data-flow-based technique tracks suspected data. Sometimes, untainted data flow is alsomentioned as “positive tainted data flow”.

5.1.4. Analysis Level. This feature identifies what representation of program code isused in a static analysis phase. The analysis levels vary widely. These include statement[Halfond et al. 2005], control flow [Monga et al. 2009; Balzarotti et al. 2007], data flow[Castro et al. 2006], and combined granularities such as statement and control flow[Aggarwal and Jalote 2006].

5.1.5. Static Information. This feature indicates the information gathered during staticanalysis which is used in a dynamic analysis. In Table VI, we observe that collected in-formation depends not only on vulnerability types, but also on languages and analysistechniques. For example, BOF can be detected by identifying allocated memory blocksthrough MAT [Kumar et al. 2009], unsafe pointers used in memory write operations[Yong and Horwitz 2003], and unsafe library function calls having pointer arguments[Aggarwal and Jalote 2006]. However, injection vulnerabilities can be detected by iden-tifying trusted strings [Halfond et al. 2006a], hotspots [Halfond et al. 2005], finite statemachines of SQL queries [Wei et al. 2006; Muthuprasanna et al. 2006], and the set ofstatements involved in generating malicious outputs [Monga et al. 2009].

5.1.6. Vulnerability Coverage. This feature indicates what vulnerabilities are detected inhybrid analysis approaches. Table VI shows that most approaches address Web-basedvulnerabilities such as SQLI and XSS [Monga et al. 2009; Halfond et al. 2005; Johnsand Beyerlein 2007]. Moreover, BOF and FSB vulnerabilities have been addressedby several works [Aggarwal and Jalote 2006; Castro et al. 2006; Kumar et al. 2009;Ringenburg and Grossman 2005].

5.1.7. Language. This feature indicates programming languages that are supportedin hybrid analysis approaches. As can be seen in Table VI, most works analyze codewritten in either server-side scripting languages (e.g., PHP, JSP) or in procedurallanguages (e.g., C). Very few works analyze executable code [Kumar et al. 2009]. Amotivation behind analyzing high-level scripting languages is the availability of staticanalysis tools for those languages. For example, Balzarotti et al. [2007] perform intra-and interprocedural analysis with the help of the Pixy tool [Jovanovic et al. 2006] thatanalyze PHP code. Similarly, a high number of static analysis tools and algorithms areavailable for procedural languages.

5.2. Program Operation

In this technique, the static analysis phase identifies valid memory locations that canbe accessed, read, or written during program executions. During a dynamic analysisphase, these locations are checked for any operations performed outside the validmemory locations. For example, Castro et al. [2006] identify a set of instructions thatcan modify a variable value for each variable use in the data flow graph of a programduring static analysis. During the dynamic analysis, they check whether a value readhas been defined by a legitimate set of definitions or not. Ringenburg and Grossman[2005] perform static data flow analysis to generate whitelisted addresses wherewriting operations can be performed during format function calls. Any modificationoutside the registered addresses during format function calls are identified in anactive analysis. Yong and Horwitz [2003] identify dangerous pointer dereferences andlegitimate memory locations which pointers can point to during the static analysis.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:35

Programs are instrumented to check whether dereferences are pointing to legitimatememory locations or not. If any pointer is used to write or free an illegitimate location,then the instrumented program halts further execution.

Hybrid analysis can be applied to executable program code. However, a dynamicanalysis is performed first to map executable instructions with virtual addresses andidentify program operations related to vulnerability exploitations. Static analysis isperformed by decompiling the executable into object code. The object code can be an-alyzed to obtain attributes related to vulnerabilities such as allocated memory sizes.Finally, programs are executed with test cases to check whether vulnerabilities mightbe exploited based on the gathered information. Kumar et al. [2009] apply hybridanalysis of executable C programs to identify BOF vulnerabilities.

5.3. Code Structure Integrity

In this approach, a static analysis technique is applied to extract valid code structure.During a dynamic analysis, it is checked whether runtime program code conforms tothe structure or not. The code structure can be modeled with different formal models.For example Halfond et al. [2005] apply NonDeterministic Finite Automata (NDFA)to model valid queries in each hotspot. A hotspot is a location where a SQL queryis issued to a database engine. In an NDFA, a transition contains a SQL token, adelimiter, or an input string value. Muthuprasanna et al. [2006] perform Java stringanalysis on all the hotspots to construct NDFA, where transitions occur at the characterlevel of a string. Each NDFA is converted to a SQL Finite State Machine (SQL-FSM)where transitions are either SQL keywords or input string variables. If a query is notconsumed by the model, an SQLI vulnerability is warned. Wei et al. [2006] detect SQLIvulnerabilities in stored procedures by identifying queries that are generated during aprogram’s execution. They develop Finite State Machine (FSM) models of SQL queries,where a transition from one state to another state occurs for an SQL keyword. Duringa dynamic analysis phase, query statements with user inputs are checked against theFSM. If a query is not consumed by an FSM, then an error is flagged. Another variationof a code structure integrity approach is to apply positive tainting on trusted stringsduring the static analysis and to check whether runtime-generated code is constructedfrom these trusted strings or not. Halfond et al. [2006a] apply this approach to detectSQLI attacks in Java byte code.

5.4. Code Execution Flow

In this approach, static analysis is applied to identify valid program execution pathswhich might share a common program state. These paths also represent the sequence ofoperations to perform functionalities. During a dynamic analysis, it is checked whetherit is possible to jump from one execution path to another or not. Balzarotti et al. [2007]apply this approach. They analyze programs to summarize valid execution paths wherea path might be comprised of more than one Web page to perform a desired functionality(e.g., authentication). The second stage of the analysis constructs intended workflows.A workflow connects a source view with a target view provided that a hyperlink presentin the source view is referenced in the target view and parameters provided through alink are extracted in a target view. The summarized workflow is represented by a graph,where a node contains a page and corresponding view, and an edge represents possibleWeb-based operations (e.g., form submission). A model checker identifies whether anyunintended workflow is present in the summarized workflow. A detection algorithm isused to check whether from any view it is possible to jump to another view not includedin the intended workflow.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:36 H. Shahriar and M. Zulkernine

5.5. Unwanted Value

The static analysis phase identifies potential locations where inputs or tainted valuesreach and perform sensitive operations (sinks). When a program execution reaches asink, all tainted inputs are checked for suspicious metacharacters (e.g., single quota-tion) that can be used to exploit vulnerabilities such as SQLI and XSS. For example,Monga et al. [2009] detect XSS in PHP-based programs. Similarly, Lucca et al. [2004]identify XSS vulnerabilities in ASP-based programs. However, these approaches stopprogram executions while detecting unwanted values. An alternative approach is toprevent the inclusion of unwanted values in program outputs. This is common for Web-based programs that generate HTML outputs and need to avoid unwanted values toavoid attacks. For example, Johns and Beyerlein [2007] separate programmer-writtenscripts which are static string constants in program code. A string is analyzed to iden-tify keywords (e.g., HTML attributes, JavaScript words) and they replace them withmasks (random tokens). These masked keywords are unmasked before generating re-sponses by browsers. As a result, unwanted injected code is replaced with correspondingencoded form.

5.6. Summary and Open Issues

We observe that program operation and code integrity are the two widely used dynamicanalysis objectives. Most of the works apply string pattern matching and tainted dataflow analysis along with static data or control flow analysis. Very few works performdynamic analysis followed by static analysis. Moreover, CSRF vulnerabilities have notbeen addressed by current approaches. The study shows that static analysis influencesthe dynamic analysis stage for most of the works. The precision of static analysis isimportant and needs to be carefully considered before applying in a hybrid approach.Future works can explore how assumptions behind a static analysis influence the vul-nerability detection in a dynamic analysis. We notice that very few approaches employuntained data-flow-based static analysis and code-execution-flow-based dynamic anal-ysis objectives. We believe that employing suitable dynamic analysis objectives andstatic inference techniques can not only improve the effectiveness of hybrid analysis,but also detect a wide range of vulnerabilities.

6. OTHER MITIGATION APPRAOCHES

In this section, we first describe secure programming guidelines. Then we briefly discusstwo other techniques that are primarily applied in the maintenance phase: programtransformation and patching.

6.1. Secure Programming

Program security breaches can be blamed on programmers who overlook possible vul-nerabilities in their implemented code. Moreover, the lack of understanding of imple-mentation language features (e.g., data types, libraries) contributes in writing code thatmight be vulnerable [Seacord 2006]. Secure programming approaches are intended toprovide supports for implementing programs in vulnerability-free ways and can be con-sidered as the first line of defense to avoid program security breaches. Writing securecode helps reducing subsequent costs of detecting and fixing security vulnerabilitiesat later stages. Secure programming approaches provide supports in the form of safeAPIs, libraries, aspects, languages, and filters with embedded security properties.

APIs are system calls which allow programmers to perform checks in the code toavoid vulnerabilities. For example, “ptrbounds” [Speirs 2005] is a kernel-level APIthat helps obtaining the writable upper and lower bounds for a given pointer datatype to avoid BOF vulnerabilities in C programs. Most of the vulnerabilities can be

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:37

Table VII. A Brief Comparison Summary of the Secure Programming Approaches

Work Type of support Vulnerability coverage Programming languageSpeirs [2005] API BOF CTsai and Singh [2002] Library BOF CChong et al. [2007] Language SQLI, XSS JavaHermosillo et al. [2007] Aspect SQLI, XSS JavaJuillerat [2007] Library SQLI, XSS JavaRobbins [2000] Library FSB CCSRFGuard [OWASP 2010a] Filter CSRF Java

mitigated by applying safe libraries. For example, the Libsafe [Tsai and Singh 2002]intercepts all vulnerable library functions that might result in BOF attacks. The librarycode checks the stack to identify the maximum number of bytes that can be safelywritten for each destination buffer. Similarly, the Libformat library [Robbins 2000]contains an improved version of format functions to prevent FSB vulnerabilities bychecking whether supplied format strings are in writable memory locations and containsuspicious specifiers or not. Moreover, safe libraries capture the structure of strings thatmight be used in SQL queries and HTML outputs to prevent code injection attacks. Inthis case, the library disallows writing of SQL queries and HTML structures in programcode directly. Juillerat [2007] develops such a library named Stones to prevent SQLIand XSS vulnerabilities in Web programs written in Java.

A recent direction of secure programming support is to develop programming lan-guages with annotation supports to express secure information flows. The underlyingcompilers are designed to generate code to comply with the annotated informationflow. For example, the annotation int {alice → bob} y; indicates that the variabley is sensitive to alice and can be safely passed to bob. A compiler interprets theseannotations and generates JavaScript and Java code in client and server, respectively[Chong et al. 2007]. The compiler places vulnerable code and data in the server side asopposed to client side to reduce vulnerabilities at the client side. Moreover, secure pro-gramming approaches are adapted to different programming paradigms. For example,aspect-oriented programming [Hermosillo et al. 2007] allows weaving special codethrough pointcuts (i.e., a pattern of method or function calls with common signatures)and advices (i.e., additional code to be added before or after function calls). Vulnera-bilities are caused by invalidated inputs which can be checked through interceptinginputs at pointcuts and detecting (or preventing) the presence of malicious inputs inadvices.

To protect server-side programs from CSRF attacks, filters can be added [OWASP2010a]. A filter is a mapping between resources (e.g., a server script page that performsa sensitive operation) and corresponding code that intercepts HTTP requests to detectpossible CSRF attacks. The idea is to verify a request by comparing a unique requesttoken for an HTTP parameter value with a token stored in a session table. If there is amismatch, the request is considered as forged and part of a CSRF attack. The filter canredirect a user to an error page. However, if the token matches with the stored value,then a request is forwarded to a server program which generates a response page. Theresponse page is searched for HTML forms and links, and inserted with appropriateunique token parameter values for further prevention of CSRF attacks.

We provide a comparison summary of secure programming approaches in Table VIIwhich includes three features: type of programming support, vulnerability coverage,and programming language. We notice that most secure programming approaches areintended to mitigate a limited type of vulnerabilities, namely BOF, SQLI, and XSS.Moreover, C and Java are the two programming languages having ample supports forsecure programming.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:38 H. Shahriar and M. Zulkernine

6.2. Program Transformation

Program security vulnerabilities can be mitigated in a postrelease stage which is com-monly known as maintenance phase [Mancoridis 2008]. Although program featurescan be extended, removed, or modified in this stage, we only focus on activities thatare intended to fix security vulnerability breaches in the implemented code. Programtransformation is one of the most widely used techniques in this direction which re-moves vulnerabilities by applying structured modification of program source-code. Inother words, source-code of a vulnerable program is transformed to a vulnerability-freeprogram. We categorize program-transformation-related works into two types: source-to-source translation [Nishiyama 2005; Wang et al. 2005; Xu et al. 2004; Dahn andMancoridis 2003; Austin et al. 1994] and code rewriting [Reis et al. 2007; Ofunoye andMiller 2008; Yu et al. 2007].

In source-to-source translation, a program source is taken as input and an enhancedprogram in the same language is generated automatically. A source-to-source trans-lation can be implemented in different ways such as using a functional programminglanguage that can replace certain patterns of code with desired patterns (e.g., TXL).However, we restrict our discussion on the enhancement added in program code tomitigate vulnerabilities. We divide program transformation approaches into three cat-egories based on enhancement type: shifting data to safe region, adding security checks,and enriching program data. The shifting data to safe region approach shifts vulner-able data into safe regions. For example, the SecureC translator [Nishiyama 2005]translates a C program into security-enhanced source-code. The translation shifts abuffer memory location into a shadow stack (a read-only page, except the location ofbuffer). Moreover, C programs are enhanced to reposition each stack buffer into a heaparea [Dahn and Mancoridis 2003] to avoid the corruption of return addresses. Theadding security checks approach includes necessary checks to avoid vulnerabilities. Forexample, every buffer index and pointer dereference can be preceded by an assertion toprevent BOF attacks [Wang et al. 2005]. The enriching program data approach storesadditional information to track valid memory-related information. The information isused to prevent invalid memory accesses in program code. For example, to detect BOFvulnerabilities in C programs [Xu et al. 2004; Austin et al. 1994], pointer data typesare extended to contain additional information such the base and the size of memoryobjects and the status of memory objects (i.e., allocated or freed).

The code rewriting technique is used for rewriting the output of a program as opposedto program source-code directly. The output is another high-level program that might beinterpreted or executed by another processor. For example, a server script code writtenin PHP generates HTML code which might contain BOF vulnerabilities due to arbitrarylarge HTML attribute identifiers [Reis et al. 2007]. The code can be rewritten at thebrowser to avoid unexpected results while rendering the page. Similarly, vulnerableJavaScript code can be rewritten to stop XSS attacks [Ofunoye and Miller 2008; Yuet al. 2007].

We provide a brief comparison summary of program-transformation-related worksin Table VIII according to transformation type, vulnerability coverage, and program-ming language. It is obvious that only BOF and XSS have been mitigated using pro-gram transformation techniques. Moreover, current approaches have addressed C andJavaScript programs whose sources are transformed to safe equivalents.

6.3. Patching

Patching is a widely used approach in the program maintenance phase to fix reportedbugs or errors so that modified programs conform to expected functionality, perfor-mance, and quality [Mancoridis 2008]. However, we focus on corrective maintenance

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:39

Table VIII. A Comparison Summary of Source-Code Transformations Related to Security Vulnerabilities

Work Transformation type Vulnerability coverage Programming languageNishiyama [2005] Source to source BOF CWang et al. [2005] Source to source BOF CXu et al. [2004] Source to source BOF CReis et al. [2007] Code rewriting BOF JavaScriptYu et al. [2007] Code rewriting XSS JavaScriptOfunoye and Miller [2008] Code rewriting XSS JavaScriptDahn and Mancoridis [2003] Source to source BOF CAustin et al. [1994] Source to source BOF C

which is intended to fix reported security breaches in programs. A patching techniqueidentifies vulnerable code and modifies the program to remove vulnerabilities. Unlikeother proactive (e.g., static and hybrid analysis, testing) techniques, patches aregenerated after the occurrence of attacks. We classify patching works into two types:source-code and environment patching.

The source-code patching technique analyzes program source-code to identify vul-nerable statements that need to be fixed. The common practice is replacing vulnerablecode with equivalent safe code. For example, an SQL query statement can be rewrittenin such a way so that it does not allow the modification of query structure during run-time [Dysart and Sherriff 2008; Thomas and Williams 2007]. Moreover, unsafe libraryfunction calls can be replaced with their safe equivalents to avoid BOF [Smirnov andChiueh 2007]. A variation of source-code patching is to guide patching locations by dataflow analysis on the source-code of the functions to identify related statements thatcontribute to vulnerabilities [Lin et al. 2007]. Patches are generated by determining thesize of buffers. Out-of-buffer reads are redirected within buffers. Out-of-bound writingsare discarded by replacing unsafe library function calls with safe function calls.

In an environment patching approach, the program environment is modified whichincludes memory layout, external library addresses, etc. This approach can help inpatching programs without stopping their executions. For example, patching to preventBOF attacks can be performed by redirecting a vulnerable function (e.g., strcpy) withan equivalent nonvulnerable function (e.g., strncpy) [Lin et al. 2006] by changing theGOT (Global Offset Table) entries. Many approaches analyze program artifacts that aregenerated due to vulnerability exploitations. These artifacts help identifying changesto be made in an environment. For example, the crashed program can be analyzed tochange the environment by adding a canary value at the end of a buffer to preventBOF [Gao et al. 2009]. Moreover, the heap image of a crashed program can be dumpedto learn the magnitude of the overflowed bytes [Novark et al. 2007]. The information isused to pad objects to prevent BOF vulnerabilities. For Web-based programs, patchingcan be performed in proxies located between a server and a client. In this case, a proxyis enhanced with input filters (input validation functions) [Lin and Chen 2007] to detectmalicious inputs from the client side of a program.

We provide a brief comparison summary of patching works that fix program secu-rity vulnerabilities in Table IX, where we classify the works based on patching type,vulnerability coverage, and programming language. We note that BOF, SQLI, and XSSvulnerabilities have been addressed by current approaches. Moreover, most patchingworks are related to the implementation of C programs. Very few works generatepatches for programs whose sources are available in high and intermediate languages.

7. CONCLUSIONS

In this article, we perform a comprehensive survey of the works that address detec-tion and prevention of the most commonly occurring program security vulnerabilities,

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:40 H. Shahriar and M. Zulkernine

Table IX. A Brief Comparison Summary of Patching Approaches for Mitigating Security Vulnerabilities

Work Patching type Vulnerability coverage Programming languageGao et al. [2009] Environment BOF CLin et al. [2007] Source code BOF CNovark et al. [2007] Environment BOF CSmirnov and Chiueh [2007] Source code BOF CLin et al. [2006] Environment BOF x86Dysart and Sherriff [2008] Source code SQLI PHPLin and Chen [2007] Environment SQLI, XSS N/AThomas and Williams [2007] Source code SQLI Java

Table X. A Mapping between the Program Security MitigationTechniques and the Addressed Vulnerabilities

Technique BOF FSB SQLI XSS CSRFTesting Y Y Y Y NStatic analysis Y Y Y Y NHybrid Y Y Y Y NSecure programming Y Y Y Y YProgram transformation Y N N Y NPatching Y N Y Y N

Table XI. A Mapping between the Program Security Mitigation Techniques and the Programming Languages

Technique C C++ Java JSP PHP ASP JavaScript x86 Java byte codeTesting Y N N Y Y N N Y YStatic analysis Y Y Y Y Y Y N Y NHybrid Y N Y Y Y Y N Y YSecure programming Y N Y N N N N N NProgram transformation Y N N N N N Y N NPatching Y N Y N Y N N Y N

namely BOF, FSB, SQLI, XSS, and CSRF. We primarily compare and contrast thethree most widely used vulnerability mitigation techniques: testing, static analysis,and hybrid analysis. Each technique has been explored to perform comparative andqualitative analysis among relevant approaches based on a number of distinguishingcriteria. Then we identify the open issues for each of the corresponding techniques.We also briefly discuss the current challenges of some other approaches which providesecure programming guidelines or related program maintenance: program transfor-mation and patching.

Based on our analysis, we provide a summarized mapping between the programsecurity mitigation techniques and the addressed vulnerabilities in Table X. It relateswhether the techniques have been applied to mitigate corresponding vulnerabilities(Y) or not (N). It is obvious that existing techniques have devoted considerable effort topartially mitigate a subset of vulnerabilities such as BOF, FSB, SQLI, and XSS. We alsomap whether these techniques have been applied to programs written in a particularlanguage (Y) or not (N) in Table XI. We notice a gap between current techniquesand underlying programming languages as well. Currently, programs written in C,Java, PHP, and JavaScript are analyzed widely. However, we should also investigatehow vulnerabilities can be detected in the programs written in other programminglanguages and where source-code is not available (i.e., in executable forms). For allthese techniques, our common observation is that they can detect only certain typesof vulnerabilities at the same time. Some techniques are strictly limited to certainprogramming languages. Moreover, few works have attempted combined techniques todetect vulnerabilities. We believe that future program security research should explore

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:41

the detection and prevention of multiple vulnerabilities by applying new and hybridtechniques on the programs written in various programming languages.

Currently, there is no work that summarizes and compares current program-basedvulnerability mitigation works in detail. This survey will help software securitypractitioners and researchers to understand pros and cons of these techniques,develop new software security tools, and explore future research avenues. For thesake of the length of the survey and the broadness of this topic, our study is restrictedto the techniques that strive to mitigate directly exploitable vulnerabilities foundin the code level only. We also limit our analysis of vulnerabilities for the programswritten in procedural, object-oriented, and scripting languages. We do not discuss theapproaches that primarily develop [Bertino et al. 2007; Guha et al. 2009; Kemalisand Tzouramanis 2008] or evaluate [Kayacik et al. 2006; Vigna et al. 2004] IntrusionDetection Systems (IDS). Our study also does not include security breaches that can bemanaged by using formal access control policies. Furthermore, we do not discussmitigation techniques that can be applied in postdeployment stages such as runtimemonitoring. More independent surveys [Shahriar and Zulkernine 2010b and 2010d]are required for the aforementioned topics.

ACKNOWLEDGMENTS

We also thank to the anonymous reviewers to help improving this article with their thoughtful comments.

REFERENCES

AGGARWAL, A. AND JALOTE, P. 2006. Integrating static and dynamic analysis for detecting vulnerabilities. InProceedings of the 30th Annual International Computer Software and Application Conference. 343–350.

ALLEN, W., CHIN, D., AND MARIN, G. 2006. A model-based approach to the security testing of network protocolimplementations. In Proceedings of the 31st IEEE Conference on Local Computer Networks. 1008–1015.

ASHCRAFT, K. AND ENGLER, D. 2002. Using programmer-written compiler extensions to catch security holes. InProceedings of the IEEE Symposium on Security and Privacy. 143.

AUSTIN, T., BREACH, S., AND SOHI, G. 1994. Efficient detection of all pointer and array access errors. In Pro-ceedings of the Conference on Programming Language Design and Implementation. 290–301.

BALZAROTTI, D., COVA, M., FELMETSGER, V., AND VIGNA, G. 2007. Multi-Module vulnerability analysis of Web-based applications. In Proceedings of the 14th ACM Conference on Computer and Communications Secu-rity. 25–35.

BERTINO, E., KAMRA, A., AND EARLY, J. 2007. Profiling database application to detect SQL injection attacks. InProceedings of the International Performance, Computing and Communications Conference. 449–458.

BREECH, B. AND POLLOCK, L. 2005. A framework for testing security mechanisms for program-based attacks.In Proceedings of the ICSE Workshop on Software Engineering for Secure Systems. 1–7.

BURNS, J. 2005. Cross site request forgery: An introduction to a common Web application weakness. Whitepaper, Information Security Partners LLC.

CASTRO, M., COSTA, M., AND HARRIS, T. 2006. Securing software by enforcing data-flow integrity. In Proceedingsof the 7th USENIX Symposium on Operating Systems Design and Implementation. 11.

CADAR, C., GANESH, V., PAWLOWSKI, P., DILL, D., AND ENGLER, D. 2006. EXE: Automatically generating inputs ofdeath. In Proceedings of the 13th ACM Conference on Computer and Communications Security. 322–335.

CHEN, K. AND WAGNER, D. 2007. Large-Scale analysis of format string vulnerabilities in Debian Linux. InProceedings of the Workshop on Programming Languages and Analysis for Security (PLAS’07). 75–84.

CHESS, B. AND MCGRAW, G. 2004. Static analysis for security. IEEE Secur. Priv. 2, 6, 76–79.CHONG, S., LIU, J., MYERS, A., QI, X., VIKRAM, K., ZHENG, L., AND ZHENG, X. 2007. Secure Web applications

via automatic partitioning. In Proceedings of the 21st ACM SIGOPS Symposium on Operating SystemsPrinciples. 31–44.

CVE. 2010. Common vulnerabilities and exposures. http://cve.mitre.org.CWE. 2009. Common weakness enumeration. CWE/SANS top 25 most dangerous programming errors.

http://cwe.mitre.org/top25.CWE. 2010. CWE-352: Cross-Site request forgery (CSRF). http://cwe.mitre.org/data/definitions/352.html.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:42 H. Shahriar and M. Zulkernine

DAHN, C. AND MANCORIDIS, S. 2003. Using program transformation to secure C programs against bufferoverflows. In Proceedings of the 10th Working Conference on Reverse Engineering (WCRE’03). 323–332.

DEKOK, A. 2007. Pscan (1.2-8) format string security checker for C files. http://packages.debian.org/etch/pscan.DEMILLO, R., LIPTON, R., AND SAYWARD, F. 1978. Hints on test data selection: Help for the practicing programmer.

IEEE Comput. Mag. 11, 4, 34–41.DOM. 1998. Document object model (DOM), level 1 specification, version 1.0. http://www.w3.org.DOR, N., RODEH, M., AND SAGIV, M. 2003. CSSV: Towards a realistic tool for statically detecting all buffer

overflows in C. In Proceedings of the Conference on Programming Language Design and Implementation.155–167.

DOWD, M., MCDONALD, J., AND SCHUH, J. 2007. The Art of Software Security Assessment. Addison-Wesley.DU, W. AND MATHUR, A. 2000. Testing for software vulnerabilities using environment perturbation. In Pro-

ceedings of the International Conference on Dependable Systems and Networks (DSN’00). 603–612.DYSART, F. AND SHERRIFF, M. 2008. Automated fix generator for SQL injection attacks. In Proceedings of the

19th International Symposium on Software Reliability Engineering. 311–312.ERNST, M. 2003. Static and dynamic analysis: Synergy and duality. In Proceedings of the ICSE Workshop on

Dynamic Analysis. 24–27.ERLINGSSON, U. 2007. Low-Level software security: Attacks and defenses. Tech. rep. MSR-TR-07-153, Microsoft

Research.EVANS, D. AND LAROCHELLE, D. 2002. Improving security using extensible lightweight static analysis. IEEE

Softw. 19, 1, 42–51.FLAWFINDER. 2010. http://www.dwheeler.com/flawfinder.FONSECA, J., VIEIRA, M., AND MADEIRA, H. 2007. Testing and comparing Web vulnerability scanning tools for

SQL injection and XSS attacks. In Proceedings of the 13th Pacific Rim International Symposium onDependable Computing. 365–372.

GANAPATHY, V., JHA, S., CHANDLER, D., MELSKI, D., AND VITEK, D. 2003. Buffer overrun detection using lin-ear programming and static analysis. In Proceedings of the 10th ACM Conference on Computer andCommunications Security. 345–354.

GAO, Q., ZHANG, W., TANG, Y., AND QIN, F. 2009. First aid: Surviving and preventing memory management bugsduring production runs. In Proceedings of the 4th European Conference on Computer Systems. 159–172.

GHOSH, A., O’CONNOR, T., AND MCGRAW, G. 1998. An automated approach for identifying potential vulnerabil-ities in software. In Proceedings of the IEEE Symposium on Security and Privacy. 104–114.

GORDON, L. A., LOEB, M. P., LUCYSHYN, W., AND RICHARDSON, R. 2004. Ninth CSI/FBI computer crime andsecurity survey. Tech. rep. RL32331, Computer Security Institute.

GROSSO, C., ANTONIOL, G., MERLO, E., AND GALINIER, P. 2008. Detecting buffer overflow via automatic test inputdata generation. Comput. Oper. Res. 35, 10, 3125–3143.

GUHA, A., KRISHNAMURTHI, S., AND JIM, T. 2009. Using static analysis for ajax intrusion detection. In Proceedingsof the International World Wide Web Conference. 561–570.

GUO, P. 2006. A scalable mixed-level approach to dynamic analysis of C and C++ programs. Master ofEngineering thesis, Massachusetts Institute of Technology. May.

HACKETT, B., DAS, M., WANG, D., AND YANG, Z. 2006. Modular checking for buffer overflows in the large. InProceedings of the 28th International Conference on Software Engineering. 232–241.

HALFOND, W. AND ORSO, A. 2005. Combining static analysis and runtime monitoring to counter SQL injectionattacks. In Proceedings of the 3rd International Workshop on Dynamic Analysis. 1–7.

HALFOND, W., ORSO, A., AND MANOLIOS, P. 2006a. FSE. Using positive tainting and syntax-aware evaluation tocounter SQL injection attacks. In Proceedings of the 14th ACM SIGSOFT International Symposium onFoundations of Software Engineering. 175–185.

HALFOND, W., VIEGAS, J., AND ORSO, A. 2006b. A classification of SQL injection attacks and countermeasures.In Proceedings of the IEEE International Symposium on Secure Software Engineering.

HAUGH, E. AND BISHOP, M. 2003. Testing C programs for buffer overflow vulnerabilities. In Proceedings of theNetwork and Distributed System Security Symposium (NDSS).

HERMOSILLO, G., GOMEZ, R., SEINTURIER, L., AND DUCHIEN, L. 2007. AProSec: An aspect for programming secureWeb applications. In Proceedings of the 2nd International Conference on Availability, Reliability andSecurity. 1026–1033.

HIND, M. 2001. Pointer analysis: Haven’t we solved this problem yet? In Proceedings of the ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and Engineering. 54–61.

HUANG, Y., HUANG, S., LIN, T., AND TSAI, C. 2003. Web application security assessment by fault injection andbehavior monitoring. In Proceedings of the 12th International Conference on World Wide Web. 148–159.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:43

HUSS, E. 1997. The C library reference guide, release 1. http://www.acm.uiuc.edu/webmonkeys/book/c guide/.ISO. 1992. International Standards Organization, Information Technology, Database Languages, SQL 3rd

Ed. ISO/IEC.JOHNS, M. AND BEYERLEIN, C. 2007. SMask: Preventing injection attacks in Web applications by approxi-

mating automatic data/code separation. In Proceedings of the ACM Symposium on Applied Computing.284–291.

JORGENSEN, A. 2003. Testing with hostile data streams. ACM SIGSOFT Softw. Engin. Not. 28, 2, 9.JOVANOVIC, N., KRUEGEL, C., AND KIRDA, E. 2006. Pixy: A static analysis tool for detecting Web application

vulnerabilities. In Proceedings of the IEEE Symposium on Security and Privacy. 258–263.JUILLERAT, N. 2007. Enforcing code security in database Web applications using libraries and object models.

In Proceedings of the Symposium on Library-Centric Software Design. 31–41.JUNJIN, M. 2009. An approach for SQL injection vulnerability detection. In Proceedings of the 6th International

Conference on Information Technology: New Generations. 1411–1414.KALS, S., KRIDA, E., KRUEGEL, C., AND JOVANOVIC, N. 2006. SecuBat: A Web vulnerability scanner. In Proceedings

of the 15th International Conference on World Wide Web. 247–256.KAYACIK, H., HEYWOOD, M., AND HEYWOOD, N. 2006. On evolving buffer overflow attacks using genetic pro-

gramming. In Proceedings of the 8th Annual Conference on Genetic and Evolutionary Computation.1667–1674.

KEMALIS, K. AND TZOURAMANIS, T. 2008. SQL-IDS: A specification-based approach for SQL injection detection.In Proceedings of the 23rd ACM Symposium on Applied Computing (SAC’08). 2153–2158.

KIEZUN, A., GUO, P., JAYARAMAN, K., AND ERNST, M. 2009. Automatic creation of SQL injection and cross-sitescripting attacks. In Proceedings of the 31st International Conference on Software Engineering. 199–209.

KIM, H., CHOI, Y., LEE, D., AND LEE, D. 2008. Practical security testing using file fuzzing. In Proceedings of theInternational Conference on Advanced Computing Technologies (ICACT). 1304–1307.

KING, J. 1976. Symbolic execution and program testing. Comm. ACM 19, 7, 385–394.KLEIN, A. 2005. DOM-Based cross site scripting or XSS of the third kind. http://www.webappsec.org/

projects/articles/071105.shtml.KLOG. 1999. The frame pointer overwrite. Phrack Mag. 9, 55. http://www.phrack.org.KRATKEWICZ, K. AND LIPPMANN, R. 2005. Using a diagnostic corpus of C programs to evaluate buffer overflow

detection by static analysis tools. In Proceedings of the Workshop on the Evaluation of Software DefectDetection Tools.

KUMAR, P., NEMA, A., AND KUMAR, R. 2009. Hybrid analysis of executables to detect security vulnerabilities.In Proceedings of the 2nd Annual Conference on India Software Engineering. 141–142.

LAM, M., MARTIN, M., LIVSHITS, B., AND WHALEY, J. 2008. Securing Web applications with static and dynamicinformation flow tracking. In Proceedings of the ACM SIGPLAN Symposium on Partial Evaluation andSemantics-Based Program Manipulation. 3–12.

LE, W. AND SOFFA, M. 2008. Marple: A demand-driven path-sensitive buffer overflow detector. In Proceedingsof the 16th ACM SIGSOFT International Symposium on Foundations of Software Engineering (FSE’08).272–282.

LEAH, D. 2000. A memory allocator. http://g.oswego.edu/dl/html/malloc.html.LIN, J. AND CHEN, J. 2007. The automatic defense mechanism for malicious injection attack. In Proceedings of

the 7th International Conference on Computer and Information Technology. 709–714.LIN, Z., JIANG, X., XU, D., MAO, B., AND XIE, L. 2007. AutoPaG: Towards automated software patch generation

with source code root cause identification and repair. In Proceedings of the 2nd ACM Symposium onInformation, Computer and Communications Security. 329–340.

LIN, Z., MAO, B., AND XIE, L. 2006. A practical framework for dynamically immunizing software security vul-nerabilities. In Proceedings of the 1st International Conference on Availability, Reliability and Security.348–357.

LIVSHITS, V. AND LAM, M. 2005. Finding security vulnerabilities in Java applications with static analysis. InProceedings of the 14th USENIX Security Symposium. 18.

LUCCA, G., FASOLINO, A., MASTOIANNI, M., AND TRAMONTANA, P. 2004. Identifying cross site scripting vulnera-bilities in Web applications. In Proceedings of the 6th International Workshop on Web Site Evolution.71–80.

MANCORIDIS, S. 2008. Software analysis for security. In Proceedings of the Conference on Frontiers of SoftwareMaintenance. 109–118.

MATHUR, A. 2008. Foundations of Software Testing 1st Ed. Pearson Education.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:44 H. Shahriar and M. Zulkernine

MCALLISTER, S., KIRDA, E., AND KRUEGEL, C. 2008. Leveraging user interactions for in-depth testing of Webapplications. In Proceedings of the 11th International Symposium on Recent Advances in IntrusionDetection (RAID). 191–210.

MCGRAW, G. AND POTTER, B. 2004. Software security testing. IEEE Secur. Priv. 2, 5, 81–85.MCMINN, P. 2004. Search-Based software test data generation: A survey. Softw. Test. Verif. Reliab. 14, 2,

105–156.MONGA, M., PALEARI, R., AND PASSERINI, E. 2009. A hybrid analysis framework for detecting Web application

vulnerabilities. In Proceedings of the 5th Workshop on Software Engineering for Secured Systems. 25–32.

MUTHUPRASANNA, M., WEI, K., AND KOTHARI, S. 2006. Eliminating SQL injection attacks: A transparent defensemechanism. In Proceedings of the 8th International Symposium on Web Site Evolution. 22–32.

NISHIYAMA, H. 2005. SecureC: Control-Flow protection against general buffer overflow attack. In Proceedingsof the 29th Annual International Computer Software and Applications Conference. 149–155.

NOVARK, G., BERGER, E., AND ZORN, B. 2007. Exterminator: Automatically correcting memory errors with highprobability. In Proceedings of the ACM SIGPLAN Conference on Programming Language Design andImplementation. 1–11.

OFFUTT, J., WU, Y., DU, X., AND HUANG, H. 2004. Bypass testing of Web applications. In Proceedings of the 15th

International Symposium on Software Reliability Engineering (ISSRE). 187–197.OFUONYE, E. AND MILLER, J. 2008. Resolving Javascript vulnerabilities in the browser runtime. In Proceedings

of the 19th International Symposium on Software Reliability Engineering. 57–66.OKUN, V., GUTHRIE, W., GAUCHER, R., AND BLACK, P. 2007. Effect of static analysis tools on software security:

Preliminary investigation. In Proceedings of the 3rd Workshop on Quality of Protection. 1–5.ONE, A. 1996. Smashing the stack for fun and profit. Phrack Mag. 7, 49. http://insecure.org/stf/

smashstack.html.OSVDB. 2010. Open source vulnerability database. http://osvdb.org.OWASP. 2010a. OWASP CSRFGuard project. http://www.owasp.org/index.php/CSRFGuard 2.2

Configuration Manual.OWASP. 2010b. Range and type error vulnerability. http://www.owasp.org/index.php/Category:Range and

Type Error Vulnerability.POZZA, D., SISTO, R., DURANTE, L., AND VALENZANO, A. 2006. Comparing lexical analysis tools for buffer overflow

detection in network software. In Proceedings of the 1st International Conference on CommunicationSystem Software and Middleware. 1–7.

PAX. 2003. Documentation for the PaX project. http://pax.grsecurity.net/docs/pax.txt.REIS, C., DUNAGAN, J., WANG, H., DUBROVSKY, O., AND ESMEIR, S. 2007. BrowserShield: Vulnerability-Driven

filtering of dynamic HTML. ACM Trans. Web 1, 3.RINGENBURG, M. AND GROSSMAN, D. 2005. Preventing format-string attacks via automatic and efficient dy-

namic checking. In Proceedings of the 12th Conference on Computer and Communications Security. 354–363.

ROBBINS, T. 2000. Libformat. http://archives.neohapsis.com/archives/linux/lsap/2000-q3/0444.html.SEACORD, R. 2006. Secure coding in C and C++ of strings and integers. IEEE Secur. Priv. 4, 1, 74–76.SHAHRIAR, H. AND ZULKERNINE, M. 2010a. Assessing test suites for buffer overflow vulnerabilities. Int. J. Softw.

Engin. Knowl. Engin. 20, 1, 73–101. World Scientific.SHAHRIAR, H. AND ZULKERNINE, M. 2010b. Classification of buffer overflow vulnerability monitors. In Proceed-

ings of the 4th International Workshop on Secure Software Engineering. 519–524.SHAHRIAR, H. AND ZULKERNINE, M. 2010c. Classification of static analysis-based buffer overflow vulnerability

detection. In Proceedings of the 1st Workshop on Model Checking in Reliability and Security. 94–101.SHAHRIAR, H. AND ZULKERNINE, M. 2010d. Monitoring buffer overflow vulnerabilities: A perennial problem.

Int. J. Secur. Softw. Engin. 1, 3, 18–40.SHAHRIAR, H. AND ZULKERNINE, M. 2009a. Automatic testing of program security vulnerabilities. In

Proceedings of the 1st International Workshop on Test Automation. 550–555.SHAHRIAR, H. AND ZULKERNINE, M. 2009b. MUTEC: Mutation-Based testing of cross site scripting. In

Proceedings of the 5th ICSE Workshop on Software Engineering for Secure Systems. 47–53.SHAHRIAR, H. AND ZULKERNINE, M. 2008a. Mutation-Based testing of buffer overflow vulnerabilities.

In Proceedings of the 2nd International Workshop on Security in Software Engineering (IWSSE).979–984.

SHAHRIAR, H. AND ZULKERNINE, M. 2008b. Mutation-Based testing of format string bugs. In Proceedings of the11th High Assurance Systems Engineering Symposium (HASE’08). 229–238.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

Mitigating Program Security Vulnerabilities: Approaches and Challenges 11:45

SHAHRIAR, H. AND ZULKERNINE, M. 2008c. MUSIC: Mutation-Based SQL injection vulnerability checking. InProceedings of the 8th International Conference on Quality Software (QSIC). 77–86.

SHANKAR, U., TALWAR, K., FOSTER, J., AND WAGNER, D. 2001. Detecting format string vulnerabilities with typequalifiers. In Proceedings of the 10th USENIX Security Symposium.

SILVA, A. 2005. Format strings. Gotfault Security Community, version 2.5. http://www.milw0rm.com/papers/5.SMIRNOV, A. AND CHIUEH, T. 2007. Automatic patch generation for buffer overflow attacks. In Proceedings of

the 3rd International Symposium on Information Assurance and Security. 165–170.SOTIROV, A. 2005. Automatic vulnerability detection using static analysis. MSc thesis, The University of

Alabama. http://gcc.vulncheck.org/sotirov05automatic.pdf.SPEIRS, W. 2005. Making the kernel responsible: A new approach to determining and preventing buffer

overflows. In Proceedings of the 3rd IEEE International Workshop on Information Assurance. 21–32.SYMANTEC. 2008. Internet security threat report, trends for July-September 07. Volume XII.

http://eval.symantec.com/mktginfo/enterprise/white papers/b-whitepaper exec summary internetsecurity threat report xiii 04-2008.en-us.pdf.

TAL, O., KNIGHT, S., AND DEAN, T. 2004. Syntax-Based vulnerabilities testing of frame-based network protocols.In Proceedings of the 2nd Annual Conference on Privacy, Security and Trust. 155–160.

TAPPENDEN, A., BEATTY, P., MILLER, J., GERAS, A., AND SMITH, M. 2005. Agile security testing of Web-basedsystems via HTTPUnit. In Proceedings of the Agile Development Conference (ADC). 29–38.

TESO, SCUT/TEAM. 2001. Exploiting format string vulnerabilities. http://doc.bughunter.net/format-string/exploit-fs.html.

TEVIS, J. AND HAMILTON, J. 2006. Static analysis of anomalies and security vulnerabilities in executable files.In Proceedings of the 44th Annual SouthEast Regional Conference. 560–565.

THOMAS, S. AND WILLIAMS, L. 2007. Using automated fix generation to secure SQL statements. In Proceedingsof the 3rd International Workshop on Software Engineering for Secure Systems. 9–14.

TRIPP, O., PISTOIA, M., FINK, S., SRIDHARAN, M., AND WEISMAN, O. 2009. TAJ: Effective taint analysis of Webapplications. In Proceedings of the Conference on Programming Language Design and Implementation.87–97.

TSAI, T. AND SINGH, N. 2002. Libsafe: Transparent system-wide protection against buffer overflow attacks. InProceedings of the International Conference on Dependable Systems and Networks. 541.

VIEGA, J., BLOCH, J., KOHNO, T., AND MCGRAW, G. 2002. Token-Based scanning of source code for securityproblems. ACM Trans. Inf. Syst. Secur. 5, 3, 238–261.

VIGNA, G., ROBERTSON, W., AND BALZAROTTI, D. 2004. Testing network-based intrusion detection signature usingmutant exploits. In Proceedings of the ACM Conference on Computer and Communication Security. 21–30.

VILELA, P., MACHADO, M., AND WONG, E. 2002. Testing for security vulnerabilities in software. In Proceedingsof the Conference on Software Engineering and Applications (SEA).

W3C. 1999. HTML 4.10 specification. http://www.w3.org/TR/REC-html40.WAGNER, D., FOSTER, J., BREWER, E., AND AIKEN, A. 2000. A first step towards automated detection of buffer

overrun vulnerabilities. In Proceedings of the Network and Distributed System Security Symposium.WANG, L., CORDY, J., AND DEAN, T. 2005. Enhancing security using legality assertions. In Proceedings of the

12th Working Conference on Reverse Engineering. 35–44.WASSERMANN, G. AND SU, Z. 2008. Static detection of cross-site scripting vulnerabilities. In Proceedings of the

30th International Conference on Software Engineering (ISCE). 171–180.WASSERMANN, G. AND SU, Z. 2007. Sound and precise analysis of Web applications for injection vulnerabilities.

In Proceedings of the Conference on Programming Language Design and Implementation (PLDI). 32–41.

WEBER, M., SHAH, V., AND REN, C. 2001. A case study in detecting software security vulnerabilities usingconstraint optimization. In Proceedings of the Workshop on Source Code Analysis and Manipulation.3–13.

WEI, K., MUTHUPRASANNA, M., AND KOTHARI, S. 2006. Preserving SQL injection attacks in stored procedures.In Proceedings of the Australian Software Engineering Conference. 191–198.

WILANDER, J. AND KAMKAR, M. 2003. A comparison of publicly available tools for dynamic buffer overflowprevention. In Proceedings of the 10th Network and Distributed System Security Symposium.

XIE, Y. AND AIKEN, A. 2006. Static detection of security vulnerabilities in scripting languages. In Proceedingsof the 15th USENIX Security Symposium.

XIE, Y., CHOU, A., AND ENGLER, D. 2003. ARCHER: Using symbolic, path-sensitive analysis to detect memoryaccess errors. In Proceedings of the 9th European Software Engineering Conference. 327–336.

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.

11:46 H. Shahriar and M. Zulkernine

XU, W., DUVARNEY, D., AND SEKAR, R. 2004. An efficient and backwards-compatible transformation to ensurememory safety of C programs. In Proceedings of the 12th ACM SIGSOFT International Symposium onFoundations of Software Engineering. 117–126.

XU, R., GODEFROID, P., AND MAJUMDAR, R. 2008. Testing for buffer overflows with length abstraction. InProceedings of the International Symposium on Software Testing and Analysis. 27–38.

YANG, J., KREMENEK, T., XIE, Y., AND ENGLER, D. 2003. MECA: An extensible, expressive system and languagefor statically checking security properties. In Proceedings of the 10th ACM Conference on Computer andCommunications Security. 321–334.

YONG, S. AND HORWITZ, S. 2003. Protecting C programs from attacks via invalid pointer dereferences. ACMSIGSOFT Softw. Engin. Not. 28, 5, 307–316.

YOUNAN, Y., JOOSEN, W., PIESSENS, F., AND EYNDEN, H. 2005. Security of memory allocators for C and C++. Tech.rep. CW419, Katholieke University Leuven, Belgium. http://www.fort-knox.be/files/CW419.pdf.

YU, D., CHANDER, A., ISLAM, N., AND SERIKOV, I. 2007. Javascript instrumentation for browser security. InProceedings of the 34th Symposium on Principles of Programming Languages (POPL). 237–249.

ZITSER, M., LIPPMANN, R., AND LEEK, T. 2004. Testing static analysis tools using exploitable buffer over-flows from open source code. In Proceedings of the 12th ACM SIGSOFT International Symposium onFoundations of Software Engineering. 97–106.

ZHANG, X., SHAO, L., AND ZHENG, J. 2008. A novel method of software vulnerability detection based on fuzzingtechnique. In Proceedings of the International Conference on Apperceiving Computing and IntelligenceAnalysis. 270–273.

ZHU, H., HALL, P., AND MAY, J. 1997. Software unit test coverage and adequacy. ACM Comput. Surv. 29, 4,366–427.

ZUCHLINSKI, G. 2003. The anatomy of cross site scripting. http://www.net-security.org/dl/articles/xss anatomy.pdf.

Received October 2009; revised June 2010; accepted September 2010

ACM Computing Surveys, Vol. 44, No. 3, Article 11, Publication date: June 2012.