In the world of coding, if you don't have the right "swing," you get a Red Card from the server. You are talking about RCE (Remote Code Execution), which is basically like a striker from the other team finding a hole in your defense and running straight to your goalkeeper.
Let me fix the "vibe" for you. Here is the my version.
⚽ Don't Let Attackers Score: Stopping RCE in React Server Components
Look, we are all loving React Server Components (RSCs). It is like the perfect Bachata song—smooth, fast, and everyone is in sync. We fetch data on the server, the client stays light, and everything feels "Like a perfect Bachata flow."
But trust me, my friend, there is a "Cramp" waiting for you. Because RSCs run on the server, we have opened a door. If you are not careful, an attacker can get Remote Code Execution (RCE). That is a CVSS 10.0—basically, the other team just won the World Cup and you are still tying your shoes.
🕺 The Dance Has Changed: The New Pitch
In the "Dark Ages" (JQuery, IE6—don't make me cry), we only worried about the Frontend. XSS was the big enemy. But now? The boundary is moving.
Imagine you are leading a dance. You expect your partner to follow the 1, 2, 3, Tap! rhythm. But if the "partner" (the user input) suddenly does a backflip and kicks the DJ in the face? That is what happens when you trust client data in an RSC.
- The Server is the Pitch: RSCs can touch the file system, the DB, and the OS.
- The Input is the Ball: If you let the attacker control where the ball goes, they will aim for your server's heart.
🚩 The "Red Card" Mistake: Directory Traversal
Look at this code. It looks innocent, like a rookie player. But actually, it is a disaster:
// app/reports/[id]/page.tsx (Server Component)
import { promises as fs } from 'fs';
import path from 'path';
export default async function ReportPage({ params }: { params: { id: string } }) {
// DANGER! This is like leaving your goal empty.
const filePath = path.join(process.cwd(), 'reports', `${params.id}.pdf`);
const data = await fs.readFile(filePath, 'utf-8');
return <div>{data}</div>;
}
What happens?
If an attacker sends id as ../../../../etc/passwd, your server says "Okay!" and hands them the keys to the house. 1, 2, 3, CRASH!
🛡️ How to Play Defense (The my Way)
You cannot play without a strategy. You need a "VAR" for your data—something that checks if the play was legal.
1. Use a "Referee" (Validation)
Use Zod. It is like a referee who doesn't take any nonsense. If the input isn't perfect, he blows the whistle.
import { z } from 'zod';
const IdSchema = z.string().regex(/^[a-z0-9-]+$/); // Only simple letters and numbers!
export default async function ReportPage({ params }: { params: { id: string } }) {
const result = IdSchema.safeParse(params.id);
if (!result.success) {
return <h1>GET OUT! (Invalid ID)</h1>; // Blow the whistle!
}
// Now we play...
}
2. Whitelist, Don't Blacklist
Don't try to guess what the "bad" words are. Just define what "good" looks like. In Football, the ball stays inside the white lines. Period.
3. The "Secret Ingredient": const values
If you have five reports, don't let the user type the name. Let them send a number or a key, then you map it on the server.
👟 Summary of the Tactics
| Concept | The Football/Dance Way | The Code Way |
|---|---|---|
| User Input | A pass from a teammate you don't know |
params or searchParams
|
| Validation | The Referee (VAR) | Zod or Joi |
| RCE | An Own Goal | Executing malicious server code |
| Safe Flow | 1, 2, 3, Tap! | Validate -> Sanitize -> Execute |
💡 Pro Tip from the Pitch
Treat every prop in a Server Component like a suspicious package. Just because it came from a "Client Component" doesn't mean it's safe. An attacker can intercept that "pass" mid-air. Always validate at the server boundary, every single time.
✨ Let's keep the conversation going!
If you found this interesting, I'd love for you to check out more of my work or just drop in to say hello.
✍️ Read more on my blog: bishoy-bishai.github.io
☕ Let's chat on LinkedIn: linkedin.com/in/bishoybishai
📘 Curious about AI?:
You can also check out my book: Surrounded by AI
Top comments (0)