Consistent encoded path evaluation in reactive ResourceWebHandler and co
Issue: SPR-16616
This commit is contained in:
parent
e3d0ef6015
commit
13356a7ee2
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.web.reactive.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
|
@ -184,21 +185,21 @@ public class PathResourceResolver extends AbstractResourceResolver {
|
|||
return true;
|
||||
}
|
||||
locationPath = (locationPath.endsWith("/") || locationPath.isEmpty() ? locationPath : locationPath + "/");
|
||||
if (!resourcePath.startsWith(locationPath)) {
|
||||
return false;
|
||||
}
|
||||
return (resourcePath.startsWith(locationPath) && !isInvalidEncodedPath(resourcePath));
|
||||
}
|
||||
|
||||
private boolean isInvalidEncodedPath(String resourcePath) {
|
||||
if (resourcePath.contains("%")) {
|
||||
// Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars...
|
||||
if (URLDecoder.decode(resourcePath, "UTF-8").contains("../")) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Resolved resource path contains \"../\" after decoding: " + resourcePath);
|
||||
}
|
||||
return false;
|
||||
try {
|
||||
String decodedPath = URLDecoder.decode(resourcePath, "UTF-8");
|
||||
return (decodedPath.contains("../") || decodedPath.contains("..\\"));
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
// Should never happen...
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import reactor.core.Exceptions;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
|
@ -314,9 +313,9 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
|||
}
|
||||
|
||||
protected Mono<Resource> getResource(ServerWebExchange exchange) {
|
||||
|
||||
String name = HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE;
|
||||
PathContainer pathWithinHandler = exchange.getRequiredAttribute(name);
|
||||
|
||||
String path = processPath(pathWithinHandler.value());
|
||||
if (!StringUtils.hasText(path) || isInvalidPath(path)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
|
@ -324,31 +323,11 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
|||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
if (path.contains("%")) {
|
||||
try {
|
||||
// Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars
|
||||
String decodedPath = URLDecoder.decode(path, "UTF-8");
|
||||
if (isInvalidPath(decodedPath)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Ignoring invalid resource path with escape sequences [" + path + "].");
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
decodedPath = processPath(decodedPath);
|
||||
if (isInvalidPath(decodedPath)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Ignoring invalid resource path with escape sequences [" + path + "].");
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// ignore
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
return Mono.error(Exceptions.propagate(ex));
|
||||
if (isInvalidEncodedPath(path)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Ignoring invalid resource path with escape sequences [" + path + "]");
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
ResourceResolverChain resolveChain = createResolverChain();
|
||||
|
|
@ -420,6 +399,31 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
|||
return (slash ? "/" : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given path contains invalid escape sequences.
|
||||
* @param path the path to validate
|
||||
* @return {@code true} if the path is invalid, {@code false} otherwise
|
||||
*/
|
||||
private boolean isInvalidEncodedPath(String path) {
|
||||
if (path.contains("%")) {
|
||||
try {
|
||||
// Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars
|
||||
String decodedPath = URLDecoder.decode(path, "UTF-8");
|
||||
if (isInvalidPath(decodedPath)) {
|
||||
return true;
|
||||
}
|
||||
decodedPath = processPath(decodedPath);
|
||||
if (isInvalidPath(decodedPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException | UnsupportedEncodingException ex) {
|
||||
// Should never happen...
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies invalid resource paths. By default rejects:
|
||||
* <ul>
|
||||
|
|
|
|||
Loading…
Reference in New Issue