Code Injection

Overview

Instead of random injection attempts, build payload gradually based on knowledge to track how it looks when reaching the target function.


The onError String

`throw({message: 'The input "${text}" contains the following invalid characters: [${text.match(
  /['"`;]/g
)}]', statusCode: 403})`

With text = ";"

throw {
  message: 'The input ";" contains the following invalid characters: [;]',
  statusCode: 403,
};

Injection Points

Point
Location
Usability

1

"${text}"

βœ… Entire input placed

2

[${text.match(...)}]

❌ Only match output

Best target: First injection point "${text}"


Building the Payload

Step 1: Escape the String

String starts with 'The..., so use single quote to escape:

❌ Broken syntax - will crash

Step 2: Comment Out Rest

Add // to comment out remaining code:

❌ Still broken - uneven parentheses

Step 3: Close Parentheses/Braces

Close the opening ({:

βœ… Valid JavaScript!

Payload so far: '})//'


Three Rules for Injection

Rule
Description

1. Comment out

Use // to ignore rest of code

2. Even quotes/parens

Close all opened {, (, ', "

3. No syntax errors

Ensure code runs without crashing

Handling Syntax Errors

If function expects variables:

If multi-line string:

JSON Escaping

Remember to escape double quotes in JSON body:


Code Injection Attempt

Payload

Expected Result

Send Request

Response:

Check Console

Debug Console (CMD/CTRL+SHIFT+Y)... Nothing logged! ❌


Debugging the Failure

Set Breakpoint

Line 9 on eval(onError) β†’ Inspect onError value

Copy Value

As Executed Code

Code looks correct... so why didn't it work?

The Problem: throw Statement

In VSCode, the injected code appears transparent = code never reached!

Reason: throw statement stops execution immediately!


The Fix: Same Line Execution

Problem

; creates new line β†’ code after throw never runs

Solution

Use + instead of ; to chain expressions on same line

New Payload

Result


Working Payload Analysis

Payload

Part
Purpose

'

Close the string

}

Close the object

)

Close throw()

+

Chain expression (same line)

console.log('pwned')

Injected code

//

Comment out rest

As Executed


Updated Checklist

#
Step
Status

1

Hit the validateString function

βœ…

2

Trace how input looks within function

βœ…

3

Obtain an admin role

βœ…

4

Confirm we reach the eval function

βœ…

5

Prepare the payload

βœ…

6

Confirm payload reaches target as intended

βœ…

7

Inject code and confirm injection

βœ…

8

Reach command execution or file writing

⏳

9

Blindly verify command execution/file writing

⏳

10

Automate exploitation (write exploit)

⏳


Key Lessons Learned

1. Build Payload Gradually

Don't guess - construct based on knowledge of the code.

2. Understand JavaScript Execution

  • throw stops execution

  • ; creates new line

  • + chains on same line

3. Debug When Stuck

  • Set breakpoints

  • Inspect variable values

  • Check if code is reachable

4. VSCode Hints

Transparent/dimmed code = unreachable code

5. JSON Escaping

Always escape " in JSON payloads: \"


Summary

Issue
Solution

Breaking syntax

Close all quotes/parens

Dangling code

Comment with //

Code after throw

Use + instead of ;

JSON breaking

Escape double quotes

Next: Turn code injection β†’ command execution (RCE)

Last updated