2

【CVE-2019-3799】:Directory Traversal with spring-cloud-config-server

 2 years ago
source link: https://chybeta.github.io/2019/04/18/%E3%80%90CVE-2019-3799%E3%80%91-Directory-Traversal-with-spring-cloud-config-server/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Twitter: chybeta

Security Advisory

https://pivotal.io/security/cve-2019-3799

Reproduce

DEMO: https://github.com/spring-cloud/spring-cloud-config#quick-start

GET /foo/default/master/..%252F..%252F..%252F..%252Fetc%252fpasswd HTTP/1.1
Host: localhost:8888

Analysis

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments.

According to the DOC,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)。
For example if we want get test.json as plain text, you can send this request:

GET http://127.0.0.1:8888/foo/label/master/test.json

So how the backend handle this request? When we send the payload, server will dispatcher the request to org/springframework/cloud/config/server/resource/ResourceController.java:54

Step into retrieve function which located inorg/springframework/cloud/config/server/resource/ResourceController.java:104

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);

Continue step into the findOne function:

You can see the locations value is file:/tmp/config-repo-7168113927339570935/. The Config-Server will pull the remote repo and use the locations folder to store these temporary files:

Notice the path value is ..%2F..%2F..%2F..%2Fetc%2fpasswd,so actually the full path like this :

at the end, when call StreamUtils.copyToString(is, Charset.forName("UTF-8"), we can read the /etc/passwd content:

Patch

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

The backend will check whether the resource paths is valid via isInvalidPath and isInvalidEncodedPath:

if (!isInvalidPath(local) && !isInvalidEncodedPath(local)) {
Resource file = this.resourceLoader.getResource(location)
.createRelative(local);
if (file.exists() && file.isReadable()) {
return file;



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK