Bringing Binary Exploitation at Port 80: Understanding C
Vulnerabilities in WebAssembly
Emmanuele Massidda
a
, Lorenzo Pisu
b
, Davide Maiorca
c
and Giorgio Giacinto
d
Department of Electronic and Computer Engineering, University of Cagliari, Italy
Keywords:
Web Assembly, Wasm, Software Security, Web Security.
Abstract:
WebAssembly (Wasm) has emerged as a novel approach for integrating binaries into web applications start-
ing from various programming languages such as C, Rust and Python. Despite the numerous claims about
its memory safety, issues such as buffer overflow, format strings, use after free, and integer overflow have
resurfaced within Wasm. These vulnerabilities can be used to impact web application security, potentially
leading to critical issues like Cross-Site Scripting (XSS) and Remote Code Execution (RCE). Our work aims
to demonstrate how memory-related vulnerabilities in C codes, when compiled into Wasm, can be exploited
for XSS and RCE. Our methodology proposes proof of concepts related to exploiting important stack- and
heap-based vulnerabilities. In particular, we demonstrate for the first time that specific vulnerabilities (such as
format string) can be effectively employed to achieve arbitrary read and write in Wasm contexts. Our results
pose serious concerns about the reliability of Wasm in terms of memory safety, which we believe should be
addressed in the next releases.
1 INTRODUCTION
Presenting itself as a fast, efficient, and safe new bi-
nary instruction format, WebAssembly (Wasm) found
its way into the realm of web applications, enabling
developers to build performance-oriented websites
that run binary code directly in the browser. We-
bAssembly allows using languages such as C/C++,
C#, and Rust to be compiled into Wasm to run on
the web (Wang, 2021; Jazayeri, 2007; Ray, 2023).
This allows developers to recompile existing code for
use in their web applications, enhancing re-usability
and efficiency. This technology has already been
implemented in many commercial products, includ-
ing AutoCAD and Figma (Lehmann et al., 2020;
Hilbig et al., 2021), highlighting its growing popu-
larity due to its potential to enhance runtime perfor-
mance (De Macedo et al., 2022; Yan et al., 2021).
Despite its numerous advantages, adopting We-
bAssembly introduces many security challenges, par-
ticularly when porting code written in languages
known for their vulnerability to certain classes of
bugs, such as C (Sti
´
evenart et al., 2022). The pro-
a
https://orcid.org/0009-0003-9190-5648
b
https://orcid.org/0009-0001-0129-1976
c
https://orcid.org/0000-0003-2640-4663
d
https://orcid.org/0000-0002-5759-3017
cess of compiling code to WebAssembly, e.g. us-
ing tools like Emscripten (a compiler that uses Clang
and LLVM (Low-Level Virtual Machine) to compile
to WebAssembly and JavaScript (Zakai, 2011)), does
not neutralize the vulnerabilities within the new run-
time environment. On the contrary, their exploita-
tion may create a dangerous link between traditional
binary exploitation and contemporary web exploita-
tion tactics. The risk is amplified by WebAssembly’s
and Emscripten’s lack of built-in security features
like Address Space Layout Randomization (ASLR)
or stack canaries, which are commonly employed
in compilers for traditional binaries. Although Em-
scripten generates standard compile-time error warn-
ings similar to those of traditional compilers, it does
not detect many vulnerabilities that only emerge dur-
ing runtime, exposing WebAssembly to a wider range
of exploits.
Our work investigates how vulnerabilities typi-
cal of memory-unsafe languages (like C) manifest
within WebAssembly applications when compiled us-
ing Emscripten. Specifically, we focus on stack and
heap-based vulnerabilities whose exploitation may
lead to obtaining complete control of the target server.
We propose proof of concepts that exploit the char-
acteristics of Wasm to manipulate the program flow
even in unexpected ways. We explain how these vul-
552
Massidda, E., Pisu, L., Maiorca, D. and Giacinto, G.
Bringing Binary Exploitation at Port 80: Understanding C Vulnerabilities in WebAssembly.
DOI: 10.5220/0012852400003767
Paper published under CC license (CC BY-NC-ND 4.0)
In Proceedings of the 21st International Conference on Security and Cryptography (SECRYPT 2024), pages 552-559
ISBN: 978-989-758-709-2; ISSN: 2184-7711
Proceedings Copyright © 2024 by SCITEPRESS Science and Technology Publications, Lda.
nerabilities can simplify traditional Web exploitation
techniques, such as Cross-Site Scripting (XSS) and
Remote Code Execution (RCE).
The main contributions of our paper can be sum-
marized as follows:
- Providing a structured presentation of Wasm vul-
nerabilities by systematically categorizing and de-
tailing them, also illustrating their potential to in-
troduce risks on both the client and server sides.
- Providing a clear and reproducible methodology
for better understanding the security aspects of
Wasm and offering a more organized and cohesive
analysis that leads to exploiting previously unex-
plored vulnerabilities (e.g., Format Strings).
- Analyzing six Wasm vulnerabilities, namely
Buffer Overflow (BOF), Format string, Use After
Free (UAF), Integer Overflow, Improper Valida-
tion of Array Index and Redirecting Indirect Calls,
and develop the related Proof of Concepts (PoC)
that allow to achieve arbitrary read and write. In
particular, we also show how exploiting these vul-
nerabilities can lead to web-related attacks such as
XSS and RCE.
To facilitate the understanding and replication of
our findings and furnish a practical resource for fur-
ther research, we have made the source code for all
PoCs available on GitHub (Massidda, 2024). We be-
lieve that our work poses major concerns to Wasm
security, and we hope it can inspire possible improve-
ments in its next releases.
2 BACKGROUND
WebAssembly is a binary instruction format for a
stack-based virtual machine designed for efficient ex-
ecution on web browsers (Haas et al., 2017). It pro-
vides a portable compilation target for high-level lan-
guages like C, C++, and Rust, allowing developers
to run their code in a web environment with near-
native performance. Wasm is designed to run along-
side JavaScript, allowing developers to leverage both
languages in a single web application and combining
the performance benefits of WebAssembly with the
flexibility of JavaScript. A WebAssembly implemen-
tation is usually embedded into a host environment
(embedder), which specifies how modules are loaded,
how imports are supplied (including definitions on the
host side), and how exports can be utilized.
WebAssembly has two concrete representations:
the binary format and the more human-readable text
format, called ”wat”. Both representations map to a
common structure, described in the form of an ab-
stract syntax.
The text representation of Wasm binaries (wat)
can be visualized directly from the browser, which
facilitates and speeds up the reverse engineering and
debugging processes.
1 ( module
2 ( fu nc $ mai n
3 i 3 2 . c o n s t 7 ; ; Push t h e numb er 7 on t h e s t a c k
4 i 3 2 . c o n s t 3 ; ; Push t h e numb er 3 on t h e s t a c k
5 i 3 2 . add ; ; Adds t h e two numbers , l e a v i n g 10 on
t h e s t a c k
6 drop ; ; Remove t h e v al u e a t t h e t o p o f t h e s t a c k
7 )
8 ( s t a r t $m ain )
9 )
Listing 1: WebAssembly function - wat format.
Listing 1, showcases the code snippet of a simple
Wasm function that pushes two values on the stack
and sums them up, subsequently removing the result
from the stack.
3 RELATED WORKS
Two main works explore C attacks in Wasm present-
ing PoCs. One (Lehmann et al., 2020), in which the
authors identify three situations from which an attack
within a Wasm module can be constructed: obtaining
a write primitive, overwriting data, and triggering un-
expected behaviour. Another (McFadden et al., 2018)
offers a broader view of the potential risks of com-
piling code from memory-unsafe languages to We-
bAssembly.
An attack that has not yet been explored thor-
oughly in current works is format strings. Lehmann
et al. briefly mention this issue, whereas McFadden
et al. offer a PoC demonstrating successful exploita-
tion to leak data from the stack. Despite this success,
their attempts to achieve a write primitive were unsuc-
cessful due to JavaScript raising an exception, high-
lighting the need to explore its exploitation process.
In Subsection 4.2, we provide a PoC showing how to
successfully exploit this vulnerability to obtain arbi-
trary writing in linear memory.
Current works also highlight two critical security
problems of WebAssembly modules, which can sim-
plify the exploitation process compared to traditional
architectures. Firstly, the entirely deterministic ap-
proach to memory allocation, specifically the absence
of Address Space Layout Randomization (ASLR),
significantly simplifies the process of executing tar-
geted modifications to data in the heap. Therefore,
even a linear stack-based overflow, if long enough,
can lead to data corruption in the heap. Secondly,
Bringing Binary Exploitation at Port 80: Understanding C Vulnerabilities in WebAssembly
553
WebAssembly has no mechanism that makes data im-
mutable in linear memory, making ”constant” data
possibly modifiable, including non-scalar constants
and string literals.
Many other attacks are described in the papers
above, such as Integer Overflow, Stack Overflow,
Heap Metadata Corruption, redirecting indirect calls,
injecting code into the host environment, or overwrit-
ing application-specific data. We encourage the read-
ers to delve into the aforementioned papers to gain a
comprehensive understanding of these vulnerabilities.
4 METHODOLOGY
In this section, we will describe our methodology to
create vulnerable code for various C vulnerabilities
and their subsequent exploitation.
Table 1: Overview of Proof of Concepts implemented. The
headings are Client-Side (CS), Server-Side (SS), Data Leak
(DL), Data OVerwrite (DO), Unexpected Behaviour (UB).
The first column has Buffer Overflow (BOF), Format String
(FS), Use After Free (UAF), Improper Array Index Vali-
dation (IAIV), Integer OVerflow (IO), Redirecting Indirect
Calls (RIC).
Vulnerability CS SS DL DO UB
BOF XSS - - -
BOF RCE - - -
FS -
FS XSS - -
UAF - - -
IAIV - - -
IO - - -
RIC - -
4.1 Buffer Overflow
The objective of this PoC was to build an application
vulnerable to a stack-based buffer overflow (BOF),
enabling an attacker to gain an out-of-bounds write
primitive and perform an XSS or RCE attack. The ap-
plication asks the user for input, handling it in an un-
safe way that introduces the buffer overflow vulnera-
bility. Furthermore, the user’s input is used inside the
function EM ASM(), which allows embedding inline
JavaScript Code inside the C language. This function
can pave the way to new security issues, especially
if combined with the eval function. If an attacker
manages to gain control over the arguments passed to
EM ASM() (and therefore to eval) they could poten-
tially inject malicious scripts, leading to XSS on the
client and RCE on the server. Notably, the impact of
RCE is even more critical, allowing an attacker to in-
ject arbitrary code to execute on the server.
4.1.1 Proof of Concept Overview
The PoC features an input field that requests the user’s
name. This input is subsequently passed to a C func-
tion called greetings, detailed below:
Listing 2: greetings Function - PoC for buffer overflow
v o id g r e e t i n g s ( c ha r
*
name ) {
c h a r s ys c md [ 7 0 ] = document . w r i t e (< h1>Welcome t o
WebAssembly !< / h1 >’) ” ;
c h a r g r e e t [ 2 0 ] ;
s t r n c p y ( g r e e t , name , s t r l e n ( name ) ) ;
EM ASM( {
e v a l ( UT F8 To String ( $0 ) ) ;
do cu me nt . w r i t e (”<h2>H ell o , + UTF8ToStrin g ( $1 ) +
</h2 >”) ;
} , sy s cmd , g r e e t ) ;
}
This function uses strncpy to copy user input
to a buffer named greet on the stack. Stack-based
buffer overflow occurs because the input length is
used as strncpys third parameter, potentially over-
writing adjacent memory if the input exceeds the
buffer size. The function doesn’t limit copied charac-
ters to the greet buffer size. Another string, sys cmd,
stores JavaScript code passed to EM ASM(). Over-
writing sys cmd allows an attacker to inject arbi-
trary JavaScript code, possibly performing a Cross-
Site Scripting attack. For the RCE BOF, the applica-
tion has the same structure. There are only two dif-
ferences from the client-side PoC: sys cmd calls the
console.log function instead of document.write,
and the same happens inside the call to EM ASM.
4.1.2 Exploitation
Our attack strategy focused on finding the length of
the buffer and then overwriting the content of the
variable sys cmd, the argument of the eval function.
Supposing we are an attacker that does not have
access to the buffer length, we can send a long
sequence of characters (e.g., the 40 characters string
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaa)
with the aim of triggering an error that will reveal the
size of our buffer. The previous sequence will trigger
a iaaajaaa is not defined error, confirming
that the first 32 characters had filled greet and the
following 8 overwritten sys cmd.
With this information, it’s possible to craft a pay-
load consisting of a 32-character sequence followed
by JavaScript code to inject and execute. The pay-
load below injects the code alert(’XSS!’) inside
the WebAssembly module, triggering its execution:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAal e rt ( ’
XSS!’);
SECRYPT 2024 - 21st International Conference on Security and Cryptography
554
An essential observation regarding this vulnera-
bility is that stack-based buffer overflows can also
compromise data in the heap, requiring just a slightly
larger payload depending on the size and the mod-
ule’s structure. This aspect makes attacks more feasi-
ble compared to the more complex scenarios in tradi-
tional x86-64 architectures.
In a similar manner, we can craft a payload that
exploits a buffer overflow on a server-side application
with a payload such as AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAconst{execSync}=require(’child p ro
cess’);console.log(execSync(’ls’).toStrin
g());//. In this case we execute the ls command
as a simple proof of concept. The choice of ls was
purely illustrative, meant to highlight the potential for
executing arbitrary system commands through the ex-
ploited vulnerability.
4.2 Format String Vulnerability
This section showcases two Proofs of Concept high-
lighting the risks associated with the format string
vulnerability in WebAssembly, both in client-side
and server-side environments. Additionally, we com-
pare the differences between the two versions of Em-
scripten employed, finding important distinctions in
the memory’s structure, which led to the creation of
two distinct payloads, one for each version. The for-
mat string vulnerability is introduced by bad coding
practices, where the user’s input is passed directly
to the printf function, like p rintf(user buffer
) instead of printf("%s",user buffer). If an at-
tacker injects format specifiers like %p or %x inside the
buffer, the printf function will print values found on
the stack, starting from the location of the printf
pointer, therefore leaking data from memory. The
number of values leaked corresponds directly to the
number of format specifiers provided by the attacker.
In addition, there exists a format specifier (%n) that, if
leveraged, can give attackers arbitrary write to mem-
ory. The intended usage of this format specifier is to
write the number of characters printed so far on the
standard output into a variable. However, if a variable
is not provided, the printf function will write such
value into a memory address placed at a specific stack
offset starting from the printf pointer. To direct this
write operation to a particular offset x”, the %x$n
syntax comes into play. For instance, a payload like
ABC%3$n would write the value 0x3 (i.e. the length
of ”ABC”) to the address contained in the third ele-
ment from the stack starting from the printf pointer
if such address is valid. Figure 1 showcases this sce-
nario.
Figure 1: Example of writing data in memory using %n.
4.2.1 Proof of Concept Overview
The application (the PoC code can be found on our
repository) displays an input field that asks the user
for a password, which is then passed as an argu-
ment to a function named check password, where it
is compared with the correct password stored in the
stack. If the user inserts the wrong password, then
the program exposes itself to a format string vulner-
ability by directly passing the user’s input (pass) to
the printf function (printf(pass)). When a We-
bAssembly code that is compiled from C calls the
printf function, it automatically redirects this output
to the console.log function in JavaScript, allowing
us to see the output.
This PoC aims to create an exploit using the for-
mat string vulnerability, overwriting the password
stored in the stack. Specifically, we aim to over-
write the current password (”supersecretpassword”)
with the letter ”B”. Our experiments were conducted
using Emscripten version 3.1.6 on the client-side ap-
plication and Emscripten 3.1.52 on the server-side ap-
plication (Node.js).
4.2.2 Exploitation
We initiated the client-side exploitation focusing on
leaking data from memory. By crafting a payload
filled with %p format specifiers, each separated by the
| character for readability. As Figure 2 shows, the
browser’s console leaked stack values, among which
we find we find the correct password, represented in
hexadecimal.
Figure 2: Format String - Arbitrary Read (the highlighted
values are the hex representation of the password).
Using the WebAssembly Binary Toolkit (WABT),
we converted our WebAssembly module into the
Bringing Binary Exploitation at Port 80: Understanding C Vulnerabilities in WebAssembly
555
WebAssembly Text (WAT) format through the
wasm2wat tool. This conversion allowed us to ex-
amine the internal memory layout of the module, dis-
covering that the password was stored at the mem-
ory offset 1024. The next phase of our attack strat-
egy focused on obtaining a write primitive, achiev-
able through the format specifier %n. To overwrite the
password at the address 1024, we first need to store
the value 0x400 (1024 in hexadecimal) into a known
offset from the printf pointer. To achieve that, we
craft a payload composed of 1024 characters followed
by %2$n|%p|: given that the offset 2 initially con-
tains the value 0 (Figure 2), this payload will write
the value 0x400 at address 0.
The final step involved writing the ASCII value of
”B” (0x42 in hexadecimal or 66 in decimal) to ad-
dress 1024. This is achieved with a payload formed
by a 66-character sequence followed by %n, thereby
writing 0x42 to the address found at the first offset
(which is 1024), effectively overwriting the password
with the letter ”B”.
After executing this attack and deploying the crafted
payloads, we can bypass the password check by sub-
mitting the character ”B”.
The exploitation process for the server-side appli-
cation is similar to the client-side, with two key dif-
ferences. Firstly, the output of the printf function
is shown on the server console, not in the browser.
This prevents attackers from directly leaking stack
data or accessing the WebAssembly module to locate
the password’s offset. However, overwriting memory
is still possible, and attackers could perform a ”blind”
attack to find the correct offset via brute force. The
second difference is related to the Emscripten version
used. To run a Node.js application that loads Wasm
modules, we needed to upgrade to Emscripten release
3.1.52. After recompiling the C code and converting
the Wasm module to the readable WAT format, we ob-
served a significant shift in the password’s offset from
1024 to 65536, requiring a much larger payload for an
attack.
This information enabled us to craft a payload ca-
pable of writing the value 65536 (0x10000 in hex-
adecimal) into the first offset, allowing us to overwrite
the password at the correct offset. Given the substan-
tial size of this payload, an attacker might encounter
buffer size constraints. A workaround for this issue
involves using the format specifier %65536c, which
prints the specified amount of characters without ex-
ceeding buffer limits.
Contrary to previous works (McFadden et al.,
2018), we successfully exploited the format string
vulnerability within the WebAssembly environment,
managing to overwrite sensitive data in memory. The
predictability of memory address locations in We-
bAssembly, due to the lack of Address Space Lay-
out Randomization (ASLR), considerably facilitates
the exploitation process. In contrast, exploiting envi-
ronments with ASLR is more challenging due to the
randomized memory addresses. This highlights the
importance of addressing memory layout predictabil-
ity in WebAssembly’s modules.
Moreover, we observed that including the %p spec-
ifier is crucial for the payload %2$n|%p to success-
fully write to memory. Although this payload aims to
write to memory using the %n specifier, the %p speci-
fier, typically used for reading data, appears to be nec-
essary for the write operation to proceed. Omitting
the %p specifier results in the payload failing to write
to memory. The exact reasons behind this remain an
area for further investigation, highlighting an intrigu-
ing aspect of format string vulnerabilities within We-
bAssembly.
4.3 Use after Free
In this PoC, we present a server-side application ex-
hibiting a Use After Free (UAF) vulnerability, high-
lighting the dangers associated with heap manage-
ment errors when developing WebAssembly applica-
tions.
4.3.1 Proof of Concept Overview
Before diving into the details of the front-end side of
the application, we focus on a snippet of the vulnera-
ble C code, which can be seen in Listing 3.
Listing 3: Code of the PoC for the Use After Free vulnera-
bility
t y p e d e f s t r u c t {
c h a r a [ 3 0 ] ;
c h a r f l a g [ 5 ] ;
} o b j e c t ;
o b j e c t
*
x ;
b o ol c h e c k p a s s w o r d ( c h ar
*
p a s s ) {
r e t u r n ( s t r c m p ( p a ss , x−> f l a g ) == 0 ) ;
}
v o id i n i t ( ) {
x = m a l l o c ( s i z e o f ( o b j e c t ) ) ;
s t r n c p y ( x−> f l a g , wasm ” , 5) ;
}
This code snippet defines a structure named ”ob-
ject”, which has a size of 35 bytes. The init func-
tion dynamically allocates memory for an ”object”
instance, storing its address in the variable ”x” and
initializing the ”flag” field with the string ”wasm”.
However, the check password function compares
this ”flag” field with user input, potentially after its
memory has been freed, thereby introducing a Use
After Free (UAF) vulnerability into the application.
SECRYPT 2024 - 21st International Conference on Security and Cryptography
556
Additionally, the function free memory is designed
to deallocate the memory assigned to the variable x,
resulting in x becoming a dangling pointer. Mean-
while, the alloc object function allows allocating
heap memory of any specified size using malloc.
4.3.2 Exploitation
This attack aims to modify the existing password by
overwriting the data in the ”flag” field of the ”x” vari-
able. The initial step involves deallocating the heap
chunk allocated for ”x”, by invoking free memory.
Subsequently, a call to malloc requesting a chunk of
a similar size as the one just freed results in allocat-
ing that same memory space, giving us access to the
released memory. To exploit this, we allocate a new
chunk of 35 bytes, identical to the size of ”x”, con-
taining the payload allowing us to overwrite the pass-
word. We craft a payload composed of a 30-character
sequence that fills the ”a” field buffer, followed by the
string ”pass”, which will be the new password inside
the ”flag” field.
Summarizing, the exploitation process is com-
posed of 3 steps: (i) Free the chunk of ”x”; (ii)
Allocate a 35-byte object containing the payload
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAApass; (iii) Au-
thenticate using the new password ”pass”.
We demonstrated that, if leveraged, this vulnera-
bility can cause damage within the WebAssembly en-
vironment. Depending on the application’s structure,
this vulnerability can introduce many other risks, such
as possible data leaks or memory corruption. Another
common vulnerability in heap memory is the ”Dou-
ble Free”, which we leave for future research within
WebAssembly.
4.4 Improper Array Index Validation
When an application fails to properly check or val-
idate the indices used to access elements within an
array, it can open the way to unauthorized access to
sensitive data, corruption of data, crashes, and execu-
tion of arbitrary code.
4.4.1 Proof of Concept Overview
The application provides users with two functionali-
ties: verifying their entered password and modifying a
character in their password by choosing an index and
a new character. However, the application uses the
provided index to access the user’s password, stored
in heap memory along with the admin password and
another password called unreachable password,
without any checks to ensure the index is within valid
boundaries.
Listing 4: Code snippet of the PoC for Improper Array In-
dex Validation
c h a r u n r e a c h a b l e p a s s w o r d [ 3 0 ] = ” u n r e a c h a b l e p a s s w o rd ” ;
c h a r u s e r p a s s w o r d [ 3 0 ] = ” t h i s i s y o u r p a s s w o r d ;
c h a r a d m i n p a ssw o r d [ 3 0 ] = ” s u p e r s e c r e t p a s s w o r d ;
v o id c h a n g e u s e r p a s s w o r d c h a r a c t e r ( i n t i n dex , c h a r
new c h a r ) {
u s e r p a s s w o r d [ index ] = new char ;
}
Listing 4 displays the code snippet where the three
passwords are allocated in the heap memory, along-
side the function that allows modifying the user’s
password.
4.4.2 Exploitation
Our experiments aimed to access memory indices out-
side the valid range of the user’s password, which is
between 0 and 29, with the intent to overwrite adja-
cent data in memory.
Our initial approach involved accessing indices
greater than 29 to potentially overwrite the admin’s
password stored after the user’s password in mem-
ory. We successfully overwrote the admin’s pass-
word characters starting from index 32. This al-
lowed us to modify the password and log in as ad-
mins. A strategy is to change the character at index
32 to ’A’ and set the next character to a null byte, en-
abling login with just ’A’. The second experiment in-
volved accessing indices below 0, aiming at overwrit-
ing the unreachable password. This experiment
was unsuccessful because accessing negative indices
in WebAssembly will trigger a ”memory access out
of bounds” runtime error. Unlike in languages like C,
where accessing negative indices will not necessarily
lead to a crash in the program, WebAssembly throws
this error to prevent unsafe memory operations.
This PoC highlighted the critical impact of
unchecked index boundaries, which enabled overwrit-
ing sensitive data like the admin’s password. How-
ever, WebAssembly’s protection against negative in-
dex exploitation, marked by the ”memory access out
of bounds” error, is a key security feature. Despite
this, our next Proof of Concept outlines a scenario
that, in a way, bypasses these strict memory access
controls.
4.5 Integer Overflow
In this Proof of Concept, we explore the Integer Over-
flow vulnerability within a WebAssembly applica-
tion. Integer Overflow occurs when an integer vari-
able exceeds the maximum size of the integer type,
causing unexpected behaviour. In most systems, un-
signed integers are represented by 4 bytes (32 bits),
meaning that the maximum representable value is
Bringing Binary Exploitation at Port 80: Understanding C Vulnerabilities in WebAssembly
557
4,294,967,295 (2
32
1). Such value, in the C lan-
guage, is stored within the macro ”INT MAX”. In-
crementing by 1 this maximum value, the integer
overflows and wraps around to 0 due to the limited
number of bits. This PoC aims to demonstrate how
such an overflow can be exploited to compromise the
application’s integrity or security.
4.5.1 Proof of Concept Overview
Listing 5: Code snippet of the PoC for Integer Overflow.
c h a r s u p e r s e c r e t p a s s w o r d [ 5 ] = ” pas s ” ;
c h a r u s e r s [ 5 ] [ 2 0 ] = {
” g u e s t
u s e r ” ,
” gu e s t p a s s w o r d ” ,
admin ” ,
admi n p a s s wor d ”
} ;
c h a r
*
g e t a r r a y e l e m e n t ( i n t i n d e x ) {
p r i n t f ( A c c e s s i n g i n d e x : %d \n ” , i n d e x ) ;
r e t u r n u s e r s [ i n d e x ] ;
}
The C code in Listing 5 initializes a password in heap
memory, followed by an array of ve strings. The
application prompts the user for an index, restraining
the input to values greater than 0 and not equal to 3.
This check is performed inside the Node.js code.
4.5.2 Exploitation
We begin our exploration by providing the value
INT MAX + 1 to the application, causing the integer
variable to overflow and wrap to 0, enabling us to ac-
cess and print the string in the index 0. Subsequently,
we input the number INT MAX + 4, obtaining access
to the ”forbidden” index 3, and printing the content of
the admin’s password. This PoC demonstrates the po-
tential of integer overflow to compromise application
security. This finding underscores the need for rig-
orous boundary checks in WebAssembly application
development. The testing phase of this PoC led to a
notable finding: accessing the array of strings using
a negative index does not trigger the ”memory access
out of bounds” error, allowing the leakage of the pass-
word instantiated before the array of strings.
4.6 Redirecting Indirect Calls
Indirect calls in WebAssembly are used to imple-
ment function pointers and virtual functions. The
call indirect instruction pops a value from the
stack, using it as an index in the table section and in-
voking the specified function if the signature matches.
The last PoC presented in this paper demonstrates
how an attacker could change the normal control flow
of a WebAssembly application by redirecting indirect
calls.
4.6.1 Proof of Concept Overview
Similar to previous PoCs showcased in this paper, this
application prompts the user for a password.
Listing 6: Code of the PoC for Redirecting Indirect Calls -
Server-Side.
b o ol c h e c k p a s s w o r d ( c h ar
*
i n p u t ) {
b o ol (
*
l o g i n h a n d l e r ) ( v o i d ) = 0 ;
c h a r p a s swo r d [ 1 0 ] ;
s t r c p y ( p as swo rd , i n p u t ) ;
i f ( l o g i n h a n d l e r == 0 ) {
i f ( st r c m p ( p as swo rd , ” s e c r e t p a s s ) == 0 )
l o g i n h a n d l e r = ( b o o l (
*
) ( void ) )&a d m i n p a n e l ;
e l s e
l o g i n h a n d l e r = ( b o o l (
*
) ( void ) )&u s e r p a n e l ;
}
r e t u r n l o g i n h a n d l e r ( ) ;
}
Listing 6 illustrates the check password func-
tion in C, highlighting its vulnerability. This function
employs a function pointer named login handler,
which is conditionally set to the address of either the
admin panel or user panel function, based on the
user’s password input. The code introduces a buffer
overflow vulnerability at line 5, caused by using the
strcpy function, which lacks boundary checks.
The conditional assignment of function pointers,
as seen in the code, results in indirect function calls
within the WebAssembly environment.
4.6.2 Exploitation
To redirect the program’s control flow, we ex-
ploited the buffer overflow vulnerability by overwrit-
ing the login handler pointer with the address of
the admin panel function, effectively bypassing the
password verification process.
The payload we designed exploits the buffer over-
flow by starting with ten ”A” characters to fill the
user’s buffer and reach the function pointer, followed
by String.fromCharCode(1). This last byte over-
writes the login handler with ”1”, which is the
address of admin panel, effectively redirecting the
program’s execution to bypass the password check.
Low numerical addresses in WebAssembly, such
as the admin panel function’s address located at ad-
dress 1, increase security risks. Unlike traditional
systems where ASLR complicates the exploiting pro-
cess by randomizing addresses, WebAssembly’s low
and deterministic addresses simplify crafting exploits,
highlighting the need for stronger security measures
in Wasm.
SECRYPT 2024 - 21st International Conference on Security and Cryptography
558
Table 2: Comparison of Vulnerability Coverage between our work and the state of the art.
Lehmann et al. McFadden et al. Our work
Vulnerability Mention Explain PoC Mention Explain PoC Mention Explain PoC
Buffer Overflow (BOF)
Heap Metadata Corruption - - - -
BOF XSS
BOF RCE - - -
Integer Overflow - - -
Format String - -
*
Format String XSS - - - - - -
Format String RCE - - - - - - -
Use After Free - - - -
Double Free - - - - - -
Overwriting Constant Data - - - - - -
Redirecting Indirect Calls - -
Redirecting Indirect Call XSS - - - - - -
Redirecting Indirect Call RCE - - - - - -
Improper Validation of Array Index - - - - - -
*
McFadden et al. provided a PoC for the format string vulnerability without achieving arbitrary writing.
5 CONCLUSIONS
Our findings indicate a crucial need to implement
stronger security measures to protect WebAssembly
applications against potential exploits. Compiling
WebAssembly from memory-unsafe languages like C
introduces many security concerns, possibly enabling
attackers to use traditional binary exploitation tech-
niques to attack web applications. Such attack tech-
niques could significantly impact real-world scenar-
ios, particularly when developers introduce vulner-
abilities by reusing code from other projects with-
out conducting adequate security checks. Future re-
search may focus on the study and development of re-
newed security measures inside WebAssembly com-
pilers, possibly implementing traditional mitigation
techniques such as ASLR or stack canaries. We also
plan to expand our research towards more complex
vulnerabilities and attack strategies and to examine
how WebAssembly security may impact other tech-
nologies.
ACKNOWLEDGEMENTS
This work was partially supported by project SER-
ICS (PE00000014) under the NRRP MUR program.
This work was also supported by project ”SUS-
TAIN - flexible Sensors for secUre and truSTed
crowdsensing environmentAl applicatioNs”, CUP
F25F21002720001 (D.M. 737/2021 - Interdisci-
plinary research initiatives on transversal topics for
PNR). Both projects are funded by the European
Union NextGenerationEU.
REFERENCES
De Macedo, J., Abreu, R., Pereira, R., and Saraiva, J.
(2022). WebAssembly versus JavaScript: Energy and
runtime performance. In 2022 (ICT4S). IEEE.
Haas, A., Rossberg, A., Schuff, D. L., Titzer, B. L., Hol-
man, M., Gohman, D., Wagner, L., Zakai, A., and
Bastien, J. (2017). Bringing the web up to speed with
WebAssembly. In Proceedings of the 38th ACM SIG-
PLAN PLDI. ACM.
Hilbig, A., Lehmann, D., and Pradel, M. (2021). An empir-
ical study of real-world webassembly binaries: Secu-
rity, languages, use cases. In Proceedings of the Web
Conference 2021. ACM.
Jazayeri, M. (2007). Some trends in web application de-
velopment. In Future of Software Engineering (FOSE
’07). IEEE.
Lehmann, D., Kinder, J., and Pradel, M. (2020). Everything
old is new again: Binary security of {WebAssembly}.
Massidda, E. (2024). https://github.com/manumassi/vul
n wasm.
McFadden, B., Lukasiewicz, T., Dileo, J., and Engler, J.
(2018). Security chasms of wasm. NCC Group
Whitepaper.
Ray, P. P. (2023). An overview of webassembly for iot:
Background, tools, state-of-the-art, challenges, and
future directions. Future Internet, 15(8).
Sti
´
evenart, Q., De Roover, C., and Ghafari, M. (2022). Se-
curity risks of porting c programs to webassembly. In
Proceedings of the 37th ACM/SIGAPP SAC. ACM.
Wang, W. (2021). Empowering web applications with
webassembly: Are we there yet? In 2021 36th
IEEE/ACM (ASE). IEEE.
Yan, Y., Tu, T., Zhao, L., Zhou, Y., and Wang, W. (2021).
Understanding the performance of webassembly ap-
plications. In 21st ACM IMC. ACM.
Zakai, A. (2011). Emscripten: an LLVM-to-JavaScript
compiler. In OOPSLA ’11.
Bringing Binary Exploitation at Port 80: Understanding C Vulnerabilities in WebAssembly
559