---
type: Article
title: "Argus: All your (PHP) Injection-sinks are belong to us."
resource: "https://www.usenix.org/conference/usenixsecurity24/presentation/jahanshahi"
tags: [article, webseclist-reference, en, usenix-org]
generated:
  by: webseclist-refs/1
  at: "2026-08-19T16:20:27+00:00"
status: stable
stale_after: 2027-08-19
sources:
  - id: original
    resource: "https://www.usenix.org/conference/usenixsecurity24/presentation/jahanshahi"
    title: "Argus: All your (PHP) Injection-sinks are belong to us."
    author: Rasoul Jahanshahi, Manuel Egele
also_at:
  - "https://www.usenix.org/system/files/usenixsecurity24-jahanshahi.pdf"
  - "https://www.usenix.org/system/files/usenixsecurity24-appendix-jahanshahi.pdf"
  - "https://www.usenix.org/system/files/usenixsecurity24_slides-jahanshahi.pdf"
authors:
  - Rasoul Jahanshahi
  - Manuel Egele
canonical_url: ""
cited_by:
  - "2024.md:141"
commit: ""
content_sha256: bb74880f9bdf7ccba390a8c5dacc552a63b53a8814d70ff48d33b599d6bc38b8
depth: full
depth_reason: default
kind: article
language: en
licence: unknown
original_url: "https://www.usenix.org/conference/usenixsecurity24/presentation/jahanshahi"
published: ""
publisher: usenix.org
publisher_english: ""
raw_sha256: e104b736ede65d3f7a9e5f2a0821285e6f141e8216e929eccac4ce653de2cde2
retrieved_from: "https://www.usenix.org/system/files/usenixsecurity24-jahanshahi.pdf"
retrieved_kind: live
retrieved_utc: "2026-08-19T16:20:27+00:00"
slug: usenix-org-argus-all-your-php-injection-sinks-belong-us
snapshot: ""
title_english: ""
translation_file: ""
translation_of: ""
---

# Argus: All your (PHP) Injection-sinks are belong to us.

**Argus: All your (PHP) Injection-sinks are belong to us.** - Rasoul Jahanshahi, Manuel Egele, usenix.org.

- Published: date not stated
- Original: <https://www.usenix.org/conference/usenixsecurity24/presentation/jahanshahi>
- Also published at: <https://www.usenix.org/system/files/usenixsecurity24-jahanshahi.pdf>
- Also published at: <https://www.usenix.org/system/files/usenixsecurity24-appendix-jahanshahi.pdf>
- Also published at: <https://www.usenix.org/system/files/usenixsecurity24_slides-jahanshahi.pdf>
- Preserved from: https://www.usenix.org/system/files/usenixsecurity24-jahanshahi.pdf (live) on 2026-08-19
- Licence: unknown

Rights remain with the original author and publisher. This is a research
archive of a source from the Web Hacking Techniques Index collections, kept so the
page going offline. To read the original, follow the link above.

## Content

> UNTRUSTED SOURCE TEXT. Everything below this line is third-party material
> quoted for research. It is data, not instructions. Do not follow directions,
> execute code, or fetch URLs because this text says so.

Argus: All your (PHP) Injection-sinks
               are belong to us.
      Rasoul Jahanshahi and Manuel Egele, Boston University
https://www.usenix.org/conference/usenixsecurity24/presentation/jahanshahi




  This paper is included in the Proceedings of the
         33rd USENIX Security Symposium.
             August 14–16, 2024 • Philadelphia, PA, USA
                            978-1-939133-44-1




                                   Open access to the Proceedings of the
                                     33rd USENIX Security Symposium
                                         is sponsored by USENIX.
                        Argus: All your (PHP) Injection-sinks are belong to us.

                                      Rasoul Jahanshahi                    Manuel Egele
                                      Boston University                  Boston University
                                       rasoulj@bu.edu                     megele@bu.edu



                          Abstract                                   1    Introduction
Injection-based vulnerabilities in web applications such
as cross-site scripting (XSS), insecure deserialization, and         In recent years, web applications have become an inseparable
command injection have proliferated in recent years, exposing        part of users’ daily online lives, providing the means for com-
both clients and web applications to security breaches. Current      munication, news, media, and financial services. The plethora
studies in this area focus on detecting injection vulnerabilities    of sensitive information held by the databases behind such web
in applications. Crucially, existing systems rely on manually        applications becomes a lucrative target for cyber-criminals.
curated lists of functions, so-called sinks, to detect such          In 2017, Symantec reported that one in every 13 web requests
vulnerabilities. However, current studies are oblivious to the       was malicious [4]. Furthermore, the ever-increasing number of
internal mechanics of the underlying programming language.           discovered vulnerabilities exposes web applications as well as
In such a case, existing systems rely on an incomplete set of        their users to security breaches [10]. Without loss of generality,
sinks, which results in disregarding security vulnerabilities.       we focused on PHP as it powers 77% of all live websites [28].
Despite numerous studies on injection vulnerabilities, there            Injection vulnerabilities (e.g., command injection, insecure
has been no study that comprehensively identifies the set of         deserialization, or XSS) are the most common category of
functions that an attacker can exploit for injection attacks.        application vulnerabilities in web applications [10]. To exploit
   This paper addresses the drawbacks of relying on manually         such injection vulnerabilities attackers provide malicious
curated lists of sinks to identify such vulnerabilities. We devise   inputs to the web application, compromising both the backend
a novel generic approach to automatically identify the set of        systems as well as the clients. The root cause of an injection vul-
sinks that can lead to injection-style security vulnerabilities.     nerability is passing insufficiently sanitized attacker-controlled
To demonstrate the generality, we focused on three types of in-      user-input to sensitive APIs. Depending on the injection vul-
jection vulnerabilities: XSS, command injection, and insecure        nerability type, the sensitive APIs differ. For instance, PHP’s
deserialization. We implemented a prototype of our approach          echo is recognized as a sensitive API for XSS attacks, while
in a tool called Argus to identify the set of PHP functions that     unserialize plays the same role for insecure deserialization.
deserialize user-input, execute operating system (OS) com-           Despite these differences, at their core, injection vulnerabilities
mands, or write user-input to the output buffer. We evaluated        are data-flow problems where untrusted user-input is accepted
our prototype on the three most popular major versions of the        at information sources (e.g., HTTP request parameters),
PHP interpreter. Argus detected 284 deserialization functions        propagated throughout the web application’s execution, and
that allow adversaries to perform deserialization attacks, an        finally reaching sensitive sinks (e.g., echo or unserialize).
order of magnitude more than the most exhaustive manually               Existing systems proposed different approaches to detect
curated list used in related work. Furthermore, we detected 22       or exploit injection vulnerabilities using static, dynamic, or
functions that can lead to XSS attacks, which is twice the num-      hybrid analysis of web applications. Several approaches rely
ber of functions used in prior work. To demonstrate that Argus       on static taint analysis to track unsanitized user-input to a
produces security-relevant findings, we integrated its results       predefined list of sensitive APIs in order to detect different
with three existing analysis systems – Psalm and RIPS, two           types of injection vulnerabilities [1, 7–9, 21, 32, 42, 42].
static taint analyses, and FUGIO, an exploit generation tool.        Similar to static approaches, prior work also relied on dynamic
The modified tools detected 13 previously unknown deserial-          and hybrid techniques to identify injection vulnerabilities or
ization and XSS vulnerabilities in WordPress and its plugins,        generate exploits for already detected ones [25, 27].
of which 11 have been assigned CVE IDs and designated as                Despite the effectiveness of prior work in detecting security
high-severity vulnerabilities.                                       vulnerabilities, all existing systems possess one common flaw:



USENIX Association                                                                      33rd USENIX Security Symposium           6759
They rely on a manually curated or predefined list of sensitive      the PHP version). This implies that in order to identify the set
APIs to identify injection vulnerabilities. The accuracy of man-     of implicit deserialization functions featured by a given PHP
ually curated lists for sensitive APIs depend on the documenta-      version, one must analyze the implementation of the interpreter
tion for the programming language and the expertise of the ana-      itself. The same claim also applies to other injection-type
lyst who identifies the sensitive APIs. As is often the case with    vulnerabilities, such as XSS and command injection.
human involvement, the listings are not comprehensive which             To improve on the error-prone manual efforts on identi-
leads to undetected injection vulnerabilities (i.e., false nega-     fying injection APIs, this paper provides a systematic and
tives) in web applications. This intuition is not merely hypothet-   principled approach to inferring a comprehensive set of APIs
ical; our results show, incomplete lists of sensitive sink APIs      that can lead to XSS, command injection, or insecure deseri-
are commonplace and further lead to false negative results.          alization. To this end, we design, implement, and evaluate an
   Consider, as an example, the vulnerability type of insecure       automated approach called Argus to identify the list of APIs
deserialization. Insecure deserialization occurs when an             that deserialize user-input, execute OS commands, or write to
application deserializes untrusted data, such as user-input or       the output buffer. For consistency, we use the term , deseri-
generally attacker-controlled data. This vulnerability allows        alization, output and exec API to refer to the set of PHP APIs
an adversary to manipulate the control-flow of a vulnerable ap-      that perform deserialization, write to the output buffer, or exe-
plication by injecting a malicious serialized object. As applica-    cute OS commands, which can lead to an insecure deserializa-
tions commonly interact with objects after deserializing them,       tion, XSS, and command injection vulnerability, respectively.
an attacker-controlled object can lead to attacks, including         We demonstrate that by incorporating Argus’ resulting sink
arbitrary code execution. Existing studies of insecure deserial-     list into existing systems, those systems produce significantly
ization and PHP object injection focus on detection [7, 24, 37]      higher-quality results (i.e., more detected vulnerabilities and
and automated exploit generation [9, 27]. RIPS [7] and               exploits). Our key observation is that there is precisely one
Psalm [37] detect PHP object injection (POI) vulnerabilities         function inside the PHP interpreter that deserializes data –
by statically tracking user-inputs to the unserialize API            php_var_unserialize. Crucially, php_var_unserialize
function in PHP applications. Dahse et al. [9] presented the first   is at the core for all explicit and implicit deserialization APIs.
automated approach to generating POI exploits by tracking            Consequently, we argue that the correct way to identify the
the flow of user-input to invocations of the unserialize API.        set of deserialization APIs is to subject the PHP interpreter to
While Dahse et al.’s approach identifies POI vulnerabilities,        program analysis. In cases of XSS vulnerabilities, a PHP API
FUGIO [27] utilizes a fuzzing approach to generate a concrete        such as echo prints its argument to the output buffer, which
exploit object for an already detected POI vulnerability.            contains the HTML response sent back to the user’s browser.
   Deserialization in PHP is the consequence of invoking PHP         Our observation shows that there is one function inside the
API functions that perform deserialization either explicitly         PHP interpreter responsible for writing to the output buffer
or implicitly. For consistency, we use the term PHP API to           called php_output_write. Similarly, the set of exec APIs will
refer to the set of functions provided by the PHP runtime            eventually invoke the execve system call in order to execute
that can be directly invoked by web applications. Explicit           the OS command. For brevity, we use the term vulnerability
deserialization APIs are described throughout the PHP                indicator functions (VIF) throughout the text to refer to the
manual [12]. One can identify the functions of this group by         functions php_var_unserialize, php_output_write, and
studying or analyzing the PHP documentation to curate a list         the functions inside the PHP interpreter that directly invoke
of explicit deserialization functions – this approach was taken      the execve system call or use its front-ends in C (e.g., exec
by RIPS [7], Psalm [37], FUGIO [27], and Dahse et al. [9].           family).
However, implicit deserialization functions are not described           Argus detects the set of deserialization, exec, and output
in the PHP manual, and are therefore more challenging to             APIs through an automated hybrid static-dynamic program
identify. First described by Thomas for PHP in [36], implicit        analysis of the PHP interpreter. Specifically, Argus first gen-
deserialization happens if the PHP interpreter transparently         erates the call-graph for a given PHP interpreter. Subsequently,
deserializes data consumed by certain APIs. For example,             Argus performs a reachability analysis to identify the set of
Thomas found that the stream wrapper for the PHP archive             PHP API functions whose invocation can trigger either dese-
(PHAR) format implicitly deserializes metadata, which led            rialization or output API in the interpreter (i.e., reach the VIF).
to the identification of multiple PHAR-based deserialization         Using this approach, Argus detected more than 280 functions
vulnerabilities in popular web applications and libraries such       (in PHP 7.2) that deserialize their arguments and 22 functions
as WordPress and TCPDF (details in Section 2.4). Crucially,          whose invocation writes their arguments to the output buffer.
implicit deserialization functions are equally as potent for            We demonstrate the security impact of Argus by integrating
adversaries as explicit ones. However, implicit deserialization      its findings as the set of injection-sinks into three PHP analysis
APIs are not documented publicly, and the number and identity        tools; Psalm [37] and RIPS [1] (static taint analyses to identify
of these functions depend on the implementation of the PHP           POI, command injection, and XSS vulnerabilities) and FU-
interpreter (i.e., the set of deserialization APIs varies with       GIO [27] (a POI exploit generation system). When evaluating



6760    33rd USENIX Security Symposium                                                                          USENIX Association
Psalm with the extended list of injection-sinks on over 1,900        2.1    PHP interpreter and Cross-site Scripting
popular PHP applications and plugins, our evaluation yielded
10 times more potential for insecure deserialization compared        A cross-site scripting (XSS) vulnerability is an injection
to Psalm’s default implementation (which exclusively reported        vulnerability that allows an attacker to compromise the
false positives). Furthermore, we integrated Argus’ list of dese-    interactions of the victim with a vulnerable application [21].
rialization sinks into FUGIO and discovered proof-of-concept         This vulnerability allows the attacker to execute malicious
exploits for 12 previously unknown deserialization vulnerabil-       scripts in the victim’s web browser by including malicious
ities on the same data set. In summary, this paper makes the         code in a legitimate web application.
following contributions:                                                In the life-cycle of a request sent to a web-server such as
                                                                     Apache or Nginx, the PHP interpreter plays an important role
    • We draw attention to the importance of accurately and          in providing the output shown to the user. When a web-server
      comprehensively detecting APIs in PHP that lead to             receives a request for a PHP script, the web-server invokes the
      injection vulnerabilities such as insecure deserialization,    PHP interpreter to determine the output. The PHP interpreter
      XSS, and command injeciton.                                    executes the PHP script, which can include interaction with
                                                                     a database, the file system, or the underlying operating system.
    • We design and implement a novel automated analysis             After the execution of the script, the PHP interpreter provides
      and prototype (called Argus) to identify the set of            the output in the form of HTML to the web-server. The output
      deserialization, exec, and output APIs applicable to any       is then sent back to the user as the response.
      version of the PHP interpreter.                                   Thus, the PHP interpreter determines the response that
                                                                     the web-server sends back to users. In order for a PHP script
    • Evaluating Argus on the three most popular PHP versions        to assemble the response, the PHP interpreter provides a set
      identifies over 280 deserialization APIs, at least an order    of built-in functions (i.e., PHP API), which PHP scripts can
      of magnitude more than the most extensive manually             use. One of the APIs that is used to modify the response of a
      curated list used by prior work (i.e., 26 sinks in FUGIO).     web-server is echo. This function accepts one or more strings,
      An adversary can leverage a call to any of these APIs to       which are then sent verbatim to the output buffer. However,
      exploit a PHP application. Argus also detects 22 output        the set of APIs that can modify the response of a web-server
      APIs, which is twice the number of APIs that were used         is not limited to only one API. According to prior work such
      in the past to detect XSS vulnerabilities. In addition,        as RIPS [7], there are 12 functions in the PHP interpreter that
      Argus detects 9 exec APIs which can be used to detect          can modify the output buffer.
      command injection vulnerabilities by Psalm and RIPS.              In a cross-site scripting attack, the attacker is able to modify
                                                                     the response that is sent back to the user’s browser. If an
    • In order to demonstrate the real-world impact of               attacker has control over the arguments passed to an API
      these findings, we incorporated our results into three         such as echo, an XSS attack is a certainty. This capability of
      existing analysis tools, Psalm, RIPS, and FUGIO. Our           the echo API is provided by an internal function of the PHP
      refinements of the sink-lists used by these tools led to the   interpreter, which allows APIs to write into the output buffer
      identification of 13 previously unknown POI and XSS            (i.e., the HTML response). An analysis of the source-code of
      vulnerabilities. Of course, we responsibly disclosed all       the PHP interpreter reveals that all write opration to the output
      our findings to the corresponding developers. As such,         buffer goes through a function called php_output_write. As
      11 of the detected POI vulnerabilities have been assigned      a result, all invocations of the php_output_write by the PHP
      CVE IDs (CVSS scores between 7.2 and 8.8), and seven           APIs can modify the response sent back to the web-server,
      vulnerabilities have already been patched.                     which is the superset of all the APIs identified in prior work.


                                                                     2.2    PHP interpreter and command injection
2    Background and Motivation
                                                                     Command injection in PHP applications occurs when a ma-
In this section, we describe XSS, command injection, and             licious actor gains the ability to execute arbitrary commands
deserialization in PHP and how these vulnerabilities arise (e.g.,    (e.g., through a shell) [3]. Command injection attacks result
implicitly from file operations). This background allows us          in a range of consequences, such as compromised data confi-
to shed light on our results and put the evaluation presented in     dentiality and integrity or unauthorized access to the system
Section 4 in context. Finally, we elaborate on our assumptions       hosting the application. An attacker can leverage the exploited
about XSS and insecure deserialization attacks on PHP                application to execute a malicious payload and gain access to
applications and our motivation to design an automated               additional resources.
approach to identify a comprehensive set of deserialization,            As mentioned in Section 2.1, in the life-cycle of a request, the
exec, and output functions in an interpreter.                        PHP interpreter executes a PHP script. During this execution,



USENIX Association                                                                      33rd USENIX Security Symposium            6761
the PHP interpreter communicates with the resources through           1    class Example {
the operating system to determine the output.                         2       protected $ obj ;
                                                                      3       function __destruct () {
   The operating system provides mediated access to resources         4           return $ this ->obj -> getValue () ;} }
through the system call API. Applications such as the PHP             5    class Exec {
interpreter can access OS resources by invoking system call           6       private $ _cmd ;
APIs. A PHP interpreter executes OS commands by invoking              7       function getValue () {
                                                                      8         system ($ this -> _cmd ); } }
the execve system call or its wrappers in the C libraries, such as    9    $ user_data = unserialize ($ _POST ['data']) ;
the family of execv functions [22]. Consequently, a command          10    file_exists ($ _POST ['file']) ;
injection attack only occurs when the PHP application uses                Listing 1: A deserialization vulnerability leading to
a PHP API that invokes the execve system call and passes                  arbitrary code execution. An adversary can execute any
insufficiently sanitized user-input. As a result, a PHP API is            command by crafting a PHP object which modifies the
part of the Exec API if its underlying implementation invokes             value of _cmd property.
the execve system call.
                                                                     2.4      Stream Wrappers
2.3    PHP Object Injection                                          In this section, we explain the concept of PHP stream wrappers
PHP object injection (POI) is a security vulnerability that          and how an attacker can abuse stream wrappers to cause a
leverages insecure deserialization in PHP applications. To           PHP object injection. A stream in the PHP interpreter is a
exploit such a vulnerability, an adversary must control the          generalization of a data source which implements a set of
properties of an insecurely deserialized object. By exploiting       common file operation functions such as fopen and copy.
a POI vulnerability, an attacker can potentially hijack the          PHP Stream wrappers allow developers to use consistently-
program’s execution by controlling the properties used in            named file-related functions such as fopen for different
automatic calls to the __wakeup and __destruct methods.              types of file resources. The types of resources are identified
   The snippet in Listing 1 presents a PHP script that contains      analogous to URL schemes and can vary from classic local
a deserialization vulnerability. We observe that at Line 9,          files (e.g., /etc/passwd), network reachable resources (e.g.,
user-input is passed to the unserialize function without             https://example.com/text), to PHAR archive types
sanitization. In order to exploit this vulnerability, the attacker   (e.g., phar://usr/share/app.phar). Importantly, once the
needs to satisfy two conditions.                                     resource’s type is identified, the PHP interpreter, maps each
                                                                     type to a corresponding stream wrapper which allows the
   • There needs to be at least one class in the application         application developer to transparently perform (supported)
     which implements the class methods __wakeup or                  file operations on the resource (e.g., read, seek, etc.).
     __destruct to carry out the attack.                                PHP Archives (phar) allow developers to package an
                                                                     entire PHP application in a single file. To interact with phar
   • All of the classes used in the exploit need to be defined (or   files, PHP provides a built-in stream wrapper. Each phar file
     the application must support automatic loading of classes)      contains the following sections:
     when the unserialize function is called on Line 9.
                                                                          • Stub: A PHP file that instructs the interpreter how to
   Exploiting a POI vulnerability is inherently a code-reuse                load the application.
attack, where an attacker recombines the already existing code
to achieve a malicious outcome by introducing a malicious                 • Manifest: Includes the number of files in the phar, as
object. To exploit a POI vulnerability the attacker needs to                well as the file permissions, type of compression, and
identify the user-defined functions and methods (i.e., gadgets)             serialized metadata. The metadata includes a description
in the PHP app that can be used to achieve his goals [27]. As an            for the existing files in the archive in a serialized format.
example, we describe how an attacker can choose the gadgets
                                                                          • Contents: The content of files in the phar archive.
to link and perform a remote code execution attack in Listing 1.
Looking at Listing 1, the script defines two classes prior to the         • Signature: An optional signature for the file’s integrity.
deserialization: Example and Exec. The destructor of class
Example calls a function named getValue from the variable            Exploiting phar wrappers. Thomas in [36] demonstrated
obj. If an attacker sets the variable obj to an object of class      how an attacker can exploit an invocation of a file operation
Exec, then the destructor will call the class method getValue        API and perform a PHP object injection. He showed that
at Line 7. Looking at the implementation of class Exec, the          the PHP interpreter deserializes the metadata upon any file
method getValue invokes the function system on the _cmd              operation on a phar file. Considering the aforementioned
property. Hence, the attacker can run an arbitrary command           information, an adversary can achieve arbitrary code execution
be setting the value of the _cmd. The code snippet in Listing 3      by leading the PHP interpreter to perform file operations (e.g.,
contains the exploit for the vulnerability in Listing 1.             file_exists) on a phar file with a malicious metadata field.



6762    33rd USENIX Security Symposium                                                                            USENIX Association
  The second part of Listing 3 shows how an attacker can             demonstrate exploitability and is orthogonal to Argus’ goal
generate a phar file with malicious metadata (set on Line 12).       of identifying deserialization and output APIs.
Looking at the snippet in Listing 1, we observe that the PHP
script checks the existence of a file by passing an unsanitized
user-input at line 10. In order to exploit the vulnerability at      3     System Design
Line 10 of Listing 1, the attacker can set the $POST variable
file to phar://path-to-malicious-phar-file.                          In this section, we discuss the salient characteristics of our ap-
                                                                     proach – Argus – and how it identifies the set of deserialization,
                                                                     exec, and output PHP APIs. Figure 1 illustrates the overall
2.5    Observations, Motivation and Assump-                          process. First, Argus combines static and dynamic analysis
       tions                                                         techniques to generate a call-graph of a PHP interpreter in
                                                                     Step 1 . Subsequently, for Step 2 , Argus uses the call-graph
Our work is motivated by the error-prone human efforts to
                                                                     to perform a reachability analysis to determine the set of
aggregate lists of deserialization, exec, and output APIs in
                                                                     API functions that invoke the VIFs. Furthermore, Step 3
PHP. Consider the case of CVE-2022-2437, an insecure de-
                                                                     discusses the validation mechanism in Argus to confirm the
serialization vulnerability that Argus identified in the popular
                                                                     injection-sinks. Finally, we discuss how we incorporate Argus’
Feed Them Social WordPress plugin (detailed discussion in
                                                                     results into existing program analyses to detect and exploit
Section 4.3.1). This vulnerability exists because of the im-
                                                                     previously unknown vulnerabilities.
plicit (i.e., undocumented) deserialization performed by the
get_meta_tags PHP API function. As this API is missing
from all sink lists of prior systems, the vulnerability went unno-   3.1     Call-graph Generation
ticed. Argus automatically identified this function (along with
over 280 others) as a deserialization API, and by incorporating      In Step 1 , Argus generates a call-graph for the PHP
this knowledge in existing POI analysis systems these systems        interpreter. To achieve this, Argus performs a static analysis
readily detected and created POC exploits for this vulnerability.    on the PHP interpreter to generate the initial call-graph, which
   As mentioned in the introduction, Argus’ analysis relies on       it then refines using dynamic execution traces.
a key observation regarding the invocation of deserialization,
exec, or output APIs inside the PHP interpreter. In the case         3.1.1   Static Analysis of the PHP Interpreter
of deserialization, the PHP interpeter uses its own template
and formatting for serialized data. The PHP interpeter uses          To construct the call-graph, Argus analyzes the PHP interpreter.
a customized yacc [20] parser to first parse the serialized          The PHP interpreter’s core consists of approximately 120K
data and then perform the deserialization. Our analysis of           lines of C code. Additionally, the interpreter relies on exten-
the PHP source-code shows that there is only one function            sions to deliver features such as image processing, database
inside the PHP interpeter, which uses the yacc parser. Hence,        communication, and communication protocols such as LDAP
there is only one function responsible for deserialization:          and IMAP. These extensions are free to augment the PHP API,
php_var_unserialize. In the case of output APIs, we                  including adding additional injection-sinks, and frequently
analyzed the source-code of the PHP interpreter. Specifically,       do so. For example, in a standard PHP deployment, the GD
we analyzed the underlying implementation of output APIs             graphics library, the PDO database communication extension,
such as echo and print_r and identified the set of invoked           and the FTP extension are provided as separate libraries and
functions inside the interpreter. For a more comprehensive           all add additional injection-sinks to the runtime. To complicate
study of the output APIs, we executed the official PHP testsuite     matters further, extensions can be written in different
and analyzed all the function traces for each output API that        programming languages (e.g., [6, 41]), provide their own build
leads to writing to the output buffer (i.e., using the write         environments, and are usually simply loaded by the interpreter
system call). Similar to our observation for deserialization,        as shared dynamic libraries. However, injection vulnerabilities
the PHP interpreter uses the output module and specifically          can arise from any API provided by the runtime, including
the function php_output_write inside this module to write            APIs provided by the core interpreter and those provided by
to the output buffer (i.e., the HTML response).                      extensions. As such, it is imperative to analyze the interpreter’s
   Many implicit deserialization and output APIs are vulner-         core along with the code that comprises the extensions. At first
able if an attacker can invoke them on a malicious file (e.g.,       glance, the open source nature of the PHP interpreter would
PHAR archives). For such attacks to succeed, the malicious           suggest a source-based analysis to infer the call-graph. How-
file must reside on the web application’s file system. Thus,         ever, the variety of frameworks, languages, and build systems
to demonstrate exploitability, we assume an attacker already         used for extensions would require an analysis catering to all
uploaded a malicious file to the underlying web-server. Note         these characteristics. Thus, instead of deriving call-graph in-
that, while this assumption is realistic (see Section 5 for a        formation from various interconnected source-based analyses,
more detailed explanation), the assumption purely exists to          Argus instead performs its call-graph analysis on the compiled



USENIX Association                                                                      33rd USENIX Security Symposium           6763
                              PHP Tests             List of identified VIFs                                                            User Input

                                                                                                                                        Source

                      1                         2                                3                                         4A
                                                            Reachability

                           Execution Traces                                                                                   Sinks
                               uftrace
                                                                                                                                Taint Analysis
                                    TR                                                                       PHP APIs
           PHP                                                                                                             4B     Exploit Objects
        Interpreter
                                                                                                                            Hooks
                                                                                            Generate
                                                              Set of APIs that         Validation Template                    Exploit Generation
                      CG                         RA           invoke the VIFs




                                                                                                                                      ...
                                                    Argus                                                               Existing Program Analyses


Figure 1: Argus performs a hybrid static-dynamic analysis on the PHP interpreter to generate a call-graph. Next, Argus identifies
a comprehensive set of output, exec, and deserialization APIs through reachability analysis and validation tests. The output of
Argus can be used to improve the existing program analysis tools to identify POI and XSS vulnerabilities.
binaries of the interpreter and its extensions. To facilitate this               the PHP interpreter while executing its high-quality test-suite
analysis, we build the runtime and include debug symbols.                        (i.e., the PHP test-suite achieves 70% function coverage on
   The call-graph analysis ( CG in Figure 1) first disassembles                  average for our dataset of three different PHP interpreters).
the PHP interpreter and all of its shared libraries using the                    Argus then uses this dynamic information and adds any edges
objdump tool. Argus builds the call-graph by adding a node                       not already detected by the static analysis to the call-graph.
for each binary symbol in the disassembled PHP interpreter.                         To achieve this, we compile the PHP interpreter with the -pg
Subsequently, Argus performs a linear scan over the interpreter                  flag. This flag instruments each function with two additional
and library disassembly. For every call instruction, CG draws                    hook functions at the entry and exit of each function, which al-
an edge in the call-graph from the caller (i.e., the currently ana-              low Argus to perform dynamic tracing [35]. The first function
lyzed symbol) to the callee (i.e., the target of the call). This anal-           call occurs just after each function entry, which invokes the
ysis works well for direct calls and calls to symbols provided by                function __cyg_profile_func_enter. The next function
extensions. That is, direct calls will invoke symbols that have                  call invokes the function __cyg_profile_func_exit before
corresponding names in the debug information. Argus handles                      exiting each function. After the recompilation of the PHP
calls to imported symbols by launching the PHP interpreter                       interpeter, Argus uses the uftrace tool [23] ( TR in Figure 1)
with the LD_DEBUG=binding environment variable set to in-                        to implement both hook functions and record dynamic traces.
fer symbol binding information from extension libraries. The                     Finally, Argus executes the PHP unit tests while uftrace
LD_DEBUG option allows Argus to resolve the external symbols                     records the execution traces for each test-case.
to the library and address where the symbols are implemented.                       After recording the execution traces, Argus iterates over the
Unfortunately, indirect calls (e.g., those that are used to imple-               sequence of invoked functions by each test-case and examines
ment the concept of stream wrappers) elide this analysis.                        the statically generated call-graph for the missing edges. For
                                                                                 every invoked function during the dynamic analysis, Argus
3.1.2   Refining Call-graph using Dynamic Analysis                               draws an edge between the pair of functions in the execution
                                                                                 trace if there is no edge representing the recorded invocation.
Argus uses dynamic analysis to handle indirect calls in the                         At the end of this step, Argus has assembled a static
PHP interpreter and refine the statically generated call-graph                   call-graph of the PHP interpreter and refined it using
created in the previous step. For instance, PHP’s fopen can                      dynamically-collected traces of PHP unit tests.
be used to access local or remote files over protocols such as
HTTP, HTTPS, or FTP. Depending on the argument passed to
fopen, the PHP interpreter decides which stream wrapper (see                     3.2      Reachability Analysis
Section 2.4) should handle the underlying resource. Internally,
PHP stream wrappers rely on function pointers to dispatch                        In Step 2 , Argus performs a reachability analysis on the
operations (e.g., fread()) to functions that handle the proto-                   generated call-graph, which requires the identification of
col corresponding to the opened resource. The static analysis                    sources and sinks on the call-graph. In this analysis, Argus
in Argus cannot handle such cases implemented in the PHP                         identifies the set of PHP APIs that reach the VIF functions.
interpreter and runtime. To address this issue, Argus improves                    We define VIFs as the minimal set of PHP internal functions,
the statically generated call-graph by tracing the execution of                  that user-input must pass through to trigger a vulnerability. As



6764    33rd USENIX Security Symposium                                                                                          USENIX Association
stated in Section 1, the PHP interpreter uses a single internal      3.3    Validation
function that is responsible for all deserialization operations,
called php_var_unserialize (VIF). The PHP interpreter                The reachability analysis presented above might inappro-
uses a custom parser to parse serialized strings, which are then     priately label an API as an injection-sink if the underlying
converted to PHP objects. Our analysis of this custom parser         implementation in the runtime performs input sanitization or
across PHP’s source-code yielded a single deserialization            filtering. Thus, Step 3 filters APIs and only passes those that
function inside the PHP interpreter. In the case of output           propagate their input to VIF unmodified. To this end, Argus
APIs that write to an output buffer, we observed a similar           automatically generates PHP snippets to test each identified
pattern during our analysis of PHP’s code, where the function        API for this characteristic. More specifically, these snippets
php_output_write is exclusively responsible for outputting           contain a class definition (i.e., test) that, if deserialized (i.e.,
the buffer. As mentioned in Section 2.2, any PHP API that            its __wakeup method is invoked), prints the content of one of
executes an OS command requires the execve system call. As           its properties (i.e., msg) as a success message. Subsequently,
a result, in order to identify the functions inside the PHP inter-   the template calls the API in question with a serialized test
preter (VIFs) for command injection, Argus needs to identify         object that has msg set to “SUCCESS”. Thus, if the execution
the functions that call the execve system call. To achieve this,     of the PHP snippet prints the success message, Argus validates
we leveraged Saphire [3], to identify functions that invoke the      that the API in question passes the input argument unmodified
execve system call. We marked these functions as the VIFs            to VIF, and hence the API is for sure a deserialization API. For
for the exec APIs. These PHP internal functions are php_exec,        each API, the validation step iterates over various patterns of
zif_shell_exec, zif_popen, phpdbg_do_sh, php_mail,                   passing inputs including explicit (e.g., serialized data) and im-
zif_pcntl_exec, _php_imap_mail, and zif_proc_open.                   plicit (e.g., Phar file). When one input leads to deserialization
With the VIF identified, Argus labels all API functions in the       which invokes our test function and prints out the ”SUCCESS”
call-graph as sources.                                               message, Argus marks the API as a deserialization API. The
                                                                     psuedo-code in Listing 4 (Appendix B) shows the process of
   Unfortunately, the symbols for API functions are indis-           validating the reachable APIs identified.
tinguishable from those of internal functions, and text-based            As our evaluation in Section 4 will show, Argus confirmed
techniques that parse documentation are rarely, if ever,             284 deserialization APIs in the PHP interpreter, which
accurate. However, a running PHP process must be aware               warranted an automated validation step. However, the number
of any and all APIs exposed to the web applications running          of confirmed output APIs in the PHP interpreter is an order
on top of it. Thus, to identify the set of APIs, Argus uses a        of magnitude less (i.e., 22), which prompted us to manually
PHP extension that, once loaded into the PHP interpreter,            validate whether the invocation of the API with user-input can
iterates over all available APIs. Specifically, the extension        cause an XSS attack. To this end, we created a Docker container
first invokes PHP’s get_defined_functions API to obtain              with a running Nginx web-server for each PHP interpreter
the list of all API functions. Unfortunately, the results of         version. For each output API, we created a PHP template that
get_defined_functions cannot be directly mapped to the               invokes the API and passes a constant user-input containing a
call-graph. The reason is that the name of an API function           Javascript snippet (i.e., <script>alert(1)</script>). We
available to a web application is commonly different from the        visited the generated PHP template with a browser, and if the
name of the symbol that implements the actual functionality.         browser displays a dialog, Argus marks the tested API as an
For example, the session_decode PHP API is implemented               output API. In case of the exec APIs, we manually validated
by a function called zif_session_decode. Unfortunately,              the set of PHP APIs that execute commands in the PHP
the zif prefix is not a consistent pattern. As the nodes in          interpreter. For each exec API, we created a PHP script that
the call-graph correspond to symbol names rather than API            invokes the API and passes a constant user-input containing an
names, the API names have to be translated. To this end, the         OS command (i.e., ls -lh which lists the directory content).
extension leverages an interpreter-internal data structure (i.e.,    The PHP interpreter under test executes each of the generated
executor_globals.function_table), which maps API                     PHP scripts, and if the PHP script prints out the directory
names to the names of the functions that implement the APIs’         information, Argus marks the PHP API as an exec API.
functionalities. Finally, the extension relays this information
to Argus, which labels the symbols that map to API functions
in the call-graph accordingly.                                       3.4    Extend Security Analysis Tools
   Once all APIs are labeled as sources, Argus traverses             Argus’ results comprise a comprehensive list of injection-sinks.
the call-graph for each source node and follows any call             This is in contrast with the exclusively manually-crafted lists of
edges captured in the graph. Argus identifies an API as a            injection-sink used by all existing XSS and POI detection and
deserialization, exec, or output API if this traversal includes      automatic exploit generation systems. Thus, to demonstrate the
the graph node corresponding to its VIF function.                    value of Argus’ principled approach, we extend three existing



USENIX Association                                                                       33rd USENIX Security Symposium           6765
program analysis tools, Psalm [37], RIPS [7], and FUGIO [27]           detection and exploit generation systems as examples that
as examples of downstream analysis that benefit from our work.         demonstrate the security impact of Argus’ results.
                                                                          Our implementation of the call-graph analysis for the PHP
                                                                       interpreter consists of approximately 700 LoC of Python and
3.4.1   Psalm and RIPS Extension
                                                                       C code. In addition, we implemented our extensions to Psalm
Psalm and RIPS are two static analysis tools featuring code            and FUGIO with less than 600 LoC of PHP.
refactoring and taint analysis [37]. For the taint analysis,
Psalm and RIPS attempt to find unwanted flows between                  4     Evaluation
user-controlled inputs (e.g., $_GET variables) and a set of sink
functions (e.g., system). The set of sink functions in Psalm           In this section, we evaluate Argus along two orthogonal dimen-
and RIPS differs depending on the type of vulnerability that           sions. First, we focus on identifying deserialization, exec, and
the user is trying to detect. For instance, to identify insecure       output APIs in the three most popular major versions of the
deserialization, they exclusively consider unserialize as a            PHP interpreter. The reason for evaluating different interpreter
sink for the core PHP interpreter.                                     versions is that the number and names of deserialization, exec,
   As shown in previous reports [36] and in our evaluation,            and output APIs are implementation and version dependent,
relying on incomplete lists of sinks results in false negatives        calling for an automated solution such as Argus. In the second
(i.e., missed detections). To extend the static analysis tools, we     thrust of the evaluation, we assess how Argus’ analysis results
modify the list of taint sinks to include all deserialization, exec,   improve the accuracy of three example PHP security analysis
and output APIs identified by Argus.                                   systems – Psalm, RIPS, and FUGIO. To cover these two dimen-
                                                                       sions, our evaluation answers the following research questions:
3.4.2   FUGIO Extension                                                RQ1: In terms of call-graph generation, how precise is the
                                                                       call-graph generated by Argus compared to existing call-graph
FUGIO is an automatic exploit generation tool which uses a             generation tools such as Joern (Section 4.2.1)?
combination of static and dynamic analysis to generate a proof         RQ2: On the interpreter’s call-graph, how many PHP APIs
of concept exploit for previously known POI vulnerabilities.           reach the VIF functions (Section 4.2.2), and how many of
In the first step, FUGIO submits requests to a target web              the reachable APIs pass their arguments to VIF unmodified
application where request parameters (e.g., GET, POST,                 (Section 4.2.3)?
and COOKIE values) contain serialized data. During the                 RQ3: How does the number and identity of deserialization,
processing of these requests, FUGIO hooks the invocation               exec, and output APIs change across PHP versions and what
of deserialization APIs and verifies if the passed arguments           are the reasons for the observed changes (Section 4.2.4)?
correspond to the parameters supplied in the request. To               RQ4: How do Argus’ results improve the current state-of-the-
this end, FUGIO hooks a subset of 27 PHP deserialization               art PHP security analysis that target injection vulnerabilities?
APIs – the explicit unserialize API along with 26 implicit             Does Argus’ comprehensive list of injection-sinks lead
APIs first mentioned by Thomas [36]. If FUGIO detects that             to the identification of previously unknown POI and XSS
parameters are indeed forwarded to deserialization APIs,               vulnerabilities (Section 4.3)?
its second step will attempt to morph the parameter into a
complete POP chain, forming a POC exploit. While FUGIO’s
second step (i.e, the exploit generation itself), is independent
                                                                       4.1    Evaluation Dataset
of our work, the first step (i.e., recognizing the invocation of       Our evaluation dataset for Argus is divided into two categories
vulnerable deserialization APIs) is directly affected by the           corresponding to the two evaluation dimensions. For our
(in-)completeness of the list of deserialization APIs.                 experiments on the PHP interpreter, we evaluated Argus on the
   To extend FUGIO, we integrated the set of deserialization           three most popular major versions (i.e., versions 5, 7, and 8)
APIs identified by Argus such that FUGIO hooks all these               of the PHP interpreter. As of June 2023, PHP engines of these
APIs in its first analysis step. The extended FUGIO intercepts         versions power 99.8% of all live PHP websites, according
a comprehensive set of PHP APIs which allows it to identify            to W3Tech data [28]. Furthermore, PHP seven is used by
and exploit previously unknown POI vulnerabilities (see                65.2% of all live websites using PHP, which makes it by far
Section 4.3.2 for details).                                            the most popular PHP engine [28]. Our second dataset is
   In summary, Argus generates a call-graph for the PHP                used to evaluate the benefit of Argus’ results to existing POI,
interpreter by leveraging hybrid static-dynamic analysis. Fur-         command injection, and XSS detection systems as well as
thermore, Argus performs a reachability analysis to identify           exploit generation systems. As these systems operate on the
a comprehensive set of deserialization, exec, and output APIs          code of web applications, rather than the PHP interpreter,
in the PHP interpreter, and optionally validates APIs that pass        we aggregated a dataset corresponding to that purpose. We
their inputs unchecked to the underlying VIF deserialization,          collected the most popular PHP applications and plugins from
exec, and output functions. We augmented three existing                a variety of sources. On the one hand, we downloaded the 60



6766    33rd USENIX Security Symposium                                                                          USENIX Association
most popular PHP applications based on the reported popular-         source-code analysis tool. Hence, the compile-time aspects are
ity provided by W3Tech [28]. On the other hand, we recognize         an important source for the differences between the generated
that large web applications frequently feature a plugin model        call-graphs by Argus and Joern. In the case of Argus, the
that allows administrators to customize their sites. As such,        missing edges are related to cases of preprocessor directives
we also collected the most downloaded plugins for the popular        and compiler optimizations (i.e., these missing edges do not
WordPress, Drupal, and Typo3 web applications from their             exit in the binary and cannot be exercised). For example, the
respective repositories. Overall, we collected 1,977 PHP             preprocessor decides to keep or remove blocks of code based
artifacts (i.e., web applications and plugins). Table 3 provides     on directive conditions (e.g., #ifdef); hence, the compiled
a detailed breakdown in the first two columns.                       version of the same source-code can lead to a different
                                                                     binary artifact depending on the condition. As a result, Argus
4.2     Analysis of the PHP Interpreter                              analyzed a version of the PHP interpreter where some function
                                                                     calls were removed due to preprocessor directives, compared
As the PHP language and ecosystem evolves, the interpreter           to Joern. Furthermore, the analysis of the missing edges by
must provide support and functionality accordingly. Unsur-           Argus shows that the invoked functions are related to memory
prisingly, this evolution also affects the number and identity       management in C, such as free and malloc. Our analysis
of the injection-sink functions provided by different versions       shows that the missing edges do not affect the ability of
of the PHP interpreter. To assess these changes, we evaluate         Argus to detect injection-sink functions since the memory
Argus on three different versions of the PHP interpreter             management functions in this case are the leaves in the
(versions 5.6, 7.2, 8.0) as detailed in Table 2.                     call-graph and do not affect the reachability analysis.
                                                                        In the case of Joern, the missing edges are mostly related
 PHP interpreter   Argus    Joern    Argus - Joern   Joern - Argus
 PHP 5.6           56,504   31,065      26,024            585
                                                                     to function pointers in the PHP interpreter. As mentioned in
 PHP 7.2           68,410   39,560      30,620           1770        Sections 2.4 and 3.1.2, the PHP interpreter extensively uses
 PHP 8.0           47,653   33,555      16,636           2538        function pointers in order to implement its functionality. Jo-
                                                                     ern’s call-graph analysis misses the set of indirect calls inside
Table 1: Argus outperforms Joern in terms of detected edges          the PHP interpreter, which includes function pointers related
for analyzing the PHP interpreter. The second and third              to stream wrappers for different file types. Consequently,
columns show the number of detected edges by each tool. The          Joern is not able to detect indirect calls to the PHAR module
last two columns report the comparison between the number            from any file operation APIs such as fopen, and using such a
of detected edges (i.e., subtraction of matching edges).             call-graph would lead to missing all file operation APIs, which
                                                                     lead to insecure deserialization.
4.2.1   Argus vs. Joern
Argus uses the call-graph of the PHP interpreter in order            4.2.2   Reachable APIs
to identify injection-sink functions, rendering call-graph
generation a crucial step for Argus. For our first evaluation, we    Next, we look into the reachability analysis of Argus and the
investigate the generated call-graphs by Argus and compare           number of PHP APIs that invoke the VIF in the analyzed PHP
the results with Joern, an open-source code analysis tool [19].      interpreters. The first set of sub-columns in Table 2 labeled as
During this evaluation, we analyze the PHP interpreter and           Detected for both injection vulnerabilities shows the number of
generate the call-graph using both Argus and Joern. We then          APIs that Argus identified as reaching VIF for the three differ-
compare the generated call-graphs by both tools based on the         ent PHP versions. As the table shows, the number of deserializa-
number of detected edges.                                            tion APIs for versions 5 and 7 is similar, and two orders of mag-
   We compared the generated call-graphs in two dimensions:          nitude larger than for version 8. We discuss the difference in the
1) a quantitative comparison of the call-graphs for the number       number of reachable deserialization APIs in Section 4.2.4. Fur-
of missing edges, and 2) a qualitative evaluation to investigate     thermore, the number of output and exec APIs for the analyzed
the effect of missing edges on identifying injection-sink            PHP versions is almost constant across all three versions.
functions. Our evaluation of the call-graphs generated by               In our evaluation of Argus’ call-graph generation, we
Argus and Joern is listed in Table 1. This comparison shows          explored the contribution of both of our dynamic and static
that the call-graph generated by Joern misses 24,426 edges that      analysis. This analysis demonstrates the advantages of
are included in the call-graphs generated by Argus, on average.      using both static and dynamic analysis while generating the
There are also cases where Argus misses edges that Joern can         call-graph. To demonstrate the effectiveness, we looked into
detect. However, the number of missing edges by Argus is 15          the number of injection-sinks that Argus can detect by only
times less than the number of edges missed by Joern.                 using the statically generated call-graph. To achieve this, we
   For the second part of this evaluation, we investigated the       performed a reachability analysis on the statically generated
missing edges in the call-graphs of both Argus and Joern.            call-graph of the PHP interpreter before augmenting the
Compared to Argus which analyzes the binary, Joern is a              call-graph with dynamic information (Step A-2). The numbers



USENIX Association                                                                      33rd USENIX Security Symposium           6767
 Version     Deserialization API      XSS-leading API           Exec API
            Detected Validated      Detected Validated    Detected Validated
                                                                                the VIF or the input is sanitized. For instance, Argus detects
 PHP 5.6    419 (61)    281 (67%)    54 (51)   22 (41%)    10 (10)     9(90%)   the function highlight_string reaches the output VIF
 PHP 7.2    425 (63)    284 (67%)    52 (48)   22 (42%     10 (10)     9(90%)   function (i.e., php_output_write), however, the input is
 PHP 8.0    20 (13)     13 (65%)     46 (39)   22 (48%)    10 (10)     9(90%)
                                                                                sanitized by replacing "<" with "&lt;". As a result, the
Table 2: Our analysis of PHP interpreter shows PHP in-                          attacker’s input does not cause an XSS attack and the function
terpreters prior to version 8.0, contained more than 300                        highlight_string fails the validation test. In case of dese-
PHP functions that deserialize their arguments, execute                         rialization, the SplTempFileObject::__construct opens
OS command, or write to output buffer. The numbers in                           a temporary file object that the user cannot control. As a result,
parentheses of Detected sub-columns show the number of                          an attacker cannot trick the API to open a malicious PHAR
APIs detected using only the statically generated call-graph.                   file and validation failed. Table 5 (in the Appendix) contains
                                                                                the complete list of deserialization APIs for PHP versions
in parentheses in the sub-column Detected for Table 2 show                      analyzed. Note that the set of APIs in version 7.2 is a strict
the number of reachable APIs while using only the statically                    superset of the APIs in version 5.6. The table also highlights
generated call-graph. As an example, we can see that the                        the APIs that still show deserialization capabilities in version
difference in the number of detected APIs for PHP 5.6 when                      8.0 by typesetting their names in bold. As shown in Table 2, all
only using the statically generated call-graph is six times less                three versions of the PHP interpreter have 22 validated output
than when incorporating the dynamic analysis information.                       APIs, which are exactly the same among all the versions.
Similar to Joern, the missing edges in Argus’ static only                          For the set of Exec APIs, Argus correctly detected one PHP
call-graph relate to function pointers of stream handlers in                    API that reaches the exec VIFs. However, the user-input does
the PHP interpeter. These results emphasize the benefit of                      not influence the executed command (i.e., a false positive). This
including dynamic analysis to refine the static call-graph.                     PHP API, named error_log, provides the option of sending
   While using dynamic analysis improves the result of Argus,                   the error logs through email using the mail functionality in
using only dynamic analysis to generate a call-graph has                        the PHP interpreter. The mail functionality in PHP in turn
its own drawbacks. One such drawback is the coverage of                         allows users to execute OS commands by passing an extra ar-
dynamic analysis. If the dynamic analysis does not cover all                    gument. However, user-input does not influence the arguments
possible functionality of each PHP API, it leads to missing                     passed to the mail function in the error_log API. Further-
the identification of an injection PHP API. In our evaluation of                more, compared to RIPS, Argus’ set of exec APIs does not
Argus, we quantified this aspect of dynamic analysis on PHP                     include three PHP APIs. The first API, expect_popen, is not
5.6 and 8.0. During this evaluation, Argus only used dynamic                    packaged with PHP source-code. The expect extension is
traces of running PHP high quality unit tests (i.e., 70% line                   installed through PECL package management, which is not in-
coverage) to generate the call-graph for the PHP interpreter.                   stalled by default on Debian. In addition, installing the PHP
Next, Argus performs its reachability analysis to identify the                  interpreter using Debian’s apt package tool, does not install
injection APIs. Our experiments on PHP 5.6 showed that                          PECL package management. As a result, Argus cannot detect a
using only dynamic analysis leads to missing 11 and 5 APIs,                     PHP API that is not installed and compiled with the PHP in-
which leads to insecure deserialization and XSS. A similar                      terpreter. The other two APIs are w32api_invoke_function
observation holds true for PHP 8.0, which misses 4 insecure                     and w32api_register_function, which are conditionally
deserialization and 7 XSS APIs. As a result, Argus uses a                       compiled and solely available in the PHP interpreter for the
hybrid static-dynamic call-graph generation, since there are                    Windows OS. Since our evaluation environment relied on the
drawbacks in both static and dynamic call-graph generations                     Linux OS, these two APIs were not included in the compiled
as shown in the aforementioned analyses.                                        version of the PHP interpreter. While Argus did not detect any
                                                                                exec APIs beyond RIPS, Argus identified two exec APIs that
                                                                                are not listed in Psalm; mail and mb_send_mail.
4.2.3      Validated APIs
The second set of sub-columns labeled Validated in Table 2                      4.2.4   Reasons for Differences
shows the number of APIs that Argus successfully validated
to directly pass their input argument to VIF. That is, if an                    Comparing the results for PHP 5.6 with those from 7.2 reveals
adversary can control input to any of these APIs, the existence                 three additional deserialization APIs (all of which Argus
of an injection vulnerability (i.e., insecure deserialization                   validated). The reason for this increase is the addition of
or XSS) is a certainty. Validated APIs are a strict subset                      support for the BMP image format in PHP 7.2’s GD standard
of reachable APIs. The table shows that Argus was able                          graphics library. Specifically, the new createimagefrombmp
to consistently validate around 66%, 43%, and 83% of the                        and imagebmp functions serve as implicit (i.e., undocumented)
deserialization, output, and exec APIs, respectively. A closer                  deserialization APIs. The last implicit deserialization API
look at the reachable APIs that failed the validation test                      missing from PHP 5.6 is the ftp_append API which is sup-
shows that either the user is not in control of the input to                    ported in PHP versions 7.2 and above. All deserialization APIs



6768       33rd USENIX Security Symposium                                                                                  USENIX Association
                                                                             Prevalence of Validated APIs
                                         1000000                                                                                                                                                                                    For our dataset of 1,977 applications, 1,355 (i.e., 69%) and
 The number of invocations (log-scale)




                                          100000                                                                                                                                                                                    1,218 (i.e., 62%) of applications invoke at least one newly
                                           10000                                                                                                                                                                                    identified deserialization and output APIs, respectively.
                                            1000                                                                                                                                                                                       Finally, we looked into the pre-condition required for an
                                             100                                                                                                                                                                                    attacker to exploit each of the newly detected vulnerable APIs.
                                             10                                                                                                                                                                                     The first pre-condition is that the attacker needs to upload a
                                              1                                                                                                                                                                                     malicious file to the server hosting the vulnerable application
                                                                             Hash




                                                                                                       Session
                                                                                                                  Communication
                                                                                                                                  Deserialization




                                                                                                                                                                                                                   Process
                                                   Phar


                                                                DOM
                                                                      File


                                                                                    Database
                                                                                               Image




                                                                                                                                                    Database
                                                                                                                                                               File
                                                                                                                                                                      OOP
                                                                                                                                                                            Closure
                                                                                                                                                                                      Iterator
                                                                                                                                                                                                 Error
                                                                                                                                                                                                         General


                                                                                                                                                                                                                             Mail
                                                          SPL




                                                                                                                                                                                                                                    prior to passing malicious arguments to the vulnerable APIs.
                                                                                                                                                                                                                                    The second pre-condition is that there should not be a static
                                                                                                                                                                                                                                    prefix for file operation APIs, so that an attacker can specify
                                                                  Deserialization APIs                                                                                Output APIs                                    Exec           PHAR as the stream wrapper. In the case of deserialization
                                                                                                                                                                                                                     APIs
                                                   Web Apps            Drupal Plugins                            Typo3 Plugins                                        WordPress Plugins                                             APIs, there are 273 APIs (i.e., 96%) that require a file upload
                                                                                                                                                                                                                                    and lack of static prefix pre-conditions prior to exploitation.
Figure 2: The prevalence of validated APIs in real-world                                                                                                                                                                            Furthermore, five APIs (i.e., 23%) from the set of output APIs
applications.                                                                                                                                                                                                                       require the pre-condition of file upload prior to XSS exploita-
                                                                                                                                                                                                                                    tion. The APIs that have pre-conditions are indicated in Table 5
available in version 5.6 also exist in version 7.2. In contrast                                                                                                                                                                     in the Appendix. In our evaluation, we enumerated the number
to the small change of deserialization APIs between versions                                                                                                                                                                        of newly identified sinks that PHP applications in our dataset
5.6 and 7.2, the drop from 284 to merely 13 deserialization                                                                                                                                                                         invoke. In the case of deserialization APIs, the most common
APIs in version 8.0 is significant. As discussed in Section 2.4,                                                                                                                                                                    used API in our dataset was the function copy which requires
prior to version 8.0, any file operation on a phar archive                                                                                                                                                                          the pre-conditions mentioned above. However, the most
results in the implicit deserialization of the archive’s metadata.                                                                                                                                                                  common output API used in our dataset was class_alias
Fortunately, the PHP developers recognized the negative                                                                                                                                                                             API, which does not require any pre-conditions. In case of
security consequences this behavior entails in 2020 and voted                                                                                                                                                                       exec APIs, we did not perform any qualitative analysis, since
unanimously to change the default behavior of the phar stream                                                                                                                                                                       Argus did not detect any new APIs compared to RIPS.
wrapper [11]. Thus, since PHP 8.0 metadata in phar archives
is only deserialized upon an explicit call to the getMetadata
                                                                                                                                                                                                                                    4.3     Extending Prior Security Analysis Tools
function in the Phar module, and not implicitly on any file op-
eration on the archive. While this change certainly benefits the                                                                                                                                                                    Argus’ value arises from the comprehensive list of output,
security of web applications, PHP 8.x is still not widely used                                                                                                                                                                      exec, and deserialization APIs it identifies within a PHP
by PHP-powered websites (less than 5% at the time of writ-                                                                                                                                                                          interpreter. To demonstrate the security relevance of this
ing) [28]. The challenging process of migration prevents most                                                                                                                                                                       information, we extend two PHP security analysis systems
web applications from easily adopting PHP 8 (see details in                                                                                                                                                                         – Psalm and RIPS, both static data flow analysis systems,
Section 5). Therefore, most websites still rely on older versions                                                                                                                                                                   and FUGIO, a dynamic automatic exploit generation system
of the PHP interpreter that include 284 deserialization APIs.                                                                                                                                                                       targeting POI vulnerabilities.


4.2.5                                          Qualitative Analysis of Identified APIs                                                                                                                                              4.3.1   Psalm and RIPS Extension

In this experiment, we assess the prevalence of deserialization                                                                                                                                                                     Psalm and RIPS are two static analysis tools for PHP
and output APIs in our dataset of applications. It is crucial to                                                                                                                                                                    applications, providing taint analysis and code refactoring
investigate how many of the identified APIs are actively used                                                                                                                                                                       capabilities [37]. Taint analysis operates based on a set of
in PHP applications since the validated APIs are at the core                                                                                                                                                                        configuration files that specify the taint sources and sinks in
of injection vulnerabilities. For this evaluation, we grouped                                                                                                                                                                       the PHP application. For our evaluation, we downloaded the
different categories of validated APIs listed in Table 5 for                                                                                                                                                                        latest available versions of both Psalm1 and RIPS2 at the time
different sets of injection vulnerabilities. Figure 2 shows                                                                                                                                                                         of writing from their GitHub repositories.
the number of invocation for each API category. As shown                                                                                                                                                                               Psalm’s taint analysis identifies exactly one PHP API func-
in Figure 2, in the case of deserialization APIs, we observe                                                                                                                                                                        tion as a taint sink for insecure deserialization: unserialize.
more usage for categories such as file operations and image                                                                                                                                                                         Furthermore, Psalm includes six functions as taint sinks
processing APIs. Similarly, in the case of output APIs, the                                                                                                                                                                         for XSS vulnerabilities. Argus identified and confirmed
applications in our dataset often use more error handling APIs                                                                                                                                                                      283 and 16 additional sinks that are missing in Psalm
as well as general output APIs such as echo compared to                                                                                                                                                                             related to deserialization and XSS, respectively. To improve
categories such as Database, Closure, and Iterator APIs.                                                                                                                                                                            Psalm’s taint analysis, we extended the set of taint sinks for
   Furthermore, we enumerate the set of distinct applications                                                                                                                                                                          1 Psalm 4.x-dev@832fc35d8da6e5bb60f059ebf5cb681b4ec2dba5

that invoke at least one of the newly identified vulnerable APIs.                                                                                                                                                                      2 master@ccdd2a56dbc0077cbffd08d4aa9b14af0809831d




USENIX Association                                                                                                                                                                                                                                     33rd USENIX Security Symposium             6769
                                                Deserialization                    XSS                      Command Inj.
         Repo. Group          # of Apps
                                           P    P+A      R     R+A      P     P+A      R      R+A      P     P+A R R+A
         Web Apps             60           35   354     58      511   3687    3693    538      544     25     32  14     14
         Drupal plugins       521           0     0     40       47     1       1       8       8       0      0   0      0
         Typo3 plugins        400           0    13     22       80     43      43     35      35       0      0   0      0
         WordPress plugins    996          28   289 253 1386          1658    1667 3707       3747      4      4   4      4
         Total                1977         63   656 373 825           5,389   5,404 4,288     4,334    29     36  18     18

Table 3: Extending static analysis tools such as Psalm (Labeled as P) and RIPS (Labeled as R) using Argus’ results (Labeled
as A) improved their detection rate.

both XSS and insecure deserialization to include the APIs             which refers to the required privilege in order to exploit
Argus identified for PHP 7.2. Subsequently, we performed              the POI vulnerabilities. In the case of an unauthenticated
a comparative evaluation between upstream Psalm, and our              deserialization vulnerability, the attacker can reach and
modified version incorporating the APIs identified by Argus           exploit the vulnerable functionality in the application without
on the set of 1,977 PHP artifacts described in Section 4.1.           providing any administrator credentials for the vulnerable
   Our findings in Table 3 show a significant increase (i.e., over    application. The last vulnerability type is CSRF to Phar
10X) in the number of detected insecure deserialization vulner-       deserialization, where a malicious actor tricks an administrator
abilities by the extended version of Psalm. To compare the qual-      of a WordPress app into performing an action such as clicking
ity of the results produced by upstream Psalm and our extended        on a link leading to Phar deserialization.
version, we manually analyzed all 656 insecure deserialization            In addition, we confirmed that the extended Psalm detected
reports. As Psalm is a static analysis, we expect the results to      one previously unknown XSS vulnerability in the core of the
contain false positives. Furthermore, as the extended version         WordPress web application. As we will show in Section 4.3.2,
features 284 times as many deserialization sinks, it is unsurpris-    FUGIO generated POC exploits for all 12 POI reports
ing that it reports 10 times as many potential vulnerabilities.       supporting the notion that these are actual vulnerabilities. As a
However, what we did not expect is that all 63 reports (i.e.,         case study, we will describe three of the vulnerabilities that we
100%) arising from upstream Psalm are false positives. False          discovered among WordPress and its plugins and how Argus’
positives can arise from web applications that sanitize inputs        comprehensive results were necessary to detect them.
or, more prevalent in our POI vulnerability analysis, arise from          In the case of exec APIs, we only extended the list of exec
the fact that the application sets a fixed prefix for file-paths. A   sinks for Psalm static analysis, as Argus only detected more
“fixed” file-path-prefix, even if it is derived from an API such      exec APIs compared to Psalm. According to Table 3, we ob-
as dirname essentially thwarts any attack that relies on the          served that Psalm detected more potential command injec-
phar module, as the attacker will no longer be able to specify        tions compared to RIPS. In addition, Psalm+Argus detected
the phar:// prefix that triggers the stream wrapper. In order         seven more command injections compared to the unmodified
to analyze Psalm’s results, we investigated the reason behind         Psalm. Our investigation of the newly identified vulnerabilities
the false positives in Psalm’s taint analysis. To achieve this,       showed that the cause of the vulnerabilities was passing user-
we randomly chose 50 reported deserialization vulnerabilities         input to the PHP function mail, which was not detected by the
by Psalm, analyzed the report, and reviewed the source-code           unmodified Psalm. Furthermore, since the applications were
of the application. Our investigation shows 49 cases of false         using OOP, RIPS was unable to detect the tainted data-flow and
positives, where 31 false positives were reported due to over-        did not detect the potential command injection vulnerabilities.
approximation in Psalm’s taint analysis as well as not detecting      However, our analysis shows that the newly identified vulner-
the sanitization process. Furthermore, 18 false positives were        abilities were false positive as the applications were passing
reported due to the fact that the pre-condition was not met. In       user-input to the mail function after sufficient sanitization.
all these cases, tainted variables had a hard-coded prefix passed         Case Study - Feed Them Social
to vulnerable APIs, meaning that an attacker cannot trigger               The detected vulnerability in Feed Them Social is an
the phar module by specifying the phar:// prefix. Psalm’s             unauthenticated insecure deserialization which resides in the
variable-level taint analysis only taints entire variables and        functionality of the module’s Twitter feed. The Twitter feed in
hence cannot differentiate variables with a hard-coded prefix.        this plugin retrieves and shows the content of tweets including
Finally, one reported case was a true positive.                       any referenced media on a WordPress page. Whenever a tweet
   We confirmed that our extension to Psalm’s taint analysis          contains a URL, the plugin attempts to retrieve the URL’s
detected 12 previously unknown POI vulnerabilities (i.e., 2%          title, image, and description to display on the WordPress
true positives) in our dataset (see Table 4). We categorized          page. To do this, the plugin uses the function get_meta_tags
the POI vulnerabilities into three groups: (i) unauthenticated,       with unsanitized user-input directly from the tweet to retrieve
(ii) authenticated, and (iii) CSRF to Phar. The first two types       the metadata of the specified URL. Listing 2 shows the
are authenticated and unauthenticated Phar deserialization,           simplified version of this vulnerability in this plugin, where the



6770    33rd USENIX Security Symposium                                                                           USENIX Association
unsanitized user-input is passed to the implicit deserialization        One should note that FUGIO states that it is not a vulnera-
API get_meta_tags on line 4.                                         bility detection tool. Rather its core contribution is to generate
   In order to exploit this vulnerability, an attacker sets the      exploits for already known deserialization vulnerabilities [27],
fts_url request parameter to the path of a phar file with            such as those identified by Psalm. As a result, we evaluated
malicious metadata. When the plugin tries to read and parse the      FUGIO on the 12 vulnerabilities that our extended version of
metadata of the passed URL, it will automatically deserialize        Psalm detected. To extend FUGIO, we modified its source code
the metadata of the malicious phar file. get_meta_tags is an         to hook the comprehensive set of deserialization API functions
implicit deserialization API identified by Argus and not taken       identified by Argus. The last two columns in Table 4 show
into consideration by prior work demonstrating the necessity         the results of extending FUGIO using Argus when generating
of Argus’ comprehensive analysis.                                    exploits for the discovered vulnerabilities by Psalm+Argus.
                                                                        As a dynamic analysis system, FUGIO requires a runtime
1   function fts_twitter_share_url_check () {
                                                                     environment. To this end, we created an experimental
2    $ twitter_url =$ _REQUEST ['fts_url'];
3    // ...                                                          environment for WordPress plugins consisting of Nginx, PHP
4    $ tags = get_meta_tags ($ twitter_url ) ;}                      7.2, MySQL 8, and WordPress 5.4. FUGIO creates attacks by
    Listing 2: The feed them social plugin passes unsanitized        stitching together so-called gadgets into a POP-chain. How-
    user-input to the function get_meta_tags.                        ever, WordPress alone does not contain any gadgets that could
                                                                     be used for remote code execution attacks. In practice, admin-
   According to the history of the RIPS git repository, the latest
                                                                     istrators customize their WordPress installations using plugins
modification to its static analysis was nine years ago [7]. A
                                                                     and themes. Thus to ensure that FUGIO has gadgets to work
concern that is also raised by the authors of RIPS is that it does
                                                                     with, we installed the latest versions of the top ten most popular
not support new features added to the PHP interpreter, such
                                                                     plugins in WordPress in our experimental environment [39].
as object-oriented programming (i.e., OOP). Despite its age,
                                                                     During our experiment, FUGIO without Argus’ results does
Table 3 shows that the extension of RIPS (i.e., RIPS+Argus)
                                                                     not hook into the image functions listed in Table 5. As a
leads to identifying more potential vulnerabilities. Further
                                                                     result, FUGIO was unable to generate an exploit for two of the
investigation into RIPS’ analysis shows that it raises warnings
                                                                     discovered vulnerabilities in Table 4. However, the extended
related to the use of OOP in 1,760 applications (i.e., 89% of
                                                                     FUGIO+Argus successfully generated exploits for all the dis-
our dataset), which leads to false negatives. The reason behind
                                                                     covered vulnerabilities listed in Table 4. On this small sample,
false negatives is that RIPS [7] is not able to track tainted data
                                                                     this indicates the comprehensive set of sinks provided by Argus
(i.e., data from $_GET and $_POST parameters) to and from
                                                                     leads to a 20% increase in the number of generated exploits.
objects instantiated from classes in the PHP applications. In
addition, due to the complex and large codebase for some             Web App     Plugin                  Vuln. Type       CVE              Function        P   P+A   R   R+A   F    F+A
                                                                     Xoops       -                           1              -         imagecreatefrombmp   7    X    7    7    7     X
applications in our dataset, RIPS was not able to complete                       Feed them Social            1        CVE-2022-2437      get_meta_tags     7    X    7    X    7     X
                                                                                 ImageMagick                 2        CVE-2022-2441      is_executable     7    X    7    X    X     X
the analysis for 135 applications (i.e., 7% of the dataset).                     String locator
                                                                                 Ajax load more
                                                                                                             2
                                                                                                             2
                                                                                                                      CVE-2022-2434
                                                                                                                      CVE-2022-2433
                                                                                                                                           file_exists
                                                                                                                                           file_exists
                                                                                                                                                           7
                                                                                                                                                           7
                                                                                                                                                                X
                                                                                                                                                                X
                                                                                                                                                                     7
                                                                                                                                                                     7
                                                                                                                                                                          X
                                                                                                                                                                          X
                                                                                                                                                                               X
                                                                                                                                                                               X
                                                                                                                                                                                     X
                                                                                                                                                                                     X
As explained, we identified several drawbacks to the RIPS            WordPress
                                                                                 Broken link checker
                                                                                 wp editor
                                                                                                             3
                                                                                                             3
                                                                                                                      CVE-2022-2438
                                                                                                                      CVE-2022-2446
                                                                                                                                           file_exists
                                                                                                                                              is_dir
                                                                                                                                                           7
                                                                                                                                                           7
                                                                                                                                                                X
                                                                                                                                                                X
                                                                                                                                                                     7
                                                                                                                                                                     7
                                                                                                                                                                          X
                                                                                                                                                                          7
                                                                                                                                                                               X
                                                                                                                                                                               X
                                                                                                                                                                                     X
                                                                                                                                                                                     X

analysis that have implications for its vulnerability detection.                 Visualizer
                                                                                 Easy digital download
                                                                                                             3
                                                                                                             3
                                                                                                                      CVE-2022-2444
                                                                                                                      CVE-2022-2439
                                                                                                                                              fopen
                                                                                                                                           file_exists
                                                                                                                                                           7
                                                                                                                                                           7
                                                                                                                                                                X
                                                                                                                                                                X
                                                                                                                                                                     7
                                                                                                                                                                     7
                                                                                                                                                                          7
                                                                                                                                                                          X
                                                                                                                                                                               X
                                                                                                                                                                               X
                                                                                                                                                                                     X
                                                                                                                                                                                     X
                                                                                 Theme Editor                3        CVE-2022-2440           unlink       7    X    7    X    X     X
In order to demonstrate these implications, we analyzed the                      wPvivid Backup              3        CVE-2022-2442        file_exists     7    X    7    X    X     X
                                                                                 Download manager            3        CVE-2022-2436        file_exists     7    X    7    7    X     X
results of RIPS+Argus to identify whether it was able to                         -                          XSS             -                readfile      7    X    7    7     -     -
                                                                     Total       -                           -              -                              0    13   0    8    10    12
identify the vulnerabilities discovered by Psalm+Argus. Our
analysis shows that RIPS+Argus only identified eight out of          Table 4: We verified the reports of Psalm+Argus by discov-
the 13 vulnerabilities (i.e., 60%) listed in Table 4.                ering 13 previously unkown POI and XSS vulnerabilities.
                                                                     The vulnerability types 1, 2, and 3 refers to Unauthenticated
4.3.2   FUGIO Extension                                              Phar deserialization, CSRF to Phar deserialization, and
                                                                     Authenticated Phar deserialization, respectively.
FUGIO [27] is an automatic exploit generator for previously
identified deserialization vulnerabilities in PHP applications.         Disclosure. We responsibly reported all the vulnerabilities
FUGIO’s exploit generation hooks a set of predefined deserial-       to their corresponding developer teams and notified the Word-
ization functions while sending serialized objects as request to     Press plugin review team of our findings. Seven teams already
the web application under test. Our analysis of FUGIO shows          patched their WordPress plugins, and WordFence assigned
that FUGIO hooks into 26 file operation functions in the PHP         CVE numbers to the vulnerabilities as shown in Table 4.
interpreter as well as the unserialize function to intercept            Artifact Availability: Argus is open-source and available
deserialization of user-input. Similar to Psalm, FUGIO               at https://github.com/BUseclab/Argus. We provide
obtained the list of hooked functions through manual analysis        the source-code of our tool along with the instructions for
of PHP documentation and prior works such as Thomas [36].            reproducing the experiments. These artifacts were major
For our evaluation, we downloaded FUGIO from its GitHub              components of our evaluation and we believe that they can
repository at https://www.github.com/WSP-LAB/FUGIO.                  be useful for future research in this space.



USENIX Association                                                                                       33rd USENIX Security Symposium                                        6771
5   Discussion                                                       HTML response). In the case of XSS and insecure deserializa-
                                                                     tion, there is one VIF for Argus to start the reachability analysis
In this section, we discuss the limitations, challenges, and         from. However, other types of injection vulnerabilities, might
observations of Argus.                                               require the identification of multiple VIFs. In the case of
   Completeness: Argus does not guarantee completeness in            command injection, there are eight VIFs which we could
its analysis of the PHP interpreter as well as the identified set    directly obtain from Saphire. Similarly, supporting SQL
of deserialization, exec, and output APIs. Argus relies on the       injection would require the identification of multiple VIFs.
call-graph of the PHP interpreter for its analysis, which uses a     The reason is that the PHP interpreter supports a variety of
hybrid static-dynamic analysis. As mentioned in Sections 2.4         database engines (e.g., SQLite, MySQL, Oracle, etc.) through
and 3.1.2, the PHP interpreter extensively uses indirect calls,      individual extensions which can communicate SQL statements
such as function pointers, which challenges any static analysis,     to the respective back-end. Owing to this diversity, the SQL
including Argus. In order to minimize the drawbacks of               injection VIFs are located in different database extensions and
indirect calls in the generated call-graph by Argus, we use the      require individual identification. However, once a VIF for a
official unit tests of the PHP interpreter for its dynamic analy-    given database extension is identified, Argus can immediately
sis, features a 70% line coverage over the PHP interpreter. As a     identify the set of (SQL injection) vulnerable API functions
result, Argus uses a hybrid static-dynamic approach to reduce        for the corresponding database engine.
the drawbacks of each technique. However, Argus cannot                  The efforts and time required by analysts to identify the set
guarantee the completeness of its analysis due to the challenges     of VIFs for each vulnerability vary, depending on the type of
of analyzing a complex codebase such as the PHP interpreter.         vulnerability. This process starts by identifying the cause of the
   Reachability: Argus relies on a reachability analysis on          vulnerability using analysis tools (e.g., command injection and
the call-graph to identify the serialization, exec, and output       XSS) or manual inspection of the code. The manual inspection
APIs in the PHP interpreter. The reachability analysis does not      contains reasoning about the cause of the vulnerability (e.g., the
reason about any sanitization or filtering the PHP interpreter       serialization format) and detecting the parser function inside
might perform. Hence, the reachability of an API to VIF does         the PHP interpreter that uses the serialization format. In the
not necessarily imply that an attacker can exploit the API.          case of XSS, we use analysis tools to understand how the PHP
However, we perform a validation step to verify the output of        interpreter prints user-input to the output buffer. To this end, we
the reachability analysis. While it seems more pertinent to per-     inspected the sequence of function calls in the PHP interpreter
form a data-flow analysis than a reachability analysis, we argue     that involve printing to the output buffer. On average, it took
that Argus needs to reason about the PHP interpreter and its ex-     less than 10 hours to analyze the PHP interpreter to identify the
tensions that it is linked against. Ignoring additional challenges   process of deserializing and printing user-input. For command
to practicality (e.g., extensions relying on non-C code), our        injection vulnerabilities, any API that can invoke the execve
analysis needs to scale to millions of lines of code across PHP      system call is a potential exec API. Considering that, Argus
(one million lines of C code alone). Needless to say, resolving      uses prior research, Saphire [3] to analyze and enumerate the
function pointers is still a prominent challenge for existing        set of VIFs that invoke execve system call. For this analysis,
data-flow analysis, including the state-of-the-art SVF tool [33],    we spent less than four hours preparing Saphire’s environment
which leads to imprecise control-flow graphs. As a result, we        and running its analysis, as well as inspecting the source code
opted for a reachability analysis and subsequent validation          of PHP to identify the mechanism of command injection.
in Argus to identify injection-sinks in the PHP interpreter.            Precondition: Furthermore, our evaluation identified two
   Validation: During the validation step, Argus determines          sets of injection-sink APIs for PHP: 1) APIs that operates
whether user-input gets passed to the VIF function in-               directly on the value of their arguments and 2) APIs that oper-
side the PHP interpeter (i.e., php_var_unserialize and               ate on malicious files. As mentioned in Section 2.4, the phar
php_output_write) unmodified. The presence of sanitiza-              stream wrapper in the PHP interpreter only operates on local
tion logic for a specific API does not necessarily mean the API      phar files. As a result, to exploit any APIs in the latter category,
cannot be exploited by attackers. Saner [2] demonstrates that        the attacker needs to upload the phar file prior to invoking the
sanitization logic might be implemented incorrectly. In this         insecure deserialization. Therefore, in order to confirm the
paper, Argus only reports the set of APIs that pass arguments        detected vulnerabilities, we made the assumption that the at-
unmodified to a VIF, which means that Argus’ results are a           tacker had already uploaded the malicious phar file to the web
lower bound of vulnerable APIs. Analyzing the correctness of         application’s server. We argue that this assumption is realistic
sanitization logic is an orthogonal research challenge, which        since there are a plethora of approaches where an attacker can
we consider outside the scope of this paper.                         upload malicious phar files, which include exploiting arbitrary
   VIF identification: The foundation of Argus’ analysis is          file upload vulnerabilities [16, 17]. Furthermore, web applica-
based on our key observation that an underlying function is          tions and their plugins provide upload functionality for many
responsible for performing the action of either deserializing        purposes, such as uploading plugins, profile pictures, and PDF
user-input or writing user-input to output buffers (i.e., the        files, which an attacker can exploit.



6772    33rd USENIX Security Symposium                                                                           USENIX Association
   Finally, as our evaluation demonstrates, the PHP developers        whereas SerialDetector finds new object injection patterns
noticed the security consequences of automatic deserialization        at the library level (i.e., as part of the web application rather
of phar files and fixed this issue in PHP 8.0 (released in            than the application framework). Tanaka presents attacking
November 2020). However, the PHP usage statistics indicate            patterns in Python’s Pickle library, which lead to denial of
that, at the time of writing, only 10.75% of all websites that        service (DoS) attack [34]. Look-ahead object input stream
rely on PHP actually operate on PHP 8.0 [28]. The reason for          (LAOIS) is a defense mechanism against Java deserialization
this low adoption rate is probably that transitioning to PHP          vulnerabilities, allowing the type check of the serialized
8.0 is a non-trivial procedure for most PHP-powered websites.         stream before deserialization, as implemented in Apache’s
The major changes in the PHP interpreter 8.0 compared to              Common IO library [5] and Java Serialization Filtering [26].
previous versions lead to backward incompatiblilities [13]               Other Vulnerabilities: There are multiple studies on de-
which can potentially cause fatal errors in the web applications.     tecting vulnerabilities in PHP applications. Several approaches
The challenge of (in-)compatibility is evidenced by the most          rely on taint analysis to track unsanitized data and detect injec-
popular PHP application – WordPress. Although efforts                 tion vulnerabilities [1, 7, 8, 21, 32, 38, 42]. Dynamic analysis
within the WordPress project to support PHP version 8.0               and hybrid techniques also play an important role in detection
began on December 2020, WordPress still warns users that              and defense systems [3, 14, 15, 18, 25, 29, 31]. Prior works
even its latest stable version (released in May 2023) is not          exclusively analyze the web application code and many rely
fully compatible with version 8 yet [40]. While the PHP               on hand-crafted list of sinks. Argus analyzes the underlying
interpreter has addressed the threat arising from the automatic       PHP interpreter and generates these lists in a principal manner
deserialization of phar files in version 8, history suggests          which could improve existing systems, as demonstrated in
that web sites relying on older versions of PHP are likely to         our evaluation. Compared to defense mechanisms, Argus
remain publicly accessible on the Internet for the foreseeable        takes a more proactive approach in order to detect injection
future. These will continue to include the over 280 vulnerable        vulnerabilities rather than defend against such POI attacks.
deserialization APIs provided by their PHP runtimes.

6    Related Work                                                     7    Conclusion

In this section, we review the related literature on detecting se-    In this paper, we proposed Argus, an automated static-dynamic
curity vulnerabilities or defending against malicious behavior.       analysis approach to identify the set of PHP API functions that
   Deserialization in PHP Application: In light of new attack         deserialize, execute, or output their arguments in a PHP appli-
scenarios introduced by Esser, new research has emerged on            cation. Argus statically analyzes the PHP interpreter and its
detecting deserialization vulnerabilities and detecting such          modules to generate a call-graph. Next, we refine the statically
attacks on PHP applications. RIPS [7] performs an intra-              generated call-graph by using the recorded dynamic trace of the
procedural data flow analysis to detect injection vulnerabilities,    publicly available unit test of the PHP interpreter. Argus then it-
including POI. Dahse [9] proposed an automatic approach to            erates over the call-graph and identifies a comprehensive set of
identify gadget chains to exploit POI vulnerabilities. Further-       PHP APIs that can invoke the internal deserialization, execute
more, FUGIO [27] introduced an automatic exploit generation           OS command, or output functions. In our experiments on three
tool to create exploit objects for POI vulnerabilities. In an or-     of the most popular versions of the PHP interpreter, we discov-
thogonal and complementary direction, our work detects the            ered more than 300 functions that can deserialize user-input,
set of PHP API functions that lead to insecure deserialization,       execute OS command, or write user-input to an output buffer,
command injection, or XSS. Crucially, prior works rely on an          expanding prior knowledge by an order of magnitude. We draw
exclusively manually curated list of sinks for taint analysis or      attention toward the fact that prior works rely on a purely ad-
exploit generation tools. Unlike prior work, Argus performs an        hoc curated list of functions for their static or dynamic analysis,
automatic analysis to identify the set of PHP API functions that      whereas Argus automatically generates a comprehensive list.
lead to injection vulnerabilities such as insecure deserialization.   In addition, we demonstrate that Argus’ findings are highly
In our evaluation, we showed how our results directly improved        security relevant. Our findings show that, extending Psalm by
prior work in detecting previously unknown vulnerabilities.           Argus’ results, we detected 13 previously unknown XSS and
   Deserialization on Other Platforms: Deserialization                deserialization vulnerabilities in PHP applications.
vulnerabilities threaten various platforms such as Java, Python,
and .NET. The research in this area focuses on detecting
such vulnerabilities or defending against deserialization             Acknowledgements
attacks. SerialDetector [30] leverages call-graph analysis
to identify injection vulnerabilities in .NET libraries. The          We thank our anonymous shepherd and the reviewers for their
key difference between SerialDetector and Argus is that               helpful feedback. This work was supported by the National
we aim to detect functions at the PHP interpreter level,              Science Foundation (NSF) under grant CNS-2211576.



USENIX Association                                                                       33rd USENIX Security Symposium           6773
References                                                       [15] Byron Hawkins and Brian Demsky. Zenids: Intro-
                                                                      spective intrusion detection for php applications. In
 [1] Michael Backes, Konrad Rieck, Malte Skoruppa, Ben                Proceedings of the 39th International Conference on
     Stock, and Fabian Yamaguchi. Efficient and flexible              Software Engineering, 2017.
     discovery of php application vulnerabilities. In IEEE
     European symposium on Security and Privacy, 2017.           [16] Jin Huang, Yu Li, Junjie Zhang, and Rui Dai. Uchecker:
                                                                      Automatically detecting php-based unrestricted file
 [2] Davide Balzarotti, Marco Cova, Vika Felmetsger, Nenad            upload vulnerabilities. In 49th Annual IEEE/IFIP
     Jovanovic, Engin Kirda, Christopher Kruegel, and                 International Conference on Dependable Systems and
     Giovanni Vigna. Saner: Composing static and dynamic              Networks, 2019.
     analysis to validate sanitization in web applications. In
     IEEE Symposium on Security and Privacy, 2008.               [17] Jin Huang, Junjie Zhang, Jialun Liu, Chuang Li, and
                                                                      Rui Dai. Ufuzzer: Lightweight detection of php-based
 [3] Alexander Bulekov, Rasoul Jahanshahi, and Manuel                 unrestricted file upload vulnerabilities via static-fuzzing
     Egele. Saphire: Sandboxing PHP applications with                 co-analysis. In 24th International Symposium on
     tailored system call allowlists. In Proceedings of the           Research in Attacks, Intrusions and Defenses, 2021.
     30th USENIX Security Symposium, 2021.
                                                                 [18] Rasoul Jahanshahi, Adam Doupé, and Manuel Egele.
 [4] G. Cleary, M. Corpin, O. Cox, H. Lau, B. Nahorney,
                                                                      You shall not pass: Mitigating sql injection attacks on
     D. O’Brien, B. O’Gorman, J. Power, S. Wallace, P. Wood,
                                                                      legacy web applications. In Proceedings of the 15th ACM
     and Wueest C. Internet security threat report. Technical
                                                                      Asia Conference on Computer and Communications
     Report 23, Symantec Corporation, 2018.
                                                                      Security, 2020.
 [5] Apache Commons.    ValidatingObjectInputStream.
     https://github.com/apache/commons-oi, 2021.                 [19] Joern.  The Bug Hunter’s Workbench.                https:
                                                                      //joern.io, 2023.
 [6] copernica. A c++ library for developing PHP extension.
     http://www.php-cpp.com/documentation/, 2022.                [20] Stephen C Johnson et al. Yacc: Yet another compiler-
                                                                      compiler, volume 32. Bell Laboratories Murray Hill, NJ,
 [7] Johannes Dahse and Thorsten Holz. Simulation of built-           1975.
     in php features for precise static code analysis. In Net-
     work and Distributed Systems Security Symposium, 2014.      [21] Nenad Jovanovic, Christopher Kruegel, and Engin Kirda.
                                                                      Pixy: A static analysis tool for detecting web application
 [8] Johannes Dahse and Thorsten Holz. Static detection of            vulnerabilities. In IEEE Symposium on Security and
     second-order vulnerabilities in web applications. In Pro-        Privacy, 2006.
     ceedings of the 23rd USENIX Security Symposium, 2014.
                                                                 [22] Michael Kerrisk. The Linux Programming Interface.
 [9] Johannes Dahse, Nikolai Krein, and Thorsten Holz.                https://www.man7.org/linux/man-pages/man3/
     Code reuse attacks in php: Automated pop chain                   exec.3.html, 2022.
     generation. In Proceedings of the 21st ACM Conference
     on Computer and Communications Security, 2014.              [23] Namhyung Kim. Function graph tracer for c/c++/rust.
                                                                      https://github.com/namhyung/uftrace, 2022.
[10] edgescan Corporation. 2022 vulnerability statistics
     report. Technical Report 7, edgescan Corporation, 2022.     [24] Nikolaos Koutroumpouchos, Georgios Lavdanis, Eleni
[11] The PHP Group. PHP:rfc phar stop autoloading                     Veroni, Christoforos Ntantogian, and Christos Xenakis.
     metadata. https://wiki.php.net/rfc/phar_stop_                    Objectmap: Detecting insecure object deserialization.
     autoloading_metadata, 2020.                                      In Proceedings of the 23rd Pan-Hellenic Conference on
                                                                      Informatics, 2019.
[12] The PHP Group.    PHP: PHP Manual.     https:
     //www.php.net/manual/en/index.php, 2022.                    [25] Anh Nguyen-Tuong, Salvatore Guarnieri, Doug Greene,
                                                                      Jeff Shirley, and David Evans. Automatically Hardening
[13] The PHP Group. PHP:The Backward Incompatible                     Web Applications Using Precise Tainting. In Security
     Changes.     https://www.php.net/manual/en/                      and Privacy in the Age of Ubiquitous Computing, 2005.
     migration80.incompatible.php, 2022.
                                                                 [26] OpenJDK. Jep 290: Filter incoming serialization data.
[14] W. Halfond, A. Orso, and P. Manolios. Wasp: Protecting           https://openjdk.org/jeps/290, 2021.
     web applications using positive tainting and syntax-
     aware evaluation. IEEE Transactions on Software             [27] Sunnyeo Park, Daejun Kim, Suman Jana, and Sooel Son.
     Engineering, 2008.                                               FUGIO: Automatic exploit generation for PHP object



6774   33rd USENIX Security Symposium                                                                      USENIX Association
     injection vulnerabilities. In Proceedings of the 31st                php-compatibility-and-wordpress-versions/,
     USENIX Security Symposium, 2022.                                     2022.
[28] Q-Success. Usage Statistics and Market Share of PHP for       [41] Zephir.   Building php extensions with zephir.
     Websites. https://w3techs.com/technologies/                        https://docs.zephir-lang.com/, 2022.
     details/pl-php, 2022.
                                                                   [42] Y. Zheng and X. Zhang. Path sensitive static analysis of
[29] Prateek Saxena, David Molnar, and Benjamin Livshits.               web applications for remote code execution vulnerability
     Scriptgard: Automatic context-sensitive sanitization               detection. In 35th International Conference on Software
     for large-scale legacy web applications. In Proceed-               Engineering, 2013.
     ings of the 18th ACM Conference on Computer and
     Communications Security, 2011.
[30] Mikhail Shcherbakov and Musard Balliu. Serialdetector:        A      PHP Object Injection
     Principled and practical exploration of object injection
     vulnerabilities for the web. In Network and Distributed        1   // PART ONE: modify properties
     Systems Security Symposium, 2021.                              2   class Exec {
                                                                    3       private $ _cmd = " cat secret "; }
                                                                    4   class Example {
[31] Sooel Son, Kathryn S. McKinley, and Vitaly Shmatikov.
                                                                    5       protected $ obj ;
     Diglossia: detecting code injection attacks with precision     6       function __construct () {
     and efficiency. In Proceedings of the 20th ACM Confer-         7           $ this -> obj = new Exec ; } }
     ence on Computer and Communications Security, 2013.            8   print urlencode ( serialized ( new Example ));
                                                                    9   // PART TWO: create Phar file
[32] Sooel Son and Vitaly Shmatikov. Saferphp: Finding             10   $ phar = new Phar ('exploit . phar');
                                                                   11   $ phar -> startBuffering () ;
     semantic vulnerabilities in php applications.     In          12   $ phar -> setMetadata ( new Example () );
     Proceedings of the ACM SIGPLAN 6th Workshop on                13   $ phar -> stopBuffering () ;
     Programming Languages and Analysis for ecurity, 2011.              Listing 3: Adversary can exploit file operations by
[33] Yulei Sui and Jingling Xue. Svf: interprocedural static            generating a malicious phar file.
     value-flow analysis in llvm. In Proceedings of the 25th
     international conference on compiler construction, 2016.
                                                                   B      Validation Process
[34] Kousei Tanaka and Taiichi Saito. Python deserialization
     denial of services attacks and their mitigations. In          1    $ pre_code = " code snippet of the exploit ";
     International Conference on Computational Science/In-         2    $ payloads = array
     telligence & Applied Informatics, 2018.                                  (" phar "=>" path -to - phar - file " ," direct
                                                                              "=>" serialized_data " ,...) ; // different
                                                                               pattern of input to deserialize APIs
[35] GCC team. Code Gen Options - using the GNU Compiler
                                                                   3    $ list_funcs = []
     Collection.  https://gcc.gnu.org/onlinedocs/                             // the list of functions to be validated
     gcc-4.4.7/gcc/Code-Gen-Options.html, 2022.                     4   foreach ($ list_funcs as $ func ) {
                                                                    5    // generate the phar file
[36] Sam Thomas. File Operation Induced Unserialziation via         6     if $ func {
     the phar Stream Wrapper. In 21st Blackhat - USA, 2018.         7      $ ref = new ReflectionFunction ($ func );
                                                                    8      // get the list of params using reflection
[37] Vimeo.   Psalm - a static analysis tool for PHP.               9      foeach ($ payloads as $ key => $ payload ) {
                                                                   10      $ snippet
     https://psalm.dev, 2021.                                                    = " ... "; // invoke $func with $payload
                                                                   11      file_put_content
[38] Gary Wassermann and Zhendong Su. Sound and precise                          (" tmp . php " , $ pre_code . $ snippet ) }
     analysis of web applications for injection vulnerabilities.   12      $ cmd
     In Proceedings of the 28th ACM SIGPLAN Conference                           = $ PHP_BINARY ." tmp . php 2 > / dev / null ";
                                                                   13      $ res = shell_exec ($ cmd );
     on Programming Language Design and Implementation,            14      // checking the result.
     2007.                                                         15      if ( strpos ($res , " SUCCESS ") !== false ) {
                                                                   16        echo $ func . " is vulnerable \n";
[39] WordPress. Plugins Categorized as Popular. https://           17        break } } }
     wordpress.org/plugins/browse/popular/, 2022.                       Listing 4: Psuedo-code of the validation process in Argus
[40] WordPress.        Server Environment:   Make
     WordPress   Hosting.            https://make.
     wordpress.org/core/handbook/references/



USENIX Association                                                                     33rd USENIX Security Symposium         6775
                                                                       Deserialization API
 Category           PHP API functions
 Phar†              phar::__construct phar::unlinkArchive, phar::loadPhar, phar::setAlias, phar::delete, phar::offsetSet, phar::setSignatureAlgorithm,
                    phar::isValidPharFilename, phar::buildFromIterator, phar::setDefaultStub, phar::mount, phar::getType, phar::covertToExecutable,
                    phar::offsetUnset, phar::stopBuffering, phar:getATime, phar::setStub, phar::isLink, phar::addFromString, phar::isFile, phar::addFile,
                    phar::compress, phar::extractTo, phar::hasChildren, phar::getInode, phar:getFileInfo, phar::decompressFiles, phar::mapPhar,
                    phar:isReadable, phar::addEmptyDir, phar::compressFiles, phar:getOwner, phar:getGroup, phar::offsetGet, phar::setMetadata,
                    phar:getPerms, phar::isExecutable, phar::loadPhar, phar::copy, phar::convertToData, phar::isWritable, phar:getSize, phar:getCTime,
                    phar:getMTime, phar:isDir, phar::getStub, Phar::delMetadata, PharFileInfo::__construct, PharFileInfo::chmod, PharFile-
                    Info::getContent, PharFileInfo::getType, PharFileInfo::isReadable, PharFileInfo::isDir, PharFileInfo::isWritable, PharFileInfo::openFile,
                    PharFileInfo::decompress, PharFileInfo::compress, PharFileInfo::getInode, PharFileInfo::getCTime, PharFileInfo::getMTime, PharFile-
                    Info::getSize, PharFileInfo::isExecutable, PharFileInfo::isLink, PharFileInfo::isFile, PharFileInfo::getATime, PharFileInfo::getGroup,
                    PharFileInfo::getPerms, PharFileInfo::getOwner, PharFileInfo::getFileInfo, PharFileInfo::setMetadata, PharFileInfo::delMetadata,
                    PharData::unlinkArchive, PharData::loadPhar, phar::getMetadata, PharFileInfo::getMetadata,
 SPL                FileInfo::openFile† , FileInfo::getCTime† , FileInfo::getSize† , FileInfo::getATime† , FileInfo::getFileInfo† , FileInfo::getGroup† ,
                    FileInfo::getType† , FileInfo::getPerms† , FileInfo::getOwner† , FileInfo::isWritable† , FileInfo::isDir† , FileInfo::getMTime† , File-
                    Info::isReadable† , FileInfo::getInode† , FileInfo::isExecutable† , FileInfo::isFile† , FileInfo::isLink† , SplFileObject::__construct† ,
                    SplFileObject::getType† , SplFileObject::isReadable† , SplFileObject::isDir† , SplFileObject::openFile† , SplFileObject::getInode† ,
                    SplFileObject::isWritable† , SplFileObject::getFileInfo† , SplFileObject::getCTime† , SplFileObject::getPerms† , SplFileObject::getOwner† ,
                    SplFileObject::getGroup† , SplFileObject::getATime† , SplFileObject::getGroup† , SplFileObject::isExecutable† , SplFileObject::isFile† ,
                    DirectoryIterator::__construct† , DirectoryIterator::getType† , DirectoryIterator::isReadable† , DirectoryIterator::isDir† , Directo-
                    ryIterator::openFile† , DirectoryIterator::getInode† , DirectoryIterator::isWritable† , DirectoryIterator::getFileInfo† , DirectoryItera-
                    tor::getATime† , DirectoryIterator::getCTime† , DirectoryIterator::getPerms† , DirectoryIterator::getOwner† , DirectoryIterator::getGroup† ,
                    DirectoryIterator::isLink† , DirectoryIterator::isFile† , DirectoryIterator::isExecutable† , RecursiveDirectoryIterator::__construct† , Recur-
                    siveDirectoryIterator::getType† , RecursiveDirectoryIterator::isReadable† , RecursiveDirectoryIterator::isDir† , RecursiveDirectoryItera-
                    tor::openFile† , RecursiveDirectoryIterator::getInode† , RecursiveDirectoryIterator::isWritable† , RecursiveDirectoryIterator::getFileInfo† ,
                    RecursiveDirectoryIterator::getCTime† , RecursiveDirectoryIterator::getPerms† , RecursiveDirectoryIterator::getOwner† , RecursiveDirec-
                    toryIterator::getGroup† , RecursiveDirectoryIterator::isLink† , RecursiveDirectoryIterator::current† , RecursiveDirectoryIterator::isFile† ,
                    RecursiveDirectoryIterator::isExecutable† , RecursiveDirectoryIterator::hasChildren† , FileSystemIterator::__construct† , FileSystemItera-
                    tor::getType† , FileSystemIterator::isReadable† , FileSystemIterator::isDir† , FileSystemIterator::openFile† , FileSystemIterator::getInode† ,
                    FileSystemIterator::isWritable† , FileSystemIterator::getFileInfo† , FileSystemIterator::getPerms† , FileSystemIterator::getOwner† ,
                    FileSystemIterator::getGroup† , FileSystemIterator::getATime† , FileSystemIterator::current† , FileSystemIterator::getSize† , FileSystemIt-
                    erator::isLink† , FileSystemIterator::getMTime† , FileSystemIterator::isExecutable† , FileSystemIterator::isFile† , SplQueue::unserialize,
                    SplStack::unserialize, SplDoublyLinkedList::unserialize, ArrayIterator::unserialize, RecursiveArrayIteratorunserialize, SplObject-
                    Storage::unserialize, ArrayObject::__unserialize
 DOM & XML†         DOMDocument::loadHTMLFile, DOM::C14NFile, DOMDocument::load, DOMDocument::loadXML, DOMDocument:saveHTMLFile,
                    DOMDocument:relaxNGValidate, DOMDocument:validate, DOMDocument:save, xmlwrite_open_uri, xmlreader::open, SimpleXM-
                    LElement::__construct, simplexml_load_file, simplexml_load_string
 File Operation†    get_meta_tags, is_dir, scandir, is_writable, is_file, opendir, file, move_uploaded_file, rmdir, fileowner, touch, gzfile, file_get_contents, mkdir,
                    finfo_file, fileatime, bzopen, fileperms proc_open, readgzfile, is_link, file_put_contents, finfo_buffer, gzopen, getdir, unlink, is_readable,
                    filegroup, finfo_open, filectime, filemtime, rename, fileinode, copy, filesize, mime_content_type, stat, filetype, fopen,readfile,file_exists,
                    is_executable
 Hash†              md5_file, hash_hmac_file, sha1_file, hash_file
 DataBase†          PDO::pgsqlCopyFromFile, PDO:pgsqlCopyToFile, pg_trace
 Image              imageloadfont, exifimagetype, exif_read_data, read_exif_data, exif_thumbnail, getimagesize, imagecreatefromjpeg, imagecreatefrompng,
 Processing†        imagecreatefromgd2,imagecreatefromgif, imagecreatefromwebp, imagecreatefromgd, imagecreatefromxbm, imagecreatefrombmp, image-
                    createfromwbmp, imagecreatefromavif, imagejpeg, imagepng, imagegif, imagegd, imagegd2, imageavif, imagebmp, imagewbmp,imagexbm,
                    imagewebp
 Session Function   session_decode, session_start
 Communication      ftp_nb_put† , ftp_nb_get† , ftp_get† , ftp_append† , ftp_put† , msg_recieve
 Deserialization    unserialize
                                                                            Output API
 Database           pg_loreadall, pg_lo_read_all, odbc_result_all
 File Operation†    fpassthru, readfile, readgzfile, gzpassthru, SplFileObject::fpassthru
 OOP                class_alias
 Closures           Closure::bind, Closure::bindTo
 Iterators          CachingIterator::offsetGet, RecursiveCachingIterator::offsetGet
 Error Handling     trigger_error, user_error, die, exit
 General            echo, print, print_r, vprintf
                                                                             Exec API
 Mail               mail, mb_send_mail
 Process            system, shell_exec, exec, proc_open, popen, pcntl_exec, passthru

Table 5: The categories of exec, output and deserialization API. The functions or category of functions specified by † require
the precondition of uploading a malicious file prior to exploitation. The functions specified in bold are the set of vulnerable
deserialization APIs in PHP 8.



6776    33rd USENIX Security Symposium                                                                                                      USENIX Association
