Eval Injection

Overview

Before exploiting our finding, we need to understand code injection, specifically eval injection in JavaScript.


Code Injection Fundamentals

What is Code Injection?

Attacker uses user input to modify how an application executes by injecting code that becomes part of the application.

Injection Type
What's Affected

SQL Injection

SQL query

Command Injection

System command

Code Injection

Application code

Key Points

  • Only affects interpreted/scripted languages (JavaScript, Python, PHP)

  • Code is dynamically executed at runtime

  • XSS is a form of code injection (client-side)

  • Backend code injection can lead to RCE


Dangerous Functions by Language

Code Injection Functions (Highlighted)

JavaScript (Node.js)
Python
PHP

eval

eval

eval

Function

exec

exec

setInterval

setTimeout

constructor.constructor

Command Injection Functions

JavaScript
Python
PHP
C/C++
C#
Java

child_process.exec

subprocess.open

proc_open

execlp

System.Diagnostics.Process.Start

Runtime.getRuntime().exec

child_process.spawn

subprocess.run

popen

execvp

os.system

shell_exec

ShellExecute

os.popen

passthru

system

system

popen


Eval Injection Basics

Functions That Evaluate Strings as Code

Basic Vulnerable Example

Exploitation

Payload:

Resulting Code:

Executed as:

βœ… Code injection achieved!


Analyzing validateString

How It's Called

The eval Call

Condition Analysis

Role
onError Value
User Input?

Not admin

throw({message: 'Invalid input', statusCode: 403})

❌ None

admin

throw({message: 'The input "${text}" contains...

βœ… ${text} included

Key Insight

Must have role === "admin" to reach code injection!

When role is admin, our text input is placed directly into the eval string via string interpolation (${text}).


String Interpolation in JavaScript

Backtick Strings (Template Literals)

Vulnerability

When user input is interpolated into a string that gets eval()'d:

If text contains code-breaking characters, injection occurs!


Testing the Vulnerability

Setup

  1. Run app in debug mode

  2. Add breakpoint on line 20 (generateQR)

  3. Get auth token

Get Token

Send Payload

Modify Role in Debugger

  1. Breakpoint hits

  2. In VARIABLES pane, change role from user to admin

  3. Press Continue

Response

βœ… We reached the admin branch and got the verbose error message!


What the Payload Does

Payload: ";// `

Character
Purpose

"

Close the string

`

Close the template literal

;

End the statement

//

Comment out rest of line

Resulting eval String

After injection, becomes:


The Filter Problem

validateString Checks

Blocked characters: ', ", `, ;

Challenge

Our injection payload requires these characters to:

  1. Break out of strings (" or ')

  2. End statements (;)

  3. Comment out code (//)

BUT: If input contains these characters, validateString returns false BEFORE eval is called...

Wait, What?

Actually, looking at the logic:

  1. If input has bad chars β†’ eval(onError) is called

  2. onError contains our input via ${text}

  3. So we want to trigger the validation failure!

βœ… The filter helps us reach eval!


Next Steps

  1. Get admin role - How to authenticate as admin?

  2. Bypass character filter - Find payload without ['";]`

  3. Achieve code execution - Execute arbitrary JS

  4. Escalate to RCE - Run system commands


Key Takeaways

  1. eval() is dangerous - Any user input reaching it = vulnerability

  2. Template literals - ${var} interpolation can enable injection

  3. Filters can backfire - Triggering validation = reaching eval

  4. Role matters - Must be admin to get verbose error with our input

  5. Debug to verify - Modify variables to test different code paths

Last updated