flawopen.com/path-traversal/Csharp

● CWE-918 · उच्च
सुरक्षा अनुसंधान · FlawOpen

सुरक्षा भेद्यता: Path Traversal in C#

How Path.Combine discards root paths in C#, and how to verify boundaries using Path.GetFullPath and StringComparison.OrdinalIgnoreCase.

💡 आसान भाषा में (ELI5)

एक होटल के कमरे के कार्ड रीडर की कल्पना करें जिसे केवल दूसरी मंजिल के कमरे खोलने चाहिए। यदि कोई मेहमान कीपैड पर '../../master-safe' टाइप करता है, तो असुरक्षित ताला हॉलवे से बाहर निकलकर प्रबंधक की तिजोरी खोल देता है।

इस पेज के मुख्य शब्द

Web Application Security
सुरक्षा अवधारणा (Web Application Security): Core architecture component affected by CWE-918.
CWE-918
सुरक्षा अवधारणा (CWE-918): Standard Common Weakness Enumeration classification for path-traversal-csharp.
Defense-in-Depth
सुरक्षा अवधारणा (Defense-in-Depth): Multi-layered engineering verification and runtime boundary isolation.

हमले का चरण-दर-चरण प्रवाह

Step 1

क्लाइंट फ़ाइल पाथ इनपुट

एंडपॉइंट HTTP पैरामीटर के माध्यम से उपयोगकर्ता द्वारा प्रदान किया गया फ़ाइल नाम स्वीकार करता है।

Step 2

डायरेक्टरी ट्रैवर्सल सीक्वेंस इंजेक्शन

हमलावर फ़ाइल नाम में '../' या '..%2f' जैसे रिलेटिव डायरेक्टरी ट्रैवर्सल सीक्वेंस डालता है।

Step 3

फ़ाइल सिस्टम सीमा बाईपास

बैकएंड कैनोनिकल पाथ को सत्यापित किए बिना बेस डायरेक्टरी के साथ पाथ को जोड़ देता है।

Step 4

गोपनीय फ़ाइलों का प्रकटीकरण

सर्वर सिस्टम की संवेदनशील फ़ाइलें (/etc/passwd, पासवर्ड या कुंजियाँ) पढ़कर हमलावर को भेज देता है।

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

✕ कमज़ोर कार्यान्वयन
// VULNERABLE: Path.Combine discards baseFolder if userInput has a leading slash
using System.IO;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class FileController : ControllerBase {
    private readonly string _baseFolder = @"C:\App\Storage\Uploads";

    [HttpGet("download")]
    public IActionResult Download([FromQuery] string file) {
        // If file is "\Windows\System32\cmd.exe", basePath is discarded!
        // If file is "..\..\App.config", it breaks out of the folder
        string targetPath = Path.Combine(_baseFolder, file);

        if (!System.IO.File.Exists(targetPath)) return NotFound();
        return PhysicalFile(targetPath, "application/octet-stream");
    }
}
✓ सुरक्षित और सुदृढ़ फ़िक्स
// HARDENED: Canonicalize path and assert directory prefix containment
using System;
using System.IO;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class FileController : ControllerBase {
    private readonly string _baseFolder;

    public FileController() {
        _baseFolder = Path.GetFullPath(@"C:\App\Storage\Uploads");
    }

    [HttpGet("download")]
    public IActionResult Download([FromQuery] string file) {
        if (string.IsNullOrWhiteSpace(file)) return BadRequest("Invalid filename");

        // 1. Strip leading slashes to prevent Path.Combine root discard
        string cleanName = file.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

        // 2. Resolve canonical full path
        string fullPath = Path.GetFullPath(Path.Combine(_baseFolder, cleanName));

        // 3. Strict boundary containment check with DirectorySeparatorChar
        string safePrefix = _baseFolder.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
        if (!fullPath.StartsWith(safePrefix, StringComparison.OrdinalIgnoreCase)) {
            return Forbid("Path traversal attempt detected");
        }

        if (!System.IO.File.Exists(fullPath)) return NotFound();
        return PhysicalFile(fullPath, "application/octet-stream");
    }
}

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट

References