下面的简单 java 代码得到 Fortify Path Manipulation 错误。请帮我解决这个问题。我挣扎了很久。
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
下面的简单 java 代码得到 Fortify Path Manipulation 错误。请帮我解决这个问题。我挣扎了很久。
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
在使用之前尝试规范化 URL
https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#normalize()
Path path = Paths.get("/foo/../bar/../baz").normalize();
或使用org.apache.commons.io.FilenameUtils中的 normalize
Stirng path = FilenameUtils.normalize("/foo/../bar/../baz");
对于这两个结果将是\baz
查看路径操作的 OWASP 页面,它说
攻击者可以指定文件系统操作中使用的路径
您正在打开由用户给定输入定义的文件。您的代码几乎是漏洞的完美示例!任何一个
或者重新考虑您的应用程序的设计。
即使路径/文件不像属性文件那样来自用户输入,Fortify 也会标记代码。处理这些问题的最佳方法是首先规范化路径,然后根据允许路径的白名单对其进行验证。
坏的:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
好的:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
if (!isInSecureDir(file)) {
throw new IllegalArgumentException();
}
String canonicalPath = file.getCanonicalPath();
if (!canonicalPath.equals("/img/java/file1.txt") &&
!canonicalPath.equals("/img/java/file2.txt")) {
// Invalid file; handle error
}
FileInputStream fis = new FileInputStream(f);
}
仅允许输入中的 alnum 和句点。这意味着您过滤掉会使您的文件易受攻击的控制字符“..”、“/”、“\”。例如,一个人应该无法输入 /path/password.txt。
完成后,重新扫描,然后运行 Fortify AWB。
假设您正在针对 Web 应用程序运行 Fortify,在您对可能被标记为“不是问题”的 Fortify 漏洞进行分类期间。推理是 A) 显然这是测试代码和 B) 除非您有多重人格障碍,否则您在运行该测试应用程序时不会对自己进行路径操纵漏洞利用。
如果很常见的是,很少有测试实用程序提交到会产生这种误报的存储库。
至于您的编译错误,通常归结为类路径问题。
我有一个解决 Fortify Path Manipulation 问题的方法。
它抱怨的是,如果您从外部来源获取数据,那么攻击者可以使用该来源来操纵您的路径。因此,使攻击者能够删除文件或以其他方式危害您的系统。
解决此问题的建议方法是使用可信目录的白名单作为有效输入;并且,拒绝其他一切。
此解决方案在生产环境中并不总是可行的。所以,我建议另一种解决方案。解析输入以获取可接受字符的白名单。从输入中拒绝任何您不希望出现在路径中的字符。它可以被删除或更换。
下面是一个例子。这确实通过了 Fortify 审查。重要的是要记住这里返回的是文字而不是被检查的字符。Fortify 会跟踪来自原始输入的部分。如果您使用任何原始输入,您仍然可能会收到错误。
public class CleanPath {
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 '%';
}
}
我们有如下代码,它在 fortify 中引发了路径操作高类别问题。
String.join(delimeter,string1,string2,string2,string4);
我们的程序是处理 AWS S3 存储桶,因此,我们进行了如下更改并且它有效。
com.amazonaws.util.StringUtils.join(delimeter,string1,string2,string2,string4);
使用正则表达式验证文件路径和文件名
fileName = args[0];
final String regularExpression = "([\\w\\:\\\\w ./-]+\\w+(\\.)?\\w+)";
Pattern pattern = Pattern.compile(regularExpression);
boolean isMatched = pattern.matcher(fileName).matches();