CVE-2023-3224 - Code Injection Vulnerability in nuxt/nuxt Prior to 3.5.3 – Exploit Explored

CVE-2023-3224 is a critical code injection vulnerability discovered in the open-source Nuxt.js nuxt/nuxt repository, specifically affecting versions prior to 3.5.3. This flaw lets malicious users run arbitrary code on a Nuxt-powered server, potentially leading to full server compromise, data theft, or further attacks. If you haven’t updated Nuxt to version 3.5.3 or above, your project could be at serious risk.

In this post, we'll break down what this vulnerability is, how it can be exploited, and the steps you need to take to protect your application. We'll include code snippets and technical explanations to help you fully understand the issue. All code and insights here are exclusive and crafted to be clear and practical for everyday developers.

Where Was the Bug?

The code injection flaw stemmed from unsafe handling of user-supplied input in server-side rendering and dynamic imports. In Nuxt.js prior to 3.5.3, certain server APIs trusted request parameters without proper sanitization. That meant a bad actor could trick Nuxt into treating raw user data as executable code.

Imagine a route handler like this inside your Nuxt project before 3.5.3

// Server route (vulnerable code)
export default defineEventHandler((event) => {
  const query = getQuery(event)
  // Dangerous! Directly passing user input:
  return eval(query.data) // BAD! This executes whatever is inside query.data
})

If users can access /api/my-route?data=something, whatever is in data will run on your server! An attacker could supply something evil, like process.env, leaking secrets, or worse, require('child_process').exec('rm -rf /'), potentially ruining your day.

The above is a simplified version, but similar logic appeared internally in the framework code, not just in user code.

Exploit Details

This vulnerability was practical to exploit wherever user-supplied input was handled incorrectly. Attackers could send requests to endpoints that would trigger the vulnerable path and execute their payload.

PoC Exploit

Suppose your Nuxt app is running an affected version and exposes an endpoint (e.g. /api/exec). Given a payload like:

GET /api/exec?data=require('child_process').exec('touch /tmp/hacked')

The server-side code (due to improper sanitization) would process this as

eval("require('child_process').exec('touch /tmp/hacked')")

This would create a file named hacked in the /tmp/ directory as proof of code execution.

It gets worse: attackers could fetch environment variables, escalate privileges, or create reverse shells, depending on what dependencies and permissions your server has.

Context Isolation: Making sure imported modules and rendering processes are sandboxed.

You can see the fix and commit history here:  
➡️ Nuxt Commit Closing CVE-2023-3224

Security References

- GitHub Advisory Database: CVE-2023-3224
- Nuxt Security Release Notes (v3.5.3)
- NVD Entry for CVE-2023-3224

How to Stay Safe

Update your Nuxt projects to at least 3.5.3, ideally the latest.

npm install nuxt@latest
# or
yarn add nuxt@latest

Check your codebase for any custom server routes or endpoints where you use eval(), Function(), or other dynamic evaluation methods and ensure you’re never directly passing user input.

Best Practice Example

export default defineEventHandler((event) => {
  const query = getQuery(event)
  // Safe: don't evaluate user data, just return or process
  return { message: 'Data received', value: query.data }
})

Conclusion

CVE-2023-3224 is a real-world reminder that trusting user input—especially in framework code—can open your app up to devastating attacks. If your Nuxt app is on an affected version or if you run older code that dynamically executes content from users, update today.

For more info, check Nuxt's official GitHub repository and security channels. If you have custom server-side code, review it for safe patterns and sanitize all inputs!

Feel free to share this post, and make sure your apps are safe!

Timeline

Published on: 06/13/2023 18:15:00 UTC
Last modified on: 06/20/2023 17:03:00 UTC