Twistronics Blog

Spring Cloud Config Server directory traversal vulnerability CVE-2020-5410

June 17, 2020

Spring Could Config Server has a directory traversal vulnerability CVE-2020-5410. The vulnerability is due to the direct splicing of the obtained name and label in the MVC architecture without any filtering. It can be performed with the base address in the configuration file. Backtrack at any position and read the file.

Spring Cloud configuration provides server and client support for external configuration in distributed systems. With Config Server, you can manage the external properties of your application in all environments.

The Spring Cloud Config Server directory traversal vulnerability is due to the direct splicing of the obtained name and label in the MVC architecture without any filtering. With the base address in the configuration file, you can backtrack at any location and read the file.

Take Spring Cloud Config Server 2.2.2 as the vulnerability environment analysis. Pass in the constructed payload and arrive at the MVC entrance at /src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java.

	@RequestMapping("/{name}/{profiles}/{label:.*}")
	public Environment labelled(@PathVariable String name, @PathVariable String profiles,
			@PathVariable String label) {
		return getEnvironment(name, profiles, label, false);
	}

First, the RequestMapping decorator divides the url into three parts, namely name, profile, label. Then enter the getEnvironment method.

/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java

	public Environment getEnvironment(String name, String profiles, String label,
			boolean includeOrigin) {
		name = Environment.normalize(name);
		label = Environment.normalize(label);
		Environment environment = this.repository.findOne(name, profiles, label,
				includeOrigin);
		if (!this.acceptEmpty
				&& (environment == null || environment.getPropertySources().isEmpty())) {
			throw new EnvironmentNotFoundException("Profile Not found");
		}
		return environment;
	}

There are two key methods that can be found here, normalize and findOne. Let’s focus on the findOne function. Here is the key point for splicing the parameters. After entering, we find that there is another layer of findOne function, and entering again there is another layer of findOne, and finally entering The following functions:

/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java

	@Override
	public Environment findOne(String config, String profile, String label,
			boolean includeOrigin) {
		SpringApplicationBuilder builder = new SpringApplicationBuilder(
				PropertyPlaceholderAutoConfiguration.class);
		ConfigurableEnvironment environment = getEnvironment(profile);
		builder.environment(environment);
		builder.web(WebApplicationType.NONE).bannerMode(Mode.OFF);
		if (!logger.isDebugEnabled()) {
			// Make the mini-application startup less verbose
			builder.logStartupInfo(false);
		}
		String[] args = getArgs(config, profile, label);
		// Explicitly set the listeners (to exclude logging listener which would change
		// log levels in the caller)
		builder.application()
				.setListeners(Arrays.asList(new ConfigFileApplicationListener()));

		try (ConfigurableApplicationContext context = builder.run(args)) {
			environment.getPropertySources().remove("profiles");
			return clean(new PassthruEnvironmentRepository(environment).findOne(config,
					profile, label, includeOrigin));
		}
		catch (Exception e) {
			String msg = String.format(
					"Could not construct context for config=%s profile=%s label=%s includeOrigin=%b",
					config, profile, label, includeOrigin);
			String completeMessage = NestedExceptionUtils.buildMessage(msg,
					NestedExceptionUtils.getMostSpecificCause(e));
			throw new FailedToConstructEnvironmentException(completeMessage, e);
		}
	}

It can be seen that the main thing here is that the getArg function splices the parameter paths, and then addresses these paths to obtain the content.