StaticFileServer.java (vaadin-flow-4.0.5) | : | StaticFileServer.java (vaadin-flow-4.0.6) | ||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
* License for the specific language governing permissions and limitations under | * License for the specific language governing permissions and limitations under | |||
* the License. | * the License. | |||
*/ | */ | |||
package com.vaadin.flow.server; | package com.vaadin.flow.server; | |||
import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | import java.io.IOException; | |||
import java.io.InputStream; | import java.io.InputStream; | |||
import java.io.UnsupportedEncodingException; | ||||
import java.net.URL; | import java.net.URL; | |||
import java.net.URLConnection; | import java.net.URLConnection; | |||
import java.net.URLDecoder; | ||||
import java.nio.charset.StandardCharsets; | ||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | |||
import org.slf4j.Logger; | import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | |||
import com.vaadin.flow.function.DeploymentConfiguration; | import com.vaadin.flow.function.DeploymentConfiguration; | |||
import com.vaadin.flow.internal.ResponseWriter; | import com.vaadin.flow.internal.ResponseWriter; | |||
import static com.vaadin.flow.server.Constants.VAADIN_BUILD_FILES_PATH; | import static com.vaadin.flow.server.Constants.VAADIN_BUILD_FILES_PATH; | |||
import static com.vaadin.flow.server.Constants.VAADIN_MAPPING; | import static com.vaadin.flow.server.Constants.VAADIN_MAPPING; | |||
skipping to change at line 58 | skipping to change at line 55 | |||
* alone static file server. | * alone static file server. | |||
* | * | |||
* @author Vaadin Ltd | * @author Vaadin Ltd | |||
* @since 1.0 | * @since 1.0 | |||
*/ | */ | |||
public class StaticFileServer implements StaticFileHandler { | public class StaticFileServer implements StaticFileHandler { | |||
static final String PROPERTY_FIX_INCORRECT_WEBJAR_PATHS = Constants.VAADIN_P REFIX | static final String PROPERTY_FIX_INCORRECT_WEBJAR_PATHS = Constants.VAADIN_P REFIX | |||
+ "fixIncorrectWebjarPaths"; | + "fixIncorrectWebjarPaths"; | |||
private static final Pattern INCORRECT_WEBJAR_PATH_REGEX = Pattern | private static final Pattern INCORRECT_WEBJAR_PATH_REGEX = Pattern | |||
.compile("^/frontend[-\\w/]*/webjars/"); | .compile("^/frontend[-\\w/]*/webjars/"); | |||
private static final Pattern PARENT_DIRECTORY_REGEX = Pattern | ||||
.compile("(/|\\\\)\\.\\.(/|\\\\)", Pattern.CASE_INSENSITIVE); | ||||
private final ResponseWriter responseWriter; | private final ResponseWriter responseWriter; | |||
private final VaadinServletService servletService; | private final VaadinServletService servletService; | |||
private DeploymentConfiguration deploymentConfiguration; | private DeploymentConfiguration deploymentConfiguration; | |||
/** | /** | |||
* Constructs a file server. | * Constructs a file server. | |||
* | * | |||
* @param servletService | * @param servletService | |||
* servlet service for the deployment, not <code>null</code> | * servlet service for the deployment, not <code>null</code> | |||
skipping to change at line 111 | skipping to change at line 106 | |||
} | } | |||
return resource != null; | return resource != null; | |||
} | } | |||
@Override | @Override | |||
public boolean serveStaticResource(HttpServletRequest request, | public boolean serveStaticResource(HttpServletRequest request, | |||
HttpServletResponse response) throws IOException { | HttpServletResponse response) throws IOException { | |||
String filenameWithPath = getRequestFilename(request); | String filenameWithPath = getRequestFilename(request); | |||
if (!isPathSafe(filenameWithPath)) { | if (HandlerHelper.isPathUnsafe(filenameWithPath)) { | |||
getLogger().info("Blocked attempt to access file: {}", | getLogger().info(HandlerHelper.UNSAFE_PATH_ERROR_MESSAGE_PATTERN, | |||
filenameWithPath); | filenameWithPath); | |||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); | response.setStatus(HttpServletResponse.SC_FORBIDDEN); | |||
return true; | return true; | |||
} | } | |||
URL resourceUrl = null; | URL resourceUrl = null; | |||
if (isAllowedVAADINBuildUrl(filenameWithPath)) { | if (isAllowedVAADINBuildUrl(filenameWithPath)) { | |||
resourceUrl = servletService.getClassLoader() | resourceUrl = servletService.getClassLoader() | |||
.getResource("META-INF" + filenameWithPath); | .getResource("META-INF" + filenameWithPath); | |||
} | } | |||
if (resourceUrl == null) { | if (resourceUrl == null) { | |||
resourceUrl = servletService.getStaticResource(filenameWithPath); | resourceUrl = servletService.getStaticResource(filenameWithPath); | |||
skipping to change at line 193 | skipping to change at line 188 | |||
private boolean isIncorrectWebjarPath(String requestFilename) { | private boolean isIncorrectWebjarPath(String requestFilename) { | |||
return INCORRECT_WEBJAR_PATH_REGEX.matcher(requestFilename).lookingAt(); | return INCORRECT_WEBJAR_PATH_REGEX.matcher(requestFilename).lookingAt(); | |||
} | } | |||
private String fixIncorrectWebjarPath(String requestFilename) { | private String fixIncorrectWebjarPath(String requestFilename) { | |||
return INCORRECT_WEBJAR_PATH_REGEX.matcher(requestFilename) | return INCORRECT_WEBJAR_PATH_REGEX.matcher(requestFilename) | |||
.replaceAll("/webjars/"); | .replaceAll("/webjars/"); | |||
} | } | |||
private boolean isPathSafe(String path) { | ||||
// Check that the path does not have '/../', '\..\', %5C..%5C, or | ||||
// %2F..%2F | ||||
try { | ||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8.name()); | ||||
} catch (UnsupportedEncodingException e) { | ||||
throw new RuntimeException("An error occurred during decoding URL.", | ||||
e); | ||||
} | ||||
return !PARENT_DIRECTORY_REGEX.matcher(path).find(); | ||||
} | ||||
/** | /** | |||
* Check if it is ok to serve the requested file from the classpath. | * Check if it is ok to serve the requested file from the classpath. | |||
* <p> | * <p> | |||
* ClassLoader is applicable for use when we are in NPM mode and are serving | * ClassLoader is applicable for use when we are in NPM mode and are serving | |||
* from the VAADIN/build folder with no folder changes in path. | * from the VAADIN/build folder with no folder changes in path. | |||
* | * | |||
* @param filenameWithPath | * @param filenameWithPath | |||
* requested filename containing path | * requested filename containing path | |||
* @return true if we are ok to try serving the file | * @return true if we are ok to try serving the file | |||
*/ | */ | |||
End of changes. 6 change blocks. | ||||
20 lines changed or deleted | 3 lines changed or added |