VYPR
Moderate severityNVD Advisory· Published Oct 2, 2020· Updated Aug 4, 2024

Arbitrary file read un Vapor

CVE-2020-15230

Description

Vapor FileMiddleware before 4.29.4 allows path traversal via percent-encoded relative paths, enabling arbitrary file read on the host.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Vapor FileMiddleware before 4.29.4 allows path traversal via percent-encoded relative paths, enabling arbitrary file read on the host.

Vulnerability

Overview

CVE-2020-15230 is a path traversal vulnerability in Vapor's FileMiddleware component. The root cause is that FileMiddleware did not properly decode percent-encoded characters before checking for relative path segments. Specifically, sequences like %2e%2e (which decodes to ..) were not recognized as directory traversal attempts, allowing attackers to bypass the intended path restrictions [1][4].

Exploitation

An attacker can exploit this by sending HTTP requests with percent-encoded relative path segments, such as %2e%2e/ or %2e%2e%2f, to any endpoint served by FileMiddleware. No authentication is required if the vulnerable endpoint is publicly accessible. Only applications that explicitly use FileMiddleware are affected [2].

Impact

Successful exploitation allows an attacker to read arbitrary files from the filesystem of the host running the Vapor application. This could expose sensitive information including configuration files, source code, environment variables, or credentials, potentially leading to further compromise [2].

Mitigation

The vulnerability is fixed in Vapor version 4.29.4. Users are strongly advised to upgrade to this version or later. No workaround is documented; the only complete fix is to apply the patch that properly decodes percent-encoded characters before path validation [1][2].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/vapor/vaporSwiftURL
>= 4.0.0-rc.2.5, < 4.29.44.29.4

Affected products

2

Patches

1
cf1651f7ff76

fix relative percent decoding in file middleware (#2500)

https://github.com/vapor/vaporTannerSep 30, 2020via ghsa
3 files changed · +21 3
  • Sources/Vapor/Middleware/FileMiddleware.swift+5 3 modified
    @@ -13,8 +13,10 @@ public final class FileMiddleware: Middleware {
     
         /// See `Middleware`.
         public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
    -        // make a copy of the path
    -        var path = request.url.path
    +        // make a copy of the percent-decoded path
    +        guard var path = request.url.path.removingPercentEncoding else {
    +            return request.eventLoop.makeFailedFuture(Abort(.badRequest))
    +        }
     
             // path must be relative.
             while path.hasPrefix("/") {
    @@ -27,7 +29,7 @@ public final class FileMiddleware: Middleware {
             }
     
             // create absolute file path
    -        let filePath = self.publicDirectory + (path.removingPercentEncoding ?? path)
    +        let filePath = self.publicDirectory + path
     
             // check if file exists and is not a directory
             var isDir: ObjCBool = false
    
  • Tests/VaporTests/FileTests.swift+15 0 modified
    @@ -61,4 +61,19 @@ final class FileTests: XCTestCase {
                 XCTAssertEqual(res.body.string, "<h1>Hello</h1>\n")
             }
         }
    +
    +    func testPercentDecodedRelativePath() throws {
    +        let app = Application(.testing)
    +        defer { app.shutdown() }
    +
    +        let path = #file.split(separator: "/").dropLast().joined(separator: "/")
    +        app.middleware.use(FileMiddleware(publicDirectory: "/" + path))
    +
    +        try app.test(.GET, "%2e%2e/VaporTests/Utilities/foo.txt") { res in
    +            XCTAssertEqual(res.status, .forbidden)
    +        }.test(.GET, "Utilities/foo.txt") { res in
    +            XCTAssertEqual(res.status, .ok)
    +            XCTAssertEqual(res.body.string, "bar\n")
    +        }
    +    }
     }
    
  • Tests/VaporTests/Utilities/foo.txt+1 0 added
    @@ -0,0 +1 @@
    +bar
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.