Browse Source

[fix] Enhance name pre checker in resource center (#10094) (#10759)

* [fix] Enhance name pre checker in resource center (#10094)

* [fix] Enhance name pre checker in resource center

Add file name and directory checker to avoid directory traversal

* add some missing change and change docs

* change var name in directoryTraversal

* Fix ci

(cherry picked from commit 63f835715f)

* Add new constants
2.0.7-release
Jiajie Zhong 2 years ago committed by GitHub
parent
commit
23fae510df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  2. 21
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java
  3. 1
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
  4. 21
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java
  5. 30
      dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/FileUtilsTest.java

3
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -349,7 +349,8 @@ public enum Status {
ENVIRONMENT_WORKER_GROUPS_IS_INVALID(1200012, "environment worker groups is invalid format", "环境关联的工作组参数解析错误"),
UPDATE_ENVIRONMENT_WORKER_GROUP_RELATION_ERROR(1200013,"You can't modify the worker group, because the worker group [{0}] and this environment [{1}] already be used in the task [{2}]",
"您不能修改工作组选项,因为该工作组 [{0}] 和 该环境 [{1}] 已经被用在任务 [{2}] 中"),
NOT_ALLOW_TO_DISABLE_OWN_ACCOUNT(130020, "Not allow to disable your own account", "不能停用自己的账号");
NOT_ALLOW_TO_DISABLE_OWN_ACCOUNT(130020, "Not allow to disable your own account", "不能停用自己的账号"),
VERIFY_PARAMETER_NAME_FAILED(1300009, "The file name verify failed", "文件命名校验失败");
private final int code;

21
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java

@ -132,6 +132,10 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
return result;
}
if (FileUtils.directoryTraversal(name)) {
putMsg(result, Status.VERIFY_PARAMETER_NAME_FAILED);
return result;
}
String fullName = currentDir.equals("/") ? String.format("%s%s",currentDir,name) : String.format("%s/%s",currentDir,name);
result = verifyResource(loginUser, type, fullName, pid);
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
@ -498,6 +502,19 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe
private Result<Object> verifyFile(String name, ResourceType type, MultipartFile file) {
Result<Object> result = new Result<>();
putMsg(result, Status.SUCCESS);
if (FileUtils.directoryTraversal(name)) {
logger.error("file alias name {} verify failed", name);
putMsg(result, Status.VERIFY_PARAMETER_NAME_FAILED);
return result;
}
if (file != null && FileUtils.directoryTraversal(Objects.requireNonNull(file.getOriginalFilename()))) {
logger.error("file original name {} verify failed", file.getOriginalFilename());
putMsg(result, Status.VERIFY_PARAMETER_NAME_FAILED);
return result;
}
if (file != null) {
// file is empty
if (file.isEmpty()) {
@ -934,6 +951,10 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe
if (!result.getCode().equals(Status.SUCCESS.getCode())) {
return result;
}
if (FileUtils.directoryTraversal(fileName)) {
putMsg(result, Status.VERIFY_PARAMETER_NAME_FAILED);
return result;
}
//check file suffix
String nameSuffix = fileSuffix.trim();

1
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java

@ -92,6 +92,7 @@ public final class Constants {
public static final String REGISTRY_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS = "/lock/failover/workers";
public static final String REGISTRY_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS = "/lock/failover/startup-masters";
public static final String REGISTRY_SERVERS = "registry.servers";
public static final String FOLDER_SEPARATOR = "/";
/**
* fs.defaultFS

21
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java

@ -200,4 +200,25 @@ public class FileUtils {
}
}
/**
* Check whether the given string type of path can be traversal or not, return true if path could
* traversal, and return false if it is not.
*
* @param filename String type of filename
* @return whether file path could be traversal or not
*/
public static boolean directoryTraversal(String filename){
if (filename.contains(FOLDER_SEPARATOR)) {
return true;
}
File file = new File(filename);
try {
File canonical = file.getCanonicalFile();
File absolute = file.getAbsoluteFile();
return !canonical.equals(absolute);
} catch (IOException e) {
return true;
}
}
}

30
dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/FileUtilsTest.java

@ -89,4 +89,34 @@ public class FileUtilsTest {
Assert.assertEquals(content, fileContent);
}
@Test
public void testDirectoryTraversal() {
// test case which do not directory traversal
String path;
path = "abc.txt";
Assert.assertFalse(FileUtils.directoryTraversal(path));
path = "abc...txt";
Assert.assertFalse(FileUtils.directoryTraversal(path));
path = "..abc.txt";
Assert.assertFalse(FileUtils.directoryTraversal(path));
// test case which will directory traversal
path = "../abc.txt";
Assert.assertTrue(FileUtils.directoryTraversal(path));
path = "../../abc.txt";
Assert.assertTrue(FileUtils.directoryTraversal(path));
path = "abc../def.txt";
Assert.assertTrue(FileUtils.directoryTraversal(path));
path = "abc./def.txt";
Assert.assertTrue(FileUtils.directoryTraversal(path));
path = "abc/def...txt";
Assert.assertTrue(FileUtils.directoryTraversal(path));
}
}

Loading…
Cancel
Save