/*
* Copyright 2015-Present Entando S.r.l. (http://www.entando.com) All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package org.entando.entando.aps.system.services.storage;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StorageManagerUtil {
private static final Logger _logger = LoggerFactory.getLogger(StorageManagerUtil.class);
public static boolean isValidFilename(String fullname) {
if (StringUtils.isBlank(fullname)) return false;
String basename = FilenameUtils.getBaseName(fullname);
String extension = FilenameUtils.getExtension(fullname);
return isValidFilename(basename, extension);
}
public static boolean isValidFilename(String basename, String extension) {
if (StringUtils.isBlank(basename)) return false;
if (!isValidPath(basename)) return false;
if (!isValidFilenameNoExtension(basename)) return false;
if (StringUtils.isNotBlank(extension)) {
if (!isValidExtension(extension)) return false;
}
return true;
}
public static boolean isValidFilenameNoExtension(String basename) {
if (StringUtils.isBlank(basename)) return false;
Pattern pattern = Pattern.compile(REGEXP_FILE_BASENAME);
Matcher matcher = pattern.matcher(basename);
return matcher.matches();
}
public static boolean isValidDirName(String basename) {
if (StringUtils.isBlank(basename)) return true;
if (!isValidPath(basename)) return false;
Pattern pattern = Pattern.compile(REGEXP_DIR);
Matcher matcher = pattern.matcher(basename);
boolean check = matcher.matches();
if (!check) return check;
return endWithParentDir(basename);
}
public static boolean isValidExtension(String extension) {
if (StringUtils.isBlank(extension)) return false;
Pattern pattern = Pattern.compile(REGEXP_FILE_EXTENSION);
Matcher matcher = pattern.matcher(extension);
return matcher.matches();
}
public static boolean isValidPath(String path) {
final boolean check = true;
if (StringUtils.isBlank(path)) return check;
if (path.contains("../")
|| path.contains("%2e%2e%2f")
|| path.contains("..%2f")
|| path.contains(".."+File.separator)
|| path.contains("%2e%2e/")
|| path.contains("%2e%2e"+File.separator)) {
_logger.info("Attack avoided - requested path {}", path);
return !check;
}
return check;
}
private static boolean endWithParentDir(String path) {
if (StringUtils.isBlank(path)) return true;
if (path.endsWith("..")
|| path.endsWith("..")
|| path.endsWith("%2e%2e")) {
_logger.info("Attack avoided - requested path {}", path);
return false;
}
return true;
}
private static final String REGEXP_FILE_EXTENSION = "([\\w|\\-]+?$)";
private static final String REGEXP_FILE_BASENAME = "(^[\\w|\\.|\\-|\\_| ]+?)";
private static final String REGEXP_DIR = "(^[\\w|\\.|\\-|\\_|/| ]+?)";
}