How to fix "Path Manipulation Vulnerability" in some Java Code?

131.9k Views Asked by At

The below simple java code getting Fortify Path Manipulation error. Please help me to resolve this. I am struggling from long time.

public class Test {
    public static void main(String[] args) {
        File file=new File(args[0]);
    }

}
12

There are 12 best solutions below

2
Joe On

Looking at the OWASP page for Path Manipulation, it says

An attacker can specify a path used in an operation on the filesystem

You are opening a file as defined by a user-given input. Your code is almost a perfect example of the vulnerability! Either

  1. Don't use the above code (don't let the user specify the input file as an argument)
  2. Let the user choose from a list of files that you supply (an array of files with an integer choice)
  3. Don't let the user supply the filename at all, remove the configurability
  4. Accept the vulnerability but protect against it by checking the filename (although this is the worst thing to do - someone may get round it anyway).

Or re-think your application's design.

0
user1366399 On

Only allow alnum and a period in input. That means you filter out the control chars, "..", "/", "\" which would make your files vulnerable. For example, one should not be able to enter /path/password.txt.

Once done, rescan and then run Fortify AWB.

0
AudioBubble On

Assuming you're running Fortify against a web application, during your triage of Fortify vulnerabilities that would likely get marked as "Not an issue". Reasoning being A) obviously this is test code and B) unless you have multiple personality disorder you're not going to be doing a path manipulation exploit against your self when you run that test app.

If very common to see little test utilities committed to a repository which produces this style of false positive.

As for your compilation errors, that generally comes down to classpath issues.

1
user5250723 On

Use regex to validate the file path and file name

fileName = args[0];
final String regularExpression = "([\\w\\:\\\\w ./-]+\\w+(\\.)?\\w+)";
Pattern pattern = Pattern.compile(regularExpression);
boolean isMatched = pattern.matcher(fileName).matches();
0
Cassian On

Try to normalize the URL before using it

https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#normalize()

Path path = Paths.get("/foo/../bar/../baz").normalize();

or use normalize from org.apache.commons.io.FilenameUtils

https://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize(java.lang.String)

Stirng path = FilenameUtils.normalize("/foo/../bar/../baz");

For both the result will be \baz

0
BrianKeys On

Fortify will flag the code even if the path/file doesn't come from user input like a property file. The best way to handle these is to canonicalize the path first, then validate it against a white list of allowed paths.

Bad:

public class Test {
    public static void main(String[] args) {
        File file=new File(args[0]);
    }

}

Good:

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);
    }

Source: https://www.securecoding.cert.org/confluence/display/java/FIO16-J.+Canonicalize+path+names+before+validating+them

2
Trant Batey On

I have a solution to the Fortify Path Manipulation issues.

What it is complaining about is that if you take data from an external source, then an attacker can use that source to manipulate your path. Thus, enabling the attacker do delete files or otherwise compromise your system.

The suggested remedy to this problem is to use a whitelist of trusted directories as valid inputs; and, reject everything else.

This solution is not always viable in a production environment. So, I suggest an alternative solution. Parse the input for a whitelist of acceptable characters. Reject from the input, any character you don't want in the path. It could be either removed or replaced.

Below is an example. This does pass the Fortify review. It is important to remember here to return the literal and not the char being checked. Fortify keeps track of the parts that came from the original input. If you use any of the original input, you may still get the error.

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 '%';
    }
}
0
kartik kudada On

We have code like below which was raising Path Manipulation high category issue in fortify .

String.join(delimeter,string1,string2,string2,string4);

Our program is to deal with AWS S3 bucket so, we changed as below and it worked .

com.amazonaws.util.StringUtils.join(delimeter,string1,string2,string2,string4);
0
Ritesh Singh On

Using the Tika library FilenameUtils.normalize solves the fortify issue.

import org.apache.tika.io.FilenameUtils;
public class Test {
    public static void main(String[] args) {
        String filePath = FilenameUtils.normalize(args[0]); //This line solve issue.
        File file=new File(filePath);
    }

}
2
user19892486 On

Use Normalize() function in C# and it resolved the fortify vulnerability in next scan.

string s = @:c:\temp\scan.log".Normalize();

1
Smart Coder On

Try this for replacing FileInputStream. You will need to close your project and open again to accurately see whether changes worked.

File to byte[] in Java

1
Charliefes On
public void extractZipFile(String zipFilePath, String outputFolder) throws IOException {
    File file = new File(zipFilePath);
    
    try (ZipFile zip = new ZipFile(file)) {
    
    Enumeration<? extends ZipEntry> entries = zip.entries();

        while (entries.hasMoreElements()) {

            ZipEntry entry = entries.nextElement();

            String entryName = entry.getName();

            if (!entry.isDirectory()) {
                File outputFile = new File(outputFolder, entryName);
                if (!outputFile.toPath().normalize().startsWith(new File(outputFolder).toPath().normalize())) {
                    throw new IOException("Zip entry is outside of the target directory: " + entryName);
                }
                try (InputStream input = zip.getInputStream(entry)) {
                    Files.copy(input, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                }
            }
        }
    }
}