Skip to content

Commit 08bfcfb

Browse files
Fix critical path traversal vulnerability in sandbox file content API
1 parent 78bbe2d commit 08bfcfb

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

  • app/api/sandbox/[sbxId]/files/content

app/api/sandbox/[sbxId]/files/content/route.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Sandbox } from '@e2b/code-interpreter'
22
import { NextRequest } from 'next/server'
3+
import path from 'path'
34

45
export const maxDuration = 60
56
export const runtime = 'nodejs'
@@ -42,21 +43,27 @@ export async function GET(
4243
// Connect to existing sandbox
4344
const sbx = await Sandbox.connect(sbxId)
4445

45-
// Read file content from sandbox
46-
// Remove leading slash if present and prepend /home/user/
47-
const fullPath = filePath.startsWith('/')
48-
? `/home/user${filePath}`
49-
: `/home/user/${filePath}`
46+
// Sanitize path to prevent path traversal attacks
47+
const userDir = '/home/user'
48+
const normalizedPath = path.normalize(path.join(userDir, filePath))
5049

51-
const result = await sbx.commands.run(`cat "${fullPath}"`)
50+
// Verify the normalized path is still within the allowed directory
51+
if (!normalizedPath.startsWith(userDir + '/') && normalizedPath !== userDir) {
52+
return new Response(
53+
JSON.stringify({ error: 'Access denied: Invalid path' }),
54+
{ status: 403, headers: { 'Content-Type': 'application/json' } }
55+
)
56+
}
57+
58+
const result = await sbx.commands.run(`cat "${normalizedPath}"`)
5259

5360
if (result.exitCode !== 0) {
5461
console.error('Error reading file:', result.stderr)
5562
return new Response(
5663
JSON.stringify({
5764
error: 'Failed to read file',
5865
details: result.stderr,
59-
path: fullPath
66+
path: normalizedPath
6067
}),
6168
{ status: 404, headers: { 'Content-Type': 'application/json' } }
6269
)
@@ -117,12 +124,21 @@ export async function POST(
117124
// Connect to existing sandbox
118125
const sbx = await Sandbox.connect(sbxId)
119126

120-
// Write file content to sandbox
121-
const fullPath = filePath.startsWith('/')
122-
? filePath.substring(1)
123-
: filePath
127+
// Sanitize path to prevent path traversal attacks
128+
const userDir = '/home/user'
129+
const normalizedPath = path.normalize(path.join(userDir, filePath))
130+
131+
// Verify the normalized path is still within the allowed directory
132+
if (!normalizedPath.startsWith(userDir + '/') && normalizedPath !== userDir) {
133+
return new Response(
134+
JSON.stringify({ error: 'Access denied: Invalid path' }),
135+
{ status: 403, headers: { 'Content-Type': 'application/json' } }
136+
)
137+
}
124138

125-
await sbx.files.write(fullPath, content)
139+
// E2B files.write expects path relative to /home/user
140+
const relativePath = normalizedPath.substring(userDir.length + 1)
141+
await sbx.files.write(relativePath, content)
126142

127143
return new Response(
128144
JSON.stringify({

0 commit comments

Comments
 (0)