Contents

Input Path Not Canonicalized 風險

常常遇到一些問題,網路上找到一些方法筆記一下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
private static String sanitizePathTraversal(String filename) {
 Path p = Paths.get(filename);
 return p.getFileName().toString();
}
private String getFileContents_fixed(HttpServletRequest request) throws ServletException,
FileNotFoundException, IOException {
String filename = sanitizePathTraversal(request.getParameter("filename")); // Ensures access only to files in a given folder, no traversal
Path path = Paths.get(SERVED_FILES_DIR + filename);
byte[] fileContentBytes = Files.readAllBytes(path);
String fileContents = new String(fileContentBytes, FILE_CONTENT_ENCODING_STRING);
 return fileContents;
}

簡單說就是讓使用者 request 檔案名稱不可以帶入資料夾相關資料,看上面範例。但不知道Java有沒有現成安全的套件,目前是沒看到有。

Path Manipulation

自己覺得可以用白名單確認,可能是最好。再來是過濾特殊字元。最後就算沒有改 Code,正常主機設定的權限也應該要嚴謹,也不會有安全性的問題。

白名單

參考:Path Manipulation | Fix Fortify Issue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public static final String UMD_EXCEPTION ="/fxxxxbs3/UMD_EXCE/";
 public static final Map<String, String> UMD_EXCEPTION_OMC = Collections.unmodifiableMap(new HashMap<String, String>(){{
  for(String omcCode :OmcUnit.ALL_CODES){
   put(omcCode,UMD_EXCEPTION+File.separator+omcCode); 
  }
 }});


for(OmcUnit omcUnit :omcList){
    String fileName = "omc"+omcUnit.getCode()+"."+inputDateRoc+".all";
    String path = FileFullPathUrl.UMD_EXCEPTION_OMC.get(omcUnit.getCode());
File path = new File(path);
}

過濾特殊字元

參考
Fortify漏洞之 Path Manipulation 路徑篡改問題解決筆記_dazhong2012的博客-CSDN博客_pathmanipulation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
 * 過濾字符串幫助類
 */
public class CleanPathUtil {
	public static String cleanString(String aString) {
	    if (aString == null) return null;
	    String cleanString = \"\";
	    for (int i = 0; i < aString.length(); ++i) {
	        cleanString += cleanChar(aString.charAt(i));
	    }
	    return cleanString;
	}

	private static char cleanChar(char aChar) {

	    // 0 - 9
	    for (int i = 48; i < 58; ++i) {
	        if (aChar == i) return (char) i;
	    }

	    // 'A' - 'Z'
	    for (int i = 65; i < 91; ++i) {
	        if (aChar == i) return (char) i;
	    }

	    // 'a' - 'z'
	    for (int i = 97; i < 123; ++i) {
	        if (aChar == i) return (char) i;
	    }

	    // other valid characters
	    switch (aChar) {
	        case '/':
	            return '/';
	        case '.':
	            return '.';
	        case '-':
	            return '-';
	        case '_':
	            return '_';
	        case ' ':
	            return ' ';
	    }
	    return '%';
	}

}

可能還有其他做法,改天看到再補。
FIO16-J. Canonicalize path names before validating them - SEI CERT Oracle Coding Standard for Java - Confluence

以下方法為不可用

以下為不可用安全。我差點用了。

1
2
3
4
5
6
import java.nio.file.*;

String path  = System.getenv(variableName);
Path p = Paths.get(path);
Path normalizedPath = p.normalize();
path = new File(normalizedPath.toString());
1
2
3
4
import org.apache.commons.io.FilenameUtils;

String path  = System.getenv(variableName);
path = new File(FilenameUtils.normalize(path));

path - Input_Path_Not_Canonicalized - PathTravesal Vulnerability in checkmarx - Stack Overflow
FilenameUtils (Apache Commons IO 2.11.0 API)
Top 20 OWASP Vulnerabilities And How To Fix Them Infographic | UpGuard