Вы находитесь на странице: 1из 16

A Sense of Time for JavaScript and Node.

js:
First-Class Timeouts as a Cure for Event Handler Poisoning

James C. Davis Eric R. Williamson Dongyoon Lee


Virginia Tech Virginia Tech Virginia Tech

Abstract tecture — from the One Thread Per Client Architecture


The software development community has begun to (OTPCA) used in Apache to the Event-Driven Architec-
adopt the Event-Driven Architecture (EDA) to pro- ture (EDA) championed by Node.js.
vide scalable web services, most prominently through The EDA is not a passing fad. Perhaps inspired by
Node.js. Though the EDA offers excellent scalability, Welsh et al.’s SEDA concept [100], server-side EDA
it comes with an inherent risk: the Event Handler Poi- frameworks like Twisted [25] have been in use since at
soning (EHP) Denial of Service attack. In essence, EHP least the early 2000s. But the boom in the EDA has come
attacks say that the scalability of the EDA is a double- with Node.js. Node.js (“server-side JavaScript”) was in-
edged sword: the EDA is scalable because clients share troduced in 2009 and is now used by many organizations
a small set of threads, but if an attacker causes these in many industries, including IBM , Microsoft, Apple,
threads to block then the server becomes unusable. EHP Cisco, Intel, RedHat, GE, Siemens, NASA, Wikipedia,
attacks are a significant threat, as hundreds of popular and the NFL ([32, 66, 81, 76, 36, 16]). The associated
Node.js-based websites were recently reported to be vul- package ecosystem, npm, boasts 575,000 modules [55].
nerable to forms of EHP attacks. It is not an exaggeration to state that Node.js is becoming
In this work we make three contributions. First, we a critical component of the modern web [18, 35].
formally define EHP attacks, and we show that EHP at- Given the importance of the EDA to the modern web,
tacks are a common form of vulnerability in the largest it has received surprisingly little study from a security
EDA community, the Node.js ecosystem. Second, we perspective [51, 78]. We present the first formal treat-
design and evaluate an EHP-safe defense: first-class ment of the weaknesses in the EDA, and describe a De-
timeouts. Although realizing first-class timeouts is dif- nial of Service attack, Event Handler Poisoning (EHP),
ficult in a complex real-world framework like Node.js, that can be used against EDA-based services like Node.js
our Node.cure prototype defends Node.js applications applications (§3).
against all known EHP attacks. Third, we have identified EHP attacks observe that the source of the EDA’s scal-
and documented or corrected vulnerable APIs in Node.js, ability is also its Achilles’ heel. Where the OTPCA gives
and our guide on avoiding EHP attacks is now available every client its own thread, the EDA multiplexes many
on nodejs.org. clients onto a small number of Event Handlers (threads)
Node.cure is effective, defeating all known EHP at- to reduce per-client overheads. Because many clients
tacks with application overheads as low as 0%. More share the same Event Handlers, an EDA-based server
generally, we show that Node.cure offers strong security must correctly implement cooperative multitasking [91].
guarantees against EHP attacks for the majority of the An incorrect implementation of cooperative multitasking
Node.js ecosystem. enables an EHP attack: an attacker dominates the time
Millions of developers have embraced the EDA, but spent by an Event Handler, preventing the server from
without strict adherence to the EDA paradigm their code handling all clients fairly. We found that although the
is vulnerable to EHP attacks. Node.cure offers the cure. EHP problem is little discussed in the Node.js documen-
tation, EHP vulnerabilities are common in npm (§4).
1 Introduction In §5 we define criteria for EHP-safety, and use these
Web services are the lifeblood of the modern Internet. To criteria to evaluate four EHP defenses (§6). Though vari-
minimize costs, service providers want to maximize the ations of three of these defenses are used today, they are
number of clients each server can handle. Over the past ad hoc and thus impractical in an ecosystem dominated
decade, this goal has led the software community to se- by third-party modules. The fourth defense, the Timeout
riously consider a paradigm shift in their software archi- Approach, requires extending existing EDA languages

1
and frameworks, but it provides a universal solution for Loop. The Event Loop may offload expensive Tasks
EHP-safety with strong security guarantees. The Time- like file I/O to the queue of a small Worker Pool, whose
out Approach makes timeouts a first-class member of an Workers execute Tasks and generate “Task Done” events
EDA framework, securing both types of Event Handlers for the Event Loop when they finish [60]. We refer to the
with a universal timeout mechanism. Event Loop and the Workers as Event Handlers.
Our Node.cure prototype (§7) demonstrates the Time-
out Approach in the complex Node.js framework, com-
pletely defending real applications against EHP attacks.
Node.cure spans the entire Node.js stack, modifying
the Node.js JavaScript engine (V8, C++), core modules
(JavaScript and C++), and the EDA mechanism (libuv,
C), and can secure real applications with low overhead
(§8). We feel our work is timely, as Staicu and Pradel
recently reported that hundreds of popular websites are
vulnerable to one type of EHP attack with minimal at-
tacker effort [94]; Node.cure defeats this and all other
EHP attacks.
Figure 1: This is the AMPED Event-Driven Architecture. Incoming
In summary: events from clients A and B are stored in the event queue, and the as-
1. We formally define Event Handler Poisoning (EHP) sociated Callbacks (CBs) will be executed sequentially by the Event
(§3), a DoS attack against the EDA. We systemati- Loop. We will discuss B’s EHP attack (CBB1 ), which has poisoned the
cally demonstrate that EHP attacks are common in the Event Loop, in §3.3.
largest EDA community, the Node.js ecosystem (§4).
2. We describe a general antidote for Event Handler Because the Event Handlers are shared by all clients,
Poisoning attacks: first-class timeouts. We demon- the EDA has a particular development paradigm. Each
strate effectiveness with our Node.cure prototype for Callback and Task is guaranteed atomicity: once sched-
Node.js in §7. We evaluate the security guarantees of uled, it runs to completion. Atomicity calls for coopera-
timeouts (strong, §6) and their costs (small, §8). tive multitasking [91], and developers partition the gen-
3. Our findings have been corroborated by the Node.js eration of responses into multiple stages. The effect of
community. Our guide on EHP-safe techniques is on this partitioning is to regularly yield to other requests by
nodejs.org, and our PRs documenting and improving deferring work until the next stage [52]. This partition-
unsafe Node.js APIs have been merged (§9). ing results in a Lifeline [39], a DAG describing the parti-
tioned steps needed to complete an operation. A Lifeline
2 Background can be seen by following the arrows in Figure 1.

In this section we review the EDA (§2.1), explain our 2.2 Node.js among other EDA frameworks
choice of EDA framework for study (§2.2), and introduce Examples of EDA frameworks include Node.js
directly related work (sections 2.3 and 2.4). (JavaScript) [13], libuv (C/C++) [9], Vert.x (Java) [26],
2.1 Overview of the EDA Twisted (Python1 ) [25], and Microsoft’s P# [56].
These frameworks have been used to build a wide
There are two paradigms for web servers, distinguished variety of industry and open-source services (e.g.
by the ratio of clients to resources, which corresponds [6, 82, 66, 77, 30, 29, 7, 3]).
to an isolation-performance tradeoff. The One Thread Most prominent among these frameworks is Node.js, a
Per Client Architecture (OTPCA) dedicates resources to server-side event-driven framework for JavaScript intro-
each client, for strong isolation but higher memory and duced in 2009. The popularity of Node.js comes from its
context-switching overheads [84]. The Event-Driven Ar- promise of “full stack JavaScript” — client- and server-
chitecture (EDA) tries the opposite approach, with many side developers can speak the same language and share
clients sharing execution resources: client connections the same libraries. This vision has driven the rise of the
are multiplexed onto a single-threaded Event Loop, with JavaScript package ecosystem, npm, which with 575,000
a small Worker Pool for expensive operations. modules is the largest of any language [55]. Node.js is
All mainstream server-side EDA frameworks use the still accelerating: use doubled between 2016 and 2017,
Asymmetric Multi-Process Event-Driven (AMPED) ar- from 3.5 million developers [31] to 7 million [33].
chitecture [83]. This architecture (hereafter “the EDA”)
The Node.js codebase has three major parts [61],
is illustrated in Figure 1. In the EDA, the OS or a frame-
whose interactions complicate top-to-bottom extensions
work places events in a queue, and the Callbacks of
pending events are executed sequentially by the Event 1 In addition, Python 3.4 introduced native EDA support.

2
like Node.cure. An application’s JavaScript code is exe- ity. The attacker knows how to exploit this vulnerability:
cuted using Google’s V8 JavaScript engine [63], its pro- they know the victim feeds user input to a Vulnerable
grammability is supported by Node.js core JavaScript API, and they know evil input that will cause the Vulner-
modules with C++ bindings for system calls, and the able API to block the Event Handler executing it. Lastly,
event-driven architecture is implemented in C using once identified, the victim will blacklist the attacker.
libuv [9].
3.2 A formal definition of an EHP attack
2.3 Algorithmic complexity attacks
Total/synchronous complexity and time. Before we
Our work is inspired by Algorithmic Complexity (AC)
can define EHP attacks, we must introduce a few def-
attacks ([74, 50]), a form of Denial of Service attack. In
initions. First, recall the standard EDA formulation il-
an AC attack, a malicious client crafts input that trig-
lustrated in Figure 1. Each client request is handled by
gers the worst-case complexity of the victim server’s
a Lifeline [39] partitioned into one or more Callbacks
algorithms, causing execution resources to be wasted.
and Tasks. A Lifeline is a DAG whose vertices are Call-
Well-known examples of AC attacks include attacks on
backs or Tasks and whose edges are events or Task sub-
hash tables [50] as well as Regular expression Denial of
missions.
Service (ReDoS) attacks, which exploit the worst-case
We define the total complexity of a Lifeline as the cu-
exponential-time behavior typical of regular expression
mulative complexity of all of its vertices as a function
(regexp) engines [49].
of their cumulative input. The synchronous complexity
As will be made clear in §3, EHP attacks are not sim-
of a Lifeline is the greatest individual complexity among
ply the application of AC attacks to the EDA. The first
its vertices. A Lifeline’s total time and synchronous time
distinction is a matter of perspective: where AC attacks
are defined analogously. Since the EDA relies on cooper-
focus on the complexity of the algorithms the service em-
ative multitasking, a Lifeline’s synchronous complexity
ploys, EHP attacks target the software architecture used
and synchronous time provide theoretical and practical
by the service, and are only concerned with time. The
bounds on how vulnerable it is. Note that a Lifeline with
second distinction is one of definition: AC attacks rely
large total time is not vulnerable so long as each vertex
on CPU-bound activities to achieve DoS, while EHP at-
(Callback/Task) has a small synchronous time; only syn-
tacks may use either CPU-bound or I/O-bound activities
chronous time matters for EHP.
to poison an Event Handler.
EHP attacks. An EHP attack exploits an EDA-based
2.4 Preliminary work on EHP attacks service with an incorrect implementation of cooperative
Davis et al.’s workshop paper [51] was the first to sketch multitasking. Here is how it works. The attacker iden-
EHP attacks. Their description was superficial, lacking tifies an exploitable Lifeline, one with large worst-case
a threat model or a formal description. Their (unimple- synchronous complexity, and poisons the corresponding
mented) solution was the “C-WCET Principle”, which large-complexity Callback or Task with evil input. This
would incur significant refactoring costs at the language, evil input causes the Event Handler executing it to block,
framework, and application levels. starving pending events or Tasks.
Our work offers a formal treatment of the EHP prob- An EHP attack can be carried out against either the
lem (§3), and introduces criteria for EHP-safety (§5) that Event Loop or the Workers in the Worker Pool. A poi-
explain why the C-WCET Principle is both ad hoc and soned Event Loop brings the server to a halt, while for
unsuited to dealing with I/O-based EHP attacks (§6). We each poisoned Worker the responsiveness of the Worker
then propose and prototype the Timeout Approach in Pool degrades. Thus, an attacker’s aim is to poison either
our Node.cure extension of Node.js (sections 7 and 8), the Event Loop or enough of the Worker Pool to harm the
and engage with the Node.js developer community to in- throughput of the server. Remember, the Worker Pool is
crease awareness of EHP attacks (§9). small enough that poisoning it will not attract the atten-
tion of network-level defenses.
3 Event Handler Poisoning Attacks Trends in software development [89] have made EHP
In this section we provide our threat model (§3.1), for- attacks relatively easy both to find and to launch. When
mally define Event Handler Poisoning (EHP) attacks commercial applications embrace open-source software,
(§3.2), and present an attack taxonomy (§3.5). To illus- including open-source package ecosystems, vulnerabili-
trate the problem, we demonstrate minimal EHP attacks ties in these (open-source) libraries may become vulner-
using ReDoS and “ReadDoS” (§3.3). abilities in the application. In §4.2 we show that many
npm modules have exploitable EHP vulnerabilities, and
3.1 Threat model that hundreds of real Node.js-based websites have been
We assume the following. The victim is an EDA-based affected. Even worse, these example EHP attacks are
server, e.g. a Node.js server, with an EHP vulnerabil- asymmetric, requiring a few small evil inputs from an

3
1 def serveFile ( name ) :
2 if name . match (/(\/.+) + $ /) : # ReDoS
3 data = await readFile ( name ) # ReadDoS
4 client . write ( data )

Figure 2: Gist of our simple server. It is vulnerable to two EHP attacks:


ReDoS (line 2) and ReadDoS (line 3).

attacker to poison an entire EDA-based server.

3.3 Illustrating EHP attacks: ReDoS and ReadDoS


To illustrate EHP attacks, we developed a minimal vul-
nerable file server with EHP vulnerabilities common in Figure 3: This figure shows the effect of evil input on the throughput of
a server based on Figure 2, with realistic vulnerabilities. Legitimate re-
real npm modules (§4.2). Figure 2 shows pseudocode, quests came from 80 clients using ab [1]. The attacks are against either
with the EHP vulnerabilities indicated: ReDoS on line baseline Node.js (grey) or our prototype, Node.cure (black). For Re-
2, and ReadDoS on line 3. In Figure 3 you can see the DoS (triangles), evil input was injected after three seconds, poisoning
the baseline Event Loop. For ReadDoS (circles), evil input was injected
impact of EHP attacks on baseline Node.js, as well as
four times at one second intervals beginning after three seconds, even-
the effectiveness of Node.cure. In a real website, these tually poisoning the baseline Worker Pool. The lines for Node.cure
attacks would result in partial or complete DoS. Without shows its effectiveness against these EHP attacks. When attacked,
Node.cure the only remedy would be to restart the server, Node.cure’s throughput dips until the timeout threshold is reached, af-
ter which its throughput temporarily rises as it bursts through the built-
dropping all existing client connections. up queue of pending events or Tasks.
ReDoS attacks have been well documented in the lit-
erature [49, 90, 96, 69, 88, 97]. A string composed of /’s
followed by a newline triggers exponential-backtracking contrast, in the OTPCA a similar attack poisons only
behavior in Node.js’s regular expression engine, poison- one of the thousands of “Event Handlers”. We believe
ing the Event Loop in a CPU-bound EHP attack. EHP attacks have not previously been explored because
The second EHP vulnerability might be more sur- the EDA has only recently seen popular adoption by the
prising. Our server has a directory traversal vulner- server-side community.
ability, permitting clients to read arbitrary files. In
the EDA, directory traversal vulnerabilities can be par- 3.5 A taxonomy of EHP attacks
layed into I/O-bound EHP attacks, “ReadDoS”, provided We turn now to a precise taxonomy of the root causes of
the attacker can identify a Slow File2 from which to EHP vulnerabilities. At a high level, large synchronous
read. Since line 3 uses the asynchronous framework API time can be attributed to the use of a Vulnerable API that
readFile, each ReadDoS attack on this server will poi- performs computation or I/O.
son a Worker in an I/O-bound EHP attack. Table 1 classifies Vulnerable APIs along two axes.
The architecture-level behavior of the ReDoS attack is Along the first axis, a Vulnerable API affects either the
illustrated in Figure 1. After client A’s benign request is Event Loop or a Worker, and it might be CPU-bound or
sanitized (CBA1 ), the readFile Task goes to the Worker I/O-bound. Along the second axis, a Vulnerable API can
Pool (TaskA1 ), and when the read completes the Callback be found in the language, the framework, or the applica-
returns the file content to A (CBA2 ). Then client B’s ma- tion. In our evaluation we provide an exhaustive list of
licious request arrives and triggers ReDoS (CBB1 ), drop- Vulnerable APIs for Node.js (§8.1). Although our exam-
ping the server throughput to zero. The ReadDoS attack ples are specific to Node.js, the same general classifica-
has a similar effect on the Worker Pool, with the same tion applies to any EDA framework.
unhappy result.

3.4 Aren’t EHP attacks possible in the OTPCA? 4 EHP Attacks In the Wild
EHP attacks are only possible when clients share exe- With a definition of EHP attacks in hand, we now assess
cution resources; they are not possible when clients are the awareness and incidence of EHP vulnerabilities in the
isolated as in the OTPCA. In the EDA, all clients share Node.js ecosystem. We found that the Node.js documen-
one Event Loop and a small Worker Pool. For exam- tation does not carefully outline the need for cooperative
ple, Node.js has a maximum of 128 Workers [17]. By multitasking (§4.1), which might contribute to the fact
2 In addition to files exposed on network file systems,
that 26% of known npm module vulnerabilities can be
/dev/random is a good example of a Slow File: “[r]eads from used for EHP attacks (§4.2); indeed, some already have
/dev/random may block” [34]. been [94].

4
Event Loop (§7.2) Worker Pool (§7.1)
Vuln. APIs
CPU-bound I/O-bound CPU-bound I/O-bound
Language Regexp, JSON N/A N/A N/A
Framework Crypto, zlib FS Crypto, zlib FS, DNS
Application while(1) DB query Regexp [12] DB query

Table 1: Taxonomy of Vulnerable APIs in Node.js, with examples.


An EHP attack through a Vulnerable API poisons the Event Loop or
a Worker, and its synchronous time is due to CPU-bound or I/O-bound
activity. A Vulnerable API might be part of the language, framework,
or application, and might be largely synchronous (Event Loop) or asyn-
chronous (Worker Pool). zlib is the Node.js compression library. N/A:
JavaScript has no native Worker Pool nor any I/O APIs.

Figure 4: Classification of the 838 npm module vulnerabilities, by cat-


egory and by usefulness in EHP attacks. Data from 29 January 2018.
4.1 The Node.js docs are quiet
We believe that examining the documentation and guides
for JavaScript and Node.js should tell us whether this does not discuss EHP attacks, we found that EHP vul-
community is aware of EHP attacks. nerabilities are common in npm modules, thus affecting
There are three places to look for Node.js documenta- any Node.js applications that rely on these modules.
tion. First, there is the JavaScript language specification. We systematically reproduced the analysis of Davis et
Second, Node.js maintains documentation for the APIs al. [51] on the Snyk.io vulnerability database [23]. Davis
of its core modules [19]. Third, the nodejs.org website et al. used a manual categorization of the 353 npm vul-
offers a set of guides for new developers [15]. nerabilities reported by Snyk.io as of February 2017. We
Although there are potential EHP vulnerabilities in an reproduced their analysis on the 838 npm vulnerabilities
implementation of JavaScript (like ReDoS or large JSON reported as of January 2018, using regular expressions
object manipulation), language specifications do not al- for a consistent classification scheme. Figure 4 shows the
ways discuss their risks. For example, in MDN’s docu- distribution of vulnerability types, absorbing categories
mentation only eval has warnings [11]. with fewer than 10 vulnerabilities into Other. A high-
The Node.js documentation does not indicate any vul- level CWE number is given next to each class.
nerabilities (like ReDoS) in its JavaScript engine. How- The dark bars in Figure 4 show the 223 vulnerabili-
ever, it does give hints about avoiding EHP attacks on ties (26%) that can be employed in an EHP attack under
the Node.js framework APIs. The Node.js APIs in- our threat model (§3.1). The 155 EHP-relevant Directory
clude several modules with Vulnerable APIs, and de- Traversal vulnerabilities are exploitable because they al-
velopers are warned away from the synchronous ver- low arbitrary file reads, which can poison the Event Loop
sions. The asynchronous versions, which could poison or the Worker Pool through ReadDoS (§3.3). The 59
the Worker Pool, bear the warning: “[These] APIs use EHP-relevant Denial of Service vulnerabilities poison
libuv’s threadpool, which can have surprising and neg- the Event Loop; 48 are ReDoS, and the remaining 11 can
ative performance implications for some applications,” trigger infinite loops or worst-case performance in inef-
and refer to another page reading “libuv’s threadpool has ficient algorithms. In Other are 9 Arbitrary File Write
a fixed size...other...APIs that run in libuv’s threadpool vulnerabilities that, like ReadDoS, can be used for EHP
[may] experience degraded performance.” While techni- attacks by writing to Slow Files.
cally sound, we feel that this level of documentation may Due to the frequent practice of using untrusted third-
be unhelpful for the average Node.js developer. party npm modules in production code [37], EHP vulner-
The most critical shortcoming we identified is in the abilities in npm translate directly into EHP vulnerabili-
Node.js new developer guides, which skip directly from ties in Node.js servers. For example, Staicu and Pradel
“Hello world” to deep dives on HTTP and profiling. recently showed how low the bar is for attackers. Af-
These guides do not advise developers on the design of ter remarking that “a skilled individual can attack real-
Node.js applications, which must fit the EDA paradigm world websites with moderate effort,” they used ReDoS
and avoid EHP vulnerabilities. Later we describe the vulnerabilities in popular npm modules to DoS hundreds
guide we wrote on these topics (§9), now available on of websites from the Alexa Top Million [94].
nodejs.org.

4.2 EHP vulnerabilities are common 5 What Does it Mean to be EHP-Safe?


While documentation can tell us about community Having defined the EDA (§2), explained EHP attacks
awareness, vulnerability databases tell us about the state (§3), and surveyed their reality (§4), we now ponder what
of practice. Although the community documentation it means to be EHP-Safe.

5
The fundamental cause of EHP vulnerabilities should Vulnerable API is always called with a safe input. The
be clear: EHP vulnerabilities stem from Vulnerable APIs Sanitary Approach is developer-unfriendly, because it re-
that fail to honor cooperative multitasking. As catego- quires developers to identify evil input for the APIs they
rized in Table 1, Vulnerable APIs can poison the Event call. And when Vulnerable APIs like regexps are used to
Loop or the Worker Pool, they can be CPU-bound or filter input, quis custodiet ipsos custodes?
I/O-bound, and they occur at any level of the application
stack: language (vulnerable constructs), framework (vul- 6.3 Refactor Vulnerable APIs
nerable core modules), or application (vulnerable code in A more promising path to EHP-safety is to refactor Vul-
the application or libraries). nerable APIs into safe ones, as proposed by Davis et
To be EHP-safe, an application must use APIs whose al. [51]. Since the goal of EHP-safety is to bound the syn-
synchronous time (§3.2) is (small and) bounded. If an ap- chronous time of a Lifeline, a developer could restrict the
plication cannot bound the synchronous time of its APIs, complexity of each of its Callbacks and Tasks, perhaps to
it is vulnerable to EHP attack; conversely, if an applica- Constant Worst-Case Execution Time (C-WCET). This
tion can bound the synchronous time of its APIs, then it would bound the synchronous complexity of the Life-
is EHP-safe. This application-level guarantee must span line. If all Vulnerable APIs were replaced with APIs fol-
the application’s full stack: the language constructs it lowing the C-WCET Principle, the application would be
uses, the framework APIs it invokes, and the application EHP-safe. The C-WCET Principle is the logical extreme
code itself. of cooperative multitasking, extending input sanitization
In §6, we outline several approaches to EHP-safety. To from the realm of data into the realm of the algorithms
choose between them, we suggest three criteria: used to process it.
1. General. A developer must be able to use existing Evaluating the C-WCET Principle. The C-WCET
APIs or slight modifications thereof. This ensures that Principle has two benefits. First, by bounding the syn-
applications are general, that they can solve meaning- chronous complexity of all Callbacks and Tasks, there
ful problems. would be no such thing as evil input. Every client re-
2. Developer-friendly. A developer should not need ex- quest could be handled. Second, the C-WCET Princi-
pertise in topics outside of their application domain. ple can be applied largely without changing the language
3. Composable. If a developer uses only EHP-safe APIs, specification. For example, as has previously been pro-
they should be unable to create a Vulnerable API. posed [48], a non-exponential-time regexp engine could
In a composably EHP-safe system, an API contain- be used in place of Node.js’s exponential-time Irregexp
ing while(1); would not be Vulnerable, because it engine [47], and most applications would be none the
is composed only of non-Vulnerable language con- wiser.
structs. In contrast, without composability a sys- The C-WCET Principle meets the generality criterion;
tem has only ad hoc EHP safety, because in addi- every API can be partitioned towards C-WCET. It is also
tion to making language- and framework-level APIs somewhat developer-friendly: language- and framework-
non-Vulnerable, all application-level APIs composed level APIs can be C-WCET partitioned by framework
of them must also be assessed. developers, leaving developers responsible for C-WCET
partitioning their own APIs. One difficulty, though, is
6 Antidotes for Event Handler Poisoning that application developers rely heavily on third-party
npm modules that might not be C-WCET-partitioned.
Here we discuss four schemes by which to guarantee
Critically, like the Blacklist and Sanitary Approaches,
EHP-safety: removing Vulnerable APIs (§6.1), only call-
the C-WCET Principle is not composable. Since Vulner-
ing Vulnerable APIs with safe input (§6.2), refactoring
able APIs can always be composed from non-Vulnerable
Vulnerable APIs into safe ones (§6.3), and bounding a
APIs3 , developers would need to take responsibility for
Callback or Task’s synchronous time at runtime (§6.4).
applying and maintaining the C-WCET Principle at the
We evaluate these schemes using the criteria from §5.
application level.
6.1 Remove calls to Vulnerable APIs It is worth noting that while the C-WCET Principle
To become EHP-safe, an application might eliminate applies readily to CPU-bound algorithms, it is unclear
calls to Vulnerable APIs. Obviously, this Blacklist Ap- how to achieve C-WCET Partitioning for I/O. Computa-
proach fails the generality criterion. tion can be partitioned to the instruction granularity, but
the granularity of I/O is poorly defined. For example, the
6.2 Sanitize input to Vulnerable APIs C-WCET Principle would have no trouble with ReDoS,
Many Vulnerable APIs are only problematic if they are 3 As noted in §5, an API consisting of a while(1); loop is Vulner-
called with unsafe input. Another approach to EHP- able in the Blacklist, Sanitary, and C-WCET Approaches, even though
safety, then, is the Sanitary Approach: ensure that every it only calls the constant-time “language APIs” while(1) and ;.

6
but cannot cleanly combat ReadDoS. .NET framework has used timeouts to combat ReDoS
since 2012 [20]. Unfortunately, such ad hoc timeouts
6.4 Dynamically bound the running time will always be non-composable. The second approach
The goal of the C-WCET Principle was to bound a Life- is on a per-thread basis: OSes commonly use a heart-
line’s synchronous complexity as a way to bound its syn- beat mechanism to detect and restart unresponsive ap-
chronous time, and would require refactoring every Vul- plications, and in the OTPCA a client thread can easily
nerable API. But instead of statically bounding an API’s be killed and replaced if it exceeds a timeout. But the
synchronous complexity, what if we could dynamically same approach fails in the EDA. Detecting and restart-
bound its synchronous time? Then the worst-case com- ing a blocked Event Loop will break all existing client
plexity of each Callback and Task would become irrel- connections, achieving the very DoS we seek to defeat.
evant, because they would be unable to take more than Remember the double-edged sword of the EDA: scala-
the quantum provided by the runtime. In this Timeout bility at the cost of client isolation. Because clients are
Approach, the runtime detects and aborts long-running not isolated on separate execution resources, our Time-
Callbacks and Tasks by emitting a TimeoutError, thrown out Approach makes timeouts a first-class member of
from Callbacks and returned from Tasks. JavaScript and Node.js, non-destructively guaranteeing
The Timeout Approach says that in the EDA, pure co- that no Event Handler can block on an event or Task.
operative multitasking is unsafe. Just as safe general- Another objection to the Timeout Approach is that
purpose languages offer null pointer exceptions and “someone must select a timeout,” and there is some evi-
buffer overflow exceptions, so a safe EDA framework dence that little thought has been given to the choice of
must offer timeout exceptions, and developers must be timeouts [85]. For the purpose of avoiding EHP attacks
prepared to deal with them. Developers should not have under our threat model, however, this does not pose a se-
to explicitly wrap sensitive code in timers or offload it rious problem. Remember that a typical web server han-
to separate threads or processes; in the EDA, timeouts dles hundreds or thousands of clients per second (Fig-
should be provided by the framework just like any other ure 3). If so, simple arithmetic tells us that in a Node.js
security-relevant exception. server, individual Callbacks and Tasks must be taking no
The Timeout Approach provides EHP-safety. Like the longer than milliseconds to complete. Thus, a univer-
C-WCET Principle, the Timeout Approach is general. It sal Callback-Task timeout on the order of 1 second will
is more developer-friendly because it only requires de- not discomfit normal Callbacks and Tasks, will certainly
velopers to handle TimeoutErrors in their own APIs. ensure that an EHP attack is detected and defeated expe-
And where the C-WCET Principle was ad hoc, the Time- diently, and might briefly annoy existing clients but not
out Approach is composable. If the EDA runtime had a significantly undermine their experience. It then falls to
sense of time, then a long-running Callback/Task could the application to blacklist the attacker.
be interrupted no matter where it was, whether in the lan- The last objection is “it’s trivial!” We report, however,
guage, the framework, or the application. that though the Timeout Approach is conceptually sim-
Although the Timeout Approach fulfills all of the ple, realizing it in a complex real-world framework like
EHP-safety criteria, like C-WCET Partitioning it re- Node.js is difficult. The challenges that face a sound im-
quires application-level refactoring. Because the pro- plementation are:
posed TimeoutErrors emitted by the runtime are not cur-
1. Enforcing timeouts on both Callbacks and Tasks.
rently part of the language and framework specification,
2. Enforcing timeouts in both the language (V8) and the
existing applications would need to be ported. We do not
framework (Node.js core modules and libuv).
anticipate this to be a heavy burden for well-written ap-
3. Ensuring that timeouts are low-overhead.
plications, whose Callbacks should already be exception-
aware to catch errors like null pointers (ReferenceError)
and buffer overflows (RangeError), and which should 7 First-Class Timeouts in Node.cure
test the result of Tasks for errors.
Our Node.cure prototype implements the Timeout Ap-
Though the C-WCET Principle and the Timeout Ap-
proach for Node.js by bounding the synchronous time of
proach both meet the generality criterion, the Timeout
every Callback and Task. To do so, Node.cure makes
Approach is more developer-friendly, and is the only
timeouts a first-class member of Node.js, extending the
EDA-centric solution we analyzed that is composable4 .
JavaScript specification by introducing a TimeoutError
Objections. One objection to the Timeout Approach
to abort long-running Callbacks and Tasks.
is that “timeouts are hardly novel.” We disagree. To
At a high level, here is the timeout behavior
the best of our knowledge, existing timeouts take one
Node.cure enforces. A long-running Callback poisons
of two approaches. The first is on a per-API basis: the
the Event Loop; in Node.cure these Callbacks throw
4 We discuss alternative approaches to achieve EHP-safety in §9. a TimeoutError whether they are in JavaScript or in a

7
Callback Description
void work Perform Task.
int timed out* When Task has timed out. Can request extension.
void done When Task is done. Special error code for timeout.
void killed* When a timed out Task’s thread has been killed.

Table 2: Summary of the Worker Pool API. work is invoked on the


Worker. done is invoked on the Event Loop. The new callbacks,
timed out and killed, are invoked on the Manager and the Hang-
Figure 5: This figure illustrates Node.cure’s timeout-aware Worker
man, respectively. On a timeout, work, timed out, and done are
Pool, including the roles of Event Loop, Executors (Worker Pool and
invoked, in that order; there is no ordering between the done and
Priority), and Hangman. Grey entities were present in the original
killed callbacks, which sometimes requires reference counting for
Worker Pool, black are new. The Event Loop can synchronously access
safe memory cleanup. *New callbacks.
the Priority Executor, or asynchronously offload Tasks to the Worker
Pool. If an Executor’s Manager sees its Worker time out, it creates a
replacement Worker and passes the Dangling Worker to a Hangman.
out. The Event Loop then invokes its done Callback with
a TimeoutError, permitting a rapid response to evil in-
Node.js C++ binding (§7.2). A long-running Task poi- put. Concurrently, once the Hangman successfully kills
sons its Worker; in Node.cure, such a Task is aborted the Worker thread, it invokes the Task’s killed callback
and fulfilled with a TimeoutError (§7.1). for resource cleanup, and returns.
As a result, Node.cure meets the composability crite- Differentiating between timed out and killed per-
rion of §5: the Node.js language and framework APIs are mits more flexible error handling, but introduces tech-
timeout-aware, and an application whose APIs are com- nical challenges. If a rapid response to a timeout is un-
posed of these APIs will be EHP-safe (§7.3). Node.cure necessary, then it is simple to defer done until killed
also has an exploratory Slow Resource Policy to reduce finishes. If a rapid response is necessary, then done must
timeout overheads (§7.4). be able to run before killed finishes, resulting in a Dan-
We describe the Timeout Approach for Tasks first, be- gling Worker problem: an API’s work implementation
cause it introduces machinery used to apply the Timeout may access externally-visible state after the Event Loop
Approach to Callbacks. receives the associated TimeoutError. We addressed the
Dangling Worker problem in Node.js’s Worker Pool cus-
7.1 Timeout-aware Tasks tomers using a mix of killed-waiting, message passing,
EHP attacks targeting the Worker Pool use Vulnerable and blacklisting.
APIs to submit long-running Tasks that poison a Worker. Timeout-aware Worker Pool Customers. The
Node.cure defends against such attacks by bounding the Node.js APIs affected by this change (i.e. those that cre-
synchronous time of Tasks. ate Tasks) are in the encryption, compression, DNS, and
Timeout-aware Worker Pool. We modified the file system modules. In all cases we allowed timeouts to
libuv Worker Pool to be timeout-aware, replacing libuv’s proceed, killing the long-running Worker. Handling en-
Workers with Executors that combine a permanent Man- cryption and compression was straightforward, while the
ager with a disposable Worker. If a Task times out, the DNS and file system APIs were more complex.
Manager uses a Hangman to dispose of the poisonous Node.js’s asynchronous encryption and compression
Task and its Worker, and creates a new Worker to resume APIs are implemented in Node.js C++ bindings by in-
handling Tasks. These roles are illustrated in Figure 5. voking APIs from openssl and zlib, respectively. If the
Here is a slightly more detailed description of our Worker Pool notifies these APIs of a timeout, they wait
timeout-aware Worker Pool. Node.js’s Worker Pool is for the Worker to be killed before returning, to ensure
implemented in libuv, exposing a Task submission API it no longer modifies state in these “black-box” libraries
uv queue work, which we extended as shown in Table 2. nor accesses memory that might be released after done
The original Workers of the Worker Pool would simply is invoked. Since openssl and zlib are purely computa-
invoke work and then notify the Event Loop to invoke tional, the Dangling Worker is killed immediately.
done. This is also the typical behavior of our timeout- Node.js implements its file system and DNS APIs by
aware Workers. When a Task takes too long, however, relying on libuv’s file system and DNS support, which
the potentially-poisoned Worker’s Manager invokes the on Linux make the appropriate calls to libc. Because the
Task’s timed out callback. If the submitter does not libuv file system and DNS implementations share mem-
request an extension, the Manager creates a replace- ory between the Worker and the submitter, we modified
ment Worker so that it can continue to process subse- them to use message passing for memory safety of Dan-
quent Tasks, creates a Hangman thread for the poisoned gling Workers — wherever the original implementation’s
Worker, and notifies the Event Loop that the Task timed work accessed memory owned by the submitter, e.g. for

8
read and write, we introduced a private buffer for work earlier than after the current JavaScript instruction fin-
and added copyin/copyout steps. In addition, we used ishes. High priority interrupts take effect immediately,
pthread setcancelstate to ensure that Workers will not interrupting long-running JavaScript instructions. Time-
be killed while in a non-cancelable libc API [5]. DNS outs require the use of a high priority interrupt because
is read-only so there is no risk of the Dangling Worker they must be able to interrupt long-running individual
modifying external state. In the file system, write mod- JavaScript instructions like str.match(regexp) (possi-
ifies external state, but we avoid any Dangling Worker ble ReDoS).
state pollution via blacklisting. Our blacklisting-based To support a TimeoutError, we modified V8 as fol-
Slow Resource policy is discussed in more detail in §7.4. lows: (1) We added the definition of a TimeoutError
At the top of the Node.js stack, when the Event Loop into the Error class hierarchy; (2) We added a
sees that a Task timed out, it invokes the application’s TimeoutInterrupt into the list of high-priority in-
Callback with a TimeoutError. terrupts; and (3) We added a V8 API to raise a
TimeoutInterrupt. The TimeoutWatchdog calls this
7.2 Timeouts for Callbacks
API, which interrupts the current JavaScript stack by
Node.cure defends against EHP attacks that target the throwing a TimeoutError.
Event Loop by bounding the synchronous time of Call- The only JavaScript instructions that V8 instruments
backs. To make Callbacks timeout-aware, we introduce to be interruptible are regexp matching and JSON
a TimeoutWatchdog that monitors the start and end of parsing; these are the language-level Vulnerable APIs.
each Callback and ensures that no Callback exceeds the Other JavaScript instructions are viewed as effectively
timeout threshold. We time out JavaScript instructions constant-time, so these interrupts are evaluated e.g. at
using V8’s interrupt mechanism (§7.2.1), and we mod- the end of basic blocks. We agreed with the V8 devel-
ify Node.js’s C++ bindings to ensure that Callbacks that opers in this5 , and did not attempt to instrument other
enter these bindings will also be timed out (§7.2.2). JavaScript instructions to poll for pending interrupts.
7.2.1 Timeouts for JavaScript 7.2.2 Timeouts for the Node.js C++ bindings

TimeoutWatchdog. Our TimeoutWatchdog instru-


The TimeoutWatchdog described in §7.2.1 will inter-
ments every Callback using the experimental Node.js
rupt any Vulnerable APIs implemented in JavaScript, in-
async-hooks module [14], which allows an application
cluding language-level APIs like regexp and application-
to register special Callbacks before and after a Callback
level APIs that contain blocking code like while(1);. It
is invoked.
remains to give a sense of time to the Node.js C++ bind-
Before a Callback begins, our TimeoutWatchdog starts
ings that allow the JavaScript code in Node.js applica-
a timer. If the Callback completes before the timer ex-
tions to interface with the broader world.
pires (“good path”), we erase the timer. If the timer ex-
Node.js has asynchronous and synchronous C++ bind-
pires, the watchdog signals V8 to interrupt JavaScript ex-
ings. The asynchronous bindings are safe because they
ecution by throwing a TimeoutError. The watchdog then
do a fixed amount of work synchronously to submit a
starts another timer, ensuring that timeouts while han-
Task and then return. However, the synchronous C++
dling the previous TimeoutError are also detected.
bindings complete the entire operation on the Event Loop
Although a precise TimeoutWatchdog can be imple-
before returning, and therefore must be given a sense
mented to carefully honor the timeout threshold, the
of time. The relevant Vulnerable synchronous APIs are
resulting communication overhead between the Event
those in the file system, cryptography, and compression
Loop and the TimeoutWatchdog can be non-trivial
modules. The execSync API is also Vulnerable, but is
(§8.2). A cheaper alternative is a lazy TimeoutWatch-
only intended for scripting purposes.
dog, which simply wakes up at intervals of the timeout
Because the Event Loop holds the state of all pend-
threshold and checks whether the Callback it last ob-
ing clients, we cannot use the Hangman pthread cancel
served is still executing; if so, it emits a TimeoutError.
approach, as this would result in the DoS the at-
A lazy TimeoutWatchdog reduces the overhead of mak-
tacker desired. Another alternative is to offload the
ing a Callback, but decreases the precision of the
request to the Worker Pool and await its completion,
TimeoutError threshold.
but this would incur high request latencies when the
V8 interrupts. To handle the TimeoutWatchdog’s re-
Worker Pool’s queue is not empty. Instead, we ex-
quest for a TimeoutError, Node.cure extends the in-
tended the Worker Pool paradigm with a dedicated Pri-
terrupt infrastructure of Node.js’s V8 JavaScript en-
ority Executor whose queue is exposed via a new API:
gine [63] to support timeouts. In V8, low priority inter-
rupts like a pending garbage collection are checked regu- 5 Forexample, we found that string operations complete in millisec-
larly (e.g. each loop iteration, function call, etc.), but no onds even when a string is hundreds of MBs long.

9
uv queue work prio (Figure 5). This Executor follows accesses6 , with the happy side effect of solving the Dan-
the same Manager-Worker-Hangman paradigm as the gling Worker problem for write. This policy is appropri-
Executors in Node.cure’s Worker Pool. To make these ate for the file system, where access times are not likely
Vulnerable synchronous APIs timeout-aware, we offload to change7 . For DNS queries, timeouts are likely due to a
them to the Priority Executor using the existing asyn- network hiccup, and a temporary blacklist might be more
chronous implementation of the API, and had the Event appropriate.
Loop await the result. Because these synchronous APIs
are performed on the Event Loop as part of a Callback, 7.5 Prototype details
we propagate the Callback’s remaining time to this Ex- Node.cure is built on top of Node.js LTS v8.8.18 , a re-
ecutor’s Manager to ensure that the TimeoutWatchdog’s cent long-term support version of Node.js. Our proto-
timer is honored. type is for Linux, and added 4,000 lines of C, C++,
and JavaScript code across 50 files spanning V8, libuv,
7.3 Timeouts for application-level Vulnerable APIs the Node.js C++ bindings, and the Node.js JavaScript li-
Let us revisit Node.cure’s composability guarantee. As braries.
described above, Node.cure makes Tasks (§7.1) and Node.cure is a complete and correct implementation
Callbacks (§7.2) timeout-aware to defeat EHP attacks of the Timeout Approach. It passes the core Node.js test
against language and framework APIs. The Timeout Ap- suite, with a handful of failures due to bad interactions
proach is composable, so an application composed of with experimental or deprecated features. In addition,
calls to these APIs will be EHP-safe. several cases fail when they invoke rarely-used file sys-
However, applications can still escape the reach of the tem APIs we did not make timeout-aware. Real applica-
Timeout Approach by defining their own C++ bindings. tions run on Node.cure without difficulty (Table 3).
These bindings would need to be made timeout-aware, In Node.cure, timeouts for Callbacks and Tasks are
following the example we set while making Node.js’s controlled by environment variables. Our implementa-
Vulnerable C++ bindings timeout-aware (file system, tion would readily accommodate a fine-grained assign-
DNS, encryption, and compression). Without refactor- ment of timeouts for individual Callbacks and Tasks.
ing, applications with their own C++ bindings may not be
EHP-safe. In our evaluation we found that application- 8 Evaluating Node.cure
defined C++ bindings are rare (§8.3).
We evaluated Node.cure in terms of its effectiveness
7.4 Exploring policies for slow resources (§8.1), costs (§8.2), and security guarantees (§8.3). In
summary: with a lazy TimeoutWatchdog, Node.cure de-
Our Node.cure runtime detects and aborts long-running feats all known EHP attacks with low overhead on the
Callbacks and Tasks executing on Node.js’s Event Han- “good path”, estimated at 1.3x using micro-benchmarks
dlers. For unique evil input this is the best we can do, as and manifesting at 1.0x-1.24x using real applications.
accurately predicting whether a not-yet-seen input will Node.cure guarantees EHP-safety to all Node.js appli-
time out is difficult. If an attacker might re-use the same cations that do not define their own C++ bindings, a rare
evil input multiple times, however, we can track whether practice.
or not an input led to a timeout and short-circuit subse- All measurements provided in this section were ob-
quent requests that use this input with an early timeout. tained on an otherwise-idle desktop running Ubuntu
While evil input memoization could in principle be ap- 16.04.1 (Linux 4.8.0-56-generic), 16GB RAM, Intel i7
plied to any API, the size of the input space to track is a @3.60GHz, 4 physical cores with 2 threads per core.
limiting factor. The evil inputs that trigger CPU-bound For a baseline we used Node.js LTS v8.8.1 from which
EHP attacks like ReDoS exploit properties of the vulner- Node.cure was derived, compiled with the same flags.
able algorithm and are thus usually not unique. In con- We used a default Worker Pool (4 Workers).
trast, the evil inputs that trigger I/O-bound EHP attacks
like ReadDoS must name a particularly slow resource, 8.1 Effectiveness
presenting an opportunity to short-circuit requests on this To evaluate the effectiveness of Node.cure, we devel-
slow resource. oped an EHP test suite that makes EHP attacks of all
In Node.cure we implemented a slow resource man- types shown in Table 1. Our suite is comprehensive and
agement policy for libuv’s file system APIs, targeting conducts EHP attacks using every Vulnerable API we
those that reference a single resource (e.g. open, read,
6 Toavoid fd leaks, we do not eagerly abort close.
write). When one of the APIs we manage times out, we 7 Of course, if the slow resource is in a networked file system like
mark the file descriptor and the associated inode num- NFS or GPFS, slowness might be due to a network hiccup, and incorpo-
ber as slow. We took the simple approach of perma- rating temporary device-level blacklisting might be more appropriate.
nently blacklisting these aliases by aborting subsequent 8 Node.js v8.8.1 commit dc6bbb44da on Oct. 25, 2017.

10
identified, including the language level (regexp, JSON), the lazy overhead drops to 1.3x and the precise overhead
framework level (all Vulnerable APIs from the file sys- drops to 2.7x; at 10,000 empty loop iterations, the lazy
tem, DNS, cryptography, and compression modules), and precise overheads are 1.01x and 1.15x, respectively.
and application level (infinite loops, long string opera- Worker buffering. Our timeout-aware Worker Pool re-
tions, array sorting, etc.). This test suite includes each quires buffering data to accommodate Dangling Work-
type of real EHP attack from our study of EHP vulner- ers, affecting DNS queries and file system I/O. While
abilities in npm modules (§4.2). Node.cure defeats all this overhead will vary from API to API, our micro-
92 EHP attacks in this suite: each synchronous Vulnera- benchmark indicated a 1.3x overhead using read and
ble API throws a TimeoutError, and each asynchronous write calls with a 64KB buffer.
Vulnerable API returns a TimeoutError. Overhead: Macro-benchmarks. Our micro-
To finish our suite, we ported a vulnerable npm mod- benchmarks suggested that the overhead introduced by
ule to Node.cure. We selected the node-oniguruma [12] Node.cure may vary widely depending on what an ap-
module, which offers asynchronous regexp APIs. Since plication is doing. Applications that make little use of
the Oniguruma regexp engine is vulnerable to ReDoS, the Worker Pool will only pay the overhead of the ad-
its APIs are Vulnerable. However, they evaluate the reg- ditional V8 interrupt (minimal) and the TimeoutWatch-
exps in a Task rather than in a Callback, and so poi- dog’s async hooks, whose cost is strongly dependent
son a Worker rather than the Event Loop. We made on the size of the Callbacks. Applications that use the
node-oniguruma timeout-aware by using our modified Worker Pool will also pay the overhead of Worker buffer-
Worker Pool uv queue work API (Table 2). Node.cure ing (variable, perhaps 1.3x).
times out ReDoS attacks against this module’s Vulnera- We chose macro-benchmarks using a GitHub pot-
ble APIs. pourri technique: we searched GitHub for “lan-
guage:JavaScript”, sorted by “Most starred”, and iden-
8.2 Costs tified server-side projects from the first 50 results. To
The Timeout Approach introduces runtime overheads, add additional complete servers, we also included Lok-
which we evaluated using micro-benchmarks and macro- iJS [10], a popular Node.js-based key-value store, and
benchmarks. It may also require some refactoring, and a IBM’s Acme-Air airline simulation [2].
choice of timeout. Table 3 lists the macro-benchmarks we used and the
Overhead: Micro-benchmarks. Whether or not they performance overhead for each type of TimeoutWatch-
time out, Node.cure introduces several sources of over- dog. These results show that Node.cure introduces min-
heads to monitor Callbacks and Tasks. We evaluated the imal overhead on real server applications, and they con-
following overheads using micro-benchmarks: firm the value of a lazy TimeoutWatchdog. Matching our
1. Every time V8 checks for interrupts, it now tests for a micro-benchmark assessment of the TimeoutWatchdog’s
pending timeout as well. async-hooks overhead, the overhead from Node.cure in-
2. Both the lazy and precise versions of the Timeout- creased as the complexity of the Callbacks used in the
Watchdog instrument every asynchronous Callback macro-benchmarks decreased — the middleware bench-
using async-hooks, with relative overhead dependent marks sometimes used empty Callbacks to handle client
on the complexity of the Callback. requests. In non-empty Callbacks like those of the real
3. To ensure memory safety for Dangling Workers, servers, this overhead is amortized.
Workers operate on buffered data that must be al- Refactoring. Node.cure adds a TimeoutError to the
located when the Task is submitted. For example, JavaScript and Node.js specifications. See §9.
Workers must copy the I/O buffers supplied to read Choice of timeout. See §6.4 and §9.
and write twice.
New V8 interrupt. We found that the overhead of our 8.3 Security Guarantees
V8 Timeout interrupt was negligible, simply a test for We discussed the general security guarantees of the
one more interrupt in V8’s interrupt infrastructure. Timeout Approach in §6.4. Here we discuss the precise
TimeoutWatchdog’s async hooks. We measured the security guarantees of our Node.cure prototype. As de-
additional cost of invoking a Callback due to Timeout- scribed in §7, we gave a sense of time to JavaScript (in-
Watchdog’s async hooks. A lazy TimeoutWatchdog in- cluding interrupting long-running regexp and JSON op-
creases the cost of invoking a Callback by 2.4x, and a erations) as well as to framework APIs identified by the
precise TimeoutWatchdog increases the cost by 7.9x. Of Node.js developers as long-running (file system, DNS,
course, this overhead is most noticeable in Callbacks that cryptography, and compression).
are empty. As the number of instructions in a Callback Because the Timeout Approach is composable,
increases, the cost of the hooks amortizes. For exam- application-level APIs composed of these timeout-aware
ple, if the Callback executes 500 empty loop iterations, language and framework APIs are also timeout-aware.

11
Benchmark Description Overheads Principle11 . First, we submitted a PR with a guide
LokiJS [10] Server, Key-value store 1.00, 1.00 to building EHP-safe EDA-based applications. It was
Node Acme-Air [2] Server, Airline simulation 1.02, 1.03
webtorrent [27] Server, P2P torrenting 1.02, 1.02
merged and can be found on nodejs.org, where new
ws [28] Utility, websockets 1.00, 1.00*
Node.js developers go to learn best practices for Node.js
Three.js [24] Utility, graphics library 1.08, 1.09 development. We believe that it will give developers in-
Express [4] Middleware 1.06, 1.24 sights into secure Node.js programming practices.
Sails [22] Middleware 1.14, 1.23* Second, we studied the Node.js implementation
Restify [21] Middleware 1.14, 1.63* and identified several unnecessarily Vulnerable APIs
Koa [8] Middleware 1.24, 1.60
in Node.js (fs.readFile, crypto.randomFill, and
crypto.randomBytes, all of which submit a single un-
Table 3: Results of our macro-benchmark evaluation of Node.cure’s partitioned Task). Our PRs warning developers about
overhead. Where available, we used the benchmarks defined by the the risks of EHP attacks using these APIs have been
project itself. Otherwise, we ran its test suite. Overheads are reported merged. We also submitted a trial pull request repair-
as “lazy, precise”, and are the ratio of Node.cure’s performance to that
of the baseline Node.js, averaged over several steady-state runs. We ing the simplest of these, by partitioning fs.readFile. It
report the average overhead because we observed no more than 3% was been merged after a multi-month discussion on the
standard deviation in all but LokiJS, which averaged 8% standard de- performance-security tradeoff involved.
viation across our samples of its sub-benchmarks. *: Median of sub-
What might timeout-aware programs look like? As
benchmark overheads.
discussed in §7, applying the Timeout Approach while
preserving the EDA changes the language and frame-
However, Node.js also permits applications to add their work specifications. In particular, all synchronous APIs
own C++ bindings, and these will not be timeout-aware may now throw a TimeoutError, and all asynchronous
without refactoring. APIs may now be fulfilled with a TimeoutError. These
To evaluate the extent of this limitation, we measured changes have two implications for application develop-
how frequently developers use C++ bindings. To this ers: Timeout-aware applications must be able to toler-
end, we examined a sample of npm modules. We npm ate arbitrary TimeoutErrors (just like any other excep-
install’d 125,173 modules (about 20% of the ecosys- tion), and developers should pursue low-variance Call-
tem) using node v8.9.1 (npm v5.5.1), resulting in 23,070 backs and Tasks (to permit the choice of a tighter timeout
successful installations9 . Of these, 695 (3%) had C++ threshold).
bindings10 . Are there other avenues toward EHP-safety? In
From this we conclude that the use of user-defined §6 we discussed several EHP-safe designs. There are of
C++ bindings is uncommon in npm modules, unsur- course other approaches, like significantly increasing the
prising since many developers in this community come size of the Worker Pool, performing speculative concur-
from client-side JavaScript and may not have strong C++ rent execution [45], or using explicitly preemptable Call-
skills. This implies, but does not directly indicate, that backs and Tasks. However, each of these is a variation
C++ bindings are unusual in Node.js applications. We on the same theme: dedicating resources to every client,
conclude that the need to refactor C++ bindings to be i.e. the One Thread Per Client Architecture. If the server
timeout-aware would not place a significant burden on community wishes to use the EDA, which offers high
the community. As a template, we performed several responsiveness and scalability through the use of coop-
such refactorings ourselves in the Node.js framework and erative multitasking, we believe the Timeout Approach
our port of node-oniguruma. is a good path to EHP-safety.

9 Discussion 10 Related Work


Throughout the paper we have referred to specific related
What should the EDA community do without time-
work. Here we place our work in its broader context, sit-
outs? Although they lack first-class timeouts, develop-
uated at the intersection of the Denial of Service litera-
ers in the EDA community must still be concerned about
ture and the Event-Driven Architecture community.
EHP attacks. We believe their best approach is the C-
Denial of Service attacks. Research on DoS can
WCET Principle (§6.3).
be broadly divided into network-level attacks (e.g. dis-
We have pursued a two-pronged approach to help de-
tributed DoS attacks) and application-level attacks [38].
velopers in the Node.js community follow the C-WCET
Since EHP attacks exploit the semantics of the appli-
9 Module installations failed for reasons including “No such mod- cation, they are application-level attacks, not easily de-
ule”, “Unsupported OS”, and “Unsupported Node.js version”. feated by network-level defenses.
10 We determined the presence of C++ bindings by searching a mod-

ule’s directory tree for files with endings like “.h” and “.c[pp]”. 11 We omit references to meet the double-blind requirement.

12
DoS attacks seek to exhaust the resources critical to “Don’t block the Event Loop”, advised by many tuto-
the proper operation of a server, and various kinds of rials as well as recent books about EDA programming
exhaustion have been considered. The brunt of the lit- for Node.js [98, 44]. Wandschneider suggests worst-case
erature has focused on exhausting the CPU. Some have linear-time partitioning on the Event Loop [98], while
examined the gap between common-case and worst-case Casciaro advises developers to partition any computation
performance in algorithms and data structures, for ex- on the Event Loop, and to offload computationally ex-
ample in quicksort [74], hashing [50], and exponentially pensive tasks to the Worker Pool [44]. Our work offers a
backtracking algorithms like ReDoS [49, 90] and rule more rigorous taxonomy and evaluation of EHP attacks,
matching [92]. Other CPU-centric DoS attacks have tar- and in particular we extend the rule of “Don’t block the
geted more general programming issues, showing how to Event Loop” to the Worker Pool.
trigger infinite recursion [46] and how to trigger [93] or EHP attacks on the server side may correspond to per-
detect [42] infinite loops. But the CPU is not the only formance bugs in client-side EDA programs. Liu et al.
vulnerable resource, as shown by Olivo et al.’s work pol- studied such bugs [72], and Lin et al. proposed an au-
luting databases to increase the cost of queries [79]. We tomatic refactoring to offload expensive tasks from the
are not aware of prior research work that incurs DoS us- Event Loop to the Worker Pool [71]. This approach is
ing the file system, as do our ReadDoS attacks, though sound on a client-side system like Android, where the
we have found a handful of CVE reports to this effect12 demand for threads is limited, but is not applicable to
Our work identifies and shows how to exploit the the server-side EDA because the small Worker Pool is
most limited resource of the EDA: Event Handlers. To shared among all clients. For the server-side EDA, Lin et
launch a similar attack in the OTPCA, attackers must al.’s approach would need to be extended to incorporate
submit enough queries to overwhelm the OS’s preemp- automatic C-WCET partitioning.
tive scheduler, no mean feat. In contrast, in the EDA
As future work, we believe that research into compu-
there are only a few Event Handlers to be poisoned. Al-
tational complexity estimation ([80, 65, 86]) and mea-
though we prove our point using previously-reported at-
surement ([87, 62, 43]) might be adapted to the Node.js
tacks like ReDoS, the underlying resource we are ex-
context for EHP vulnerability detection and automatic
hausting is not the CPU but the small, fixed-size set of
refactoring using the C-WCET Principle. This may be
Event Handlers deployed in EDA-based services.
difficult because of the complexity of statically analyz-
Security in the EDA. Though researchers have stud-
ing JavaScript and the EDA ([73, 40, 64, 99, 59]).
ied security vulnerabilities in different EDA frameworks,
most prominently client-side applications, the security
properties of the EDA itself have not been investigated 11 Conclusion
in detail.
Our work is most closely related to the workshop pa- The Event-Driven Architecture (EDA) holds great
per of Davis et al. [51], discussed earlier (§2.4). Less promise for scalable web services, and it is increasingly
immediately relevant is the Node.js-specific high-level popular in the software development community. In this
survey of Ojamaa et al. [78], which mentioned the rule paper we formally defined Event Handler Poisoning at-
“Don’t block the event loop”, and Staicu and Pradel’s tacks, which exploit the the cooperative multitasking at
study on code injection vulnerabilities in npm [95], the heart of the EDA. The Node.js community has en-
which can be used for EHP attacks. DeGroef et al. [54]’s dorsed our expression of this problem, hosting our guide
proposed method to securely integrate third-party mod- at nodejs.org.
ules from npm is not effective for EHP attacks because
We proposed several defenses against EHP attacks,
Node.js lacks a sense of time.
and prototyped the most promising: first-class time-
More broadly, other security research in the EDA has
outs. Our prototype, Node.cure, defends Node.js appli-
studied client-side JavaScript/Web [70, 68, 53, 75] and
cations against all known EHP attacks. It is available on
Java/Android [58, 57, 41, 67] applications. These have
GitHub13 .
often focused on platform-specific issues like DOM issues
in web browsers [70]. Our findings can be directly applied by the EDA com-
EHP attacks. The server-side EDA practitioner com- munity, and we hope they influence the design of existing
munity is aware of the risk of DoS due to (synchronous) and future EDA frameworks. With the rise of popularity
EHP on the Event Loop. A common rule of thumb is in the EDA, EHP attacks will become an increasingly
critical DoS vector, a vector that can be defeated with
12 For Slow Files (/dev/random), see CVE-2012-1987 and CVE- first-class timeouts.
2016-6896. For a related DOS by reading Large Files, CVE-2001-
0834, CVE-2008-1353, CVE-2011-1521, and CVE-2015-5295 men-
tion DoS by ENOMEM using /dev/zero. 13 We omit the reference to meet the double-blind requirement.

13
Acknowledgments [28] ws: a node.js websocket library. https://github.com/
websockets/ws.
We thank the CCS, NDSS, S&P, and USENIX Security
[29] The Calendar and Contacts Server. https://github.com/
referees for their helpful feedback, as well as XXX for Apple/Ccs-calendarserver, 2007.
their excellent shepherding. L. Cheng, C. Coghlan, A. [30] Ubuntu One: Technical Details. https://wiki.ubuntu.
Kazerouni, S. Rahaman, J. Terner, and the Virginia Tech com/UbuntuOne/TechnicalDetails, 2012.
Systems Reading Group were helpful sounding boards [31] New node.js foundation survey reports new “full stack” in
for our ideas and manuscripts, as were M. Hicks, G. demand among enterprise developers. https://nodejs.org/
Wang, and D. Yao. J.D. Greef of Ronomon suggested en/blog/announcements/nodejs-foundation-survey/,
2016.
several of the EHP attacks listed in the discussion.
[32] 2017 User Survey Executive Summary. The Linux Foundation,
2017.
References
[33] The linux foundation: Case study: Node.js. https:
[1] ab – apache http server benchmarking tool. https://httpd. //www.linuxfoundation.org/wp-content/uploads/
apache.org/docs/2.4/programs/ab.html. 2017/06/LF_CaseStudy_NodeJS_20170613.pdf, 2017.
[2] acmeair-node. https://github.com/acmeair/ [34] Random(4). http://man7.org/linux/man-pages/man4/
acmeair-nodejs. random.4.html, 2017.
[3] Cylon.js. https://cylonjs.com/. [35] This is what node.js is used for in 2017 – sur-
[4] express. https://github.com/expressjs/express. vey results. https://blog.risingstack.com/
what-is-node-js-used-for-2017-survey/, 2017.
[5] Gnu libc – posix safety concepts. https://www.
gnu.org/software/libc/manual/html_node/ [36] How cond nast used node.js to unify brands and create cus-
POSIX-Safety-Concepts.html. tomer faith. https://www2.thelinuxfoundation.org/
node-casestudies-condenast, 2018.
[6] Ibm node-red. https://nodered.org/.
[37] A BDALKAREEM , R., N OURRY, O., W EHAIBI , S., M UJAHID ,
[7] iot-nodejs. https://github.com/ibm-watson-iot/
S., AND S HIHAB , E. Why Do Developers Use Trivial Pack-
iot-nodejs.
ages? An Empirical Case Study on npm. In Foundations of
[8] Koa. https://github.com/koajs/koa. Software Engineering (FSE) (2017).
[9] libuv. https://github.com/libuv/libuv. [38] A BLIZ , M. Internet Denial of Service Attacks and Defense
[10] Lokijs. https://github.com/techfort/LokiJS. Mechanisms. Tech. rep., 2011.
[11] Mozilla developer network: Javascript. https://developer. [39] A LIMADADI , S., M ESBAH , A., AND PATTABIRAMAN , K. Un-
mozilla.org/en-US/docs/Web/JavaScript. derstanding Asynchronous Interactions in Full-Stack JavaScript.
ICSE (2016).
[12] Node-oniguruma regexp library. https://github.com/
atom/node-oniguruma. [40] A RZT, S., R ASTHOFER , S., F RITZ , C., B ODDEN , E., BAR -
TEL , A., K LEIN , J., L E T RAON , Y., O CTEAU , D., AND M C -
[13] Node.js. http://nodejs.org/.
DANIEL , P. Flowdroid: Precise context, flow, field, object-
[14] Nodejs async hooks. https://nodejs.org/api/async_ sensitive and lifecycle-aware taint analysis for android apps. In
hooks.html. PLDI (2014).
[15] Node.js developer guides. https://nodejs.org/en/docs/ [41] BARRERA , D., K AYACIK , H. G., VAN O ORSCHOT, P. C.,
guides/. AND S OMAYAJI , A. A methodology for empirical analysis of
[16] Node.js foundation members. https://foundation. permission-based security models and its application to android.
nodejs.org/about/members. In CCS (2010).
[17] Node.js thread pool documentation. http://docs.libuv. [42] B URNIM , J., JALBERT, N., S TERGIOU , C., AND S EN , K.
org/en/v1.x/threadpool.html. Looper: Lightweight detection of infinite loops at runtime. In
International Conference on Automated Software Engineering
[18] Node.js usage: Statistics for websites using node.js tech-
(ASE) (2009).
nologies. https://trends.builtwith.com/framework/
node.js. [43] B URNIM , J., J UVEKAR , S., AND S EN , K. WISE: Automated
Test Generation for Worst-Case Complexity. In International
[19] Node.js v8.9.1 documentation. https://nodejs.org/dist/
Conference on Software Engineering (ICSE) (2009).
latest-v8.x/docs/api/.
[20] Regex.matchtimeout property. https://msdn. [44] C ASCIARO , M. Node.js Design Patterns, 1 ed. 2014.
microsoft.com/en-us/library/system.text. [45] C HADHA , G., M AHLKE , S., AND NARAYANASAMY, S. Ac-
regularexpressions.regex.matchtimeout. celerating Asynchronous Programs Through Event Sneak Peek.
[21] restify. https://github.com/restify/node-restify. In International Symposium on Computer Architecture (ISCA)
(2015).
[22] sails. https://github.com/balderdashy/sails.
[46] C HANG , R., J IANG , G., I VAN ČI Ć , F., S ANKARANARAYANAN ,
[23] Snyk.io. https://snyk.io/vuln/. S., AND S HMATIKOV, V. Inputs of coma: Static detection of
[24] three.js. https://github.com/mrdoob/three.js. denial-of-service vulnerabilities. In IEEE Computer Security
Foundations Symposium (CSF) (2009).
[25] Twisted. https://twistedmatrix.com/trac/.
[26] Vert.x. http://vertx.io/. [47] C ORRY, E., H ANSEN , C. P., AND N IELSEN , L. R. H. Irregexp,
Google Chrome’s New Regexp Implementation, 2009.
[27] webtorrent. https://github.com/webtorrent/
webtorrent.

14
[48] C OX , R. Regular Expression Matching Can Be Simple And [69] K IRRAGE , J., R ATHNAYAKE , A., AND T HIELECKE , H. Static
Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...), 2007. Analysis for Regular Expression Denial-of-Service Attacks.
[49] C ROSBY, S. Denial of service through regular expressions. Network and System Security 7873 (2013), 35–148.
USENIX Security work in progress report (2003). [70] L EKIES , S., S TOCK , B., AND J OHNS , M. 25 million flows
[50] C ROSBY, S. A., AND WALLACH , D. S. Denial of Service via later: Large-scale detection of dom-based xss. In CCS (2013).
Algorithmic Complexity Attacks. In USENIX Security (2003). [71] L IN , Y., R ADOI , C., AND D IG , D. Retrofitting Concurrency
[51] DAVIS , J., K ILDOW, G., AND L EE , D. The Case of the Poi- for Android Applications through Refactoring. In ACM Inter-
soned Event Handler: Weaknesses in the Node.js Event-Driven national Symposium on Foundations of Software Engineering
Architecture. In European Workshop on Systems Security (Eu- (FSE) (2014).
roSec) (2017). [72] L IU , Y., X U , C., AND C HEUNG , S.-C. Characterizing and
[52] DAVIS , J., T HEKUMPARAMPIL , A., AND L EE , D. Node.fz: detecting performance bugs for smartphone applications. In In-
Fuzzing the Server-Side Event-Driven Architecture. In Euro- ternational Conference on Software Engineering (ICSE) (2014).
pean Conference on Computer Systems (EuroSys) (2017). [73] M ADSEN , M., T IP, F., AND L HOTAK , O. Static analysis of
[53] D E G ROEF, W., D EVRIESE , D., N IKIFORAKIS , N., AND event-driven Node. js JavaScript applications. In ACM SIG-
P IESSENS , F. Flowfox: A web browser with flexible and precise PLAN International Conference on Object-Oriented Program-
information flow control. CCS. ming, Systems, Languages, and Applications (OOPSLA) (2015),
ACM.
[54] D E G ROEF, W., M ASSACCI , F., AND P IESSENS , F. Node-
Sentry: Least-privilege library integration for server-side [74] M CILROY, M. D. Killer adversary for quicksort. Software -
JavaScript. In Annual Computer Security Applications Confer- Practice and Experience 29, 4 (1999), 341–344.
ence (ACSAC) (2014). [75] N IKIFORAKIS , N., I NVERNIZZI , L., K APRAVELOS , A.,
[55] D E B ILL , E. Module counts. http://www.modulecounts. VAN ACKER , S., J OOSEN , W., K RUEGEL , C., P IESSENS , F.,
com/. AND V IGNA , G. You are what you include: Large-scale evalu-
ation of remote javascript inclusions. In CCS (2012).
[56] D ESAI , A., G UPTA , V., JACKSON , E., Q ADEER , S., R A -
JAMANI , S., AND Z UFFEREY, D. P: Safe asynchronous [76] O’D ELL , J. Exclusive: How LinkedIn used Node.js and
event-driven programming. In ACM SIGPLAN Conference on HTML5 to build a better, faster app, 2011.
Programming Language Design and Implementation (PLDI) [77] O’D ELL , J. Exclusive: How LinkedIn used Node.js and
(2013). HTML5 to build a better, faster app, 2011.
[57] E NCK , W., O CTEAU , D., M C DANIEL , P., AND C HAUDHURI , [78] O JAMAA , A., AND D UUNA , K. Assessing the security of
S. A study of android application security. In USENIX Security Node.js platform. In 7th International Conference for Internet
(2011). Technology and Secured Transactions (ICITST) (2012).
[58] E NCK , W., O NGTANG , M., AND M C DANIEL , P. Understand- [79] O LIVO , O., D ILLIG , I., AND L IN , C. Detecting and Exploiting
ing android security. IEEE Security and Privacy (2009). Second Order Denial-of-Service Vulnerabilities in Web Appli-
[59] F ENG , Y., A NAND , S., D ILLIG , I., AND A IKEN , A. cations. ACM Conference on Computer and Communications
Apposcopy: Semantics-based detection of android malware Security (CCS) (2015).
through static analysis. In FSE (2014). [80] O LIVO , O., D ILLIG , I., AND L IN , C. Static Detection of
[60] F ERG , S. Event-driven programming: introduction, tutorial, Asymptotic Performance Bugs in Collection Traversals. PLDI
history. 2006. (2015).
[61] F REES , S. C++ and Node.js Integration. 2016. [81] PADMANABHAN , S. How We Built
eBay’s First Node.js Application. https:
[62] G OLDSMITH , S. F., A IKEN , A. S., AND W ILKERSON , D. S. //www.ebayinc.com/stories/blogs/tech/
Measuring Empirical Computational Complexity. In Founda- how-we-built-ebays-first-node-js-application/,
tions of Software Engineering (FSE) (2007). 2013.
[63] G OOGLE. Chrome v8: Google’s high performance, open [82] PADMANABHAN , S. How We Built eBays First Node.js Appli-
source, javascript engine. https://developers.google. cation, 2013.
com/v8/.
[83] PAI , V. S., D RUSCHEL , P., AND Z WAENEPOEL , W. Flash: An
[64] G ORDON , M. I., K IM , D., P ERKINS , J., G ILHAMY, L., Efficient and Portable Web Server. In USENIX Annual Technical
N GUYENZ , N., , AND R INARD , M. Information flow analy- Conference (ATC) (1999).
sis of android applications in droidsafe. In NDSS (2015).
[84] PARIAG , D., B RECHT, T., H ARJI , A., B UHR , P., S HUKLA ,
[65] G ULWANI , S., M EHRA , K. K., AND C HILIMBI , T. SPEED: A., AND C HERITON , D. R. Comparing the performance of
Precise and Efficient Static Estimation of Program Computa- web server architectures. In European Conference on Computer
tional Complexity. In Principles of Programming Languages Systems (EuroSys) (2007), ACM.
(POPL) (2009).
[85] P ETER , S., BAUMANN , A., ROSCOE , T., BARHAM , P., AND
[66] H ARRELL , J. Node.js at PayPal. https:
I SAACS , R. 30 seconds is not enough! In European Conference
//www.paypal-engineering.com/2013/11/22/
on Computer Systems (EuroSys) (2008).
node-js-at-paypal/, 2013.
[86] P ETSIOS , T., Z HAO , J., K EROMYTIS , A. D., AND JANA , S.
[67] H EUSER , S., NADKARNI , A., E NCK , W., AND S ADEGHI , A.-
SlowFuzz: Automated Domain-Independent Detection of Algo-
R. Asm: A programmable interface for extending android secu-
rithmic Complexity Vulnerabilities. In Computer and Commu-
rity. In Proceedings of the 23rd USENIX Conference on Security
nications Security (CCS) (2017).
Symposium (2014), SEC’14.
[87] P USCHNER , P. P., AND KOZA , C. Calculating the Maximum
[68] J IN , X., H U , X., Y ING , K., D U , W., Y IN , H., AND P ERI ,
Execution Time of Real-Time Programs. Real-Time Systems 1,
G. N. Code injection attacks on html5-based mobile apps:
2 (1989), 159–176.
Characterization, detection and mitigation. In CCS (2014).

15
[88] R ATHNAYAKE , A., AND T HIELECKE , H. Static Analysis [95] S TAICU , C.-A., P RADEL , M., AND L IVSHITS , B. Understand-
for Regular Expression Exponential Runtime via Substructural ing and Automatically Preventing Injection Attacks on Node.js.
Logics. CoRR (2014). Tech. rep., 2016.
[89] R AYMOND , E. S. The Cathedral and the Bazaar. No. July [96] S ULLIVAN , B. Security Briefs - Regular Expression Denial of
1997. 2000. Service Attacks and Defenses. Tech. rep., 2010.
[90] ROICHMAN , A., AND W EIDMAN , A. VAC - ReDoS: Regular [97] VAN D ER M ERWE , B., W EIDEMAN , N., AND B ERGLUND , M.
Expression Denial Of Service. Open Web Application Security Turning Evil Regexes Harmless. In SAICSIT (2017).
Project (OWASP) (2009).
[98] WANDSCHNEIDER , M. Learning Node.js: A Hands-on Guide
[91] S ILBERSCHATZ , A., G ALVIN , P. B., AND G AGNE , G. Oper- to Building Web Applications in JavaScript. Pearson Education,
ating System Concepts, 9th ed. Wiley Publishing, 2012. 2013.
[92] S MITH , R., E STAN , C., AND J HA , S. Backtracking Algorith-
[99] W EI , F., ROY, S., O U , X., AND ROBBY. Amandroid: A precise
mic Complexity Attacks Against a NIDS. In ACSAC (2006),
and general inter-component data flow analysis framework for
pp. 89–98.
security vetting of android apps. In Proceedings of the 2014
[93] S ON , S., AND S HMATIKOV, V. SAFERPHP Finding Seman- ACM SIGSAC Conference on Computer and Communications
tic Vulnerabilities in PHP Applications. In Workshop on Pro- Security (2014), CCS ’14.
gramming Languages and Analysis for Security (PLAS) (2011),
[100] W ELSH , M., C ULLER , D., AND B REWER , E. SEDA : An
pp. 1–13.
Architecture for Well-Conditioned, Scalable Internet Services.
[94] S TAICU , C.-A., P RADEL , M., AND DARMSTADT, T. Freezing In Symposium on Operating Systems Principles (SOSP) (2001).
the Web: A Study of ReDoS Vulnerabilities in JavaScript-based
Web Servers.

16

Вам также может понравиться