I need to read the properties file kept in user home folder.
PropertyFile=System.getProperty("user.home")+System.getProperty("file.separator")+"sample.properties";
Fortify is giving path manipulation error in this line. How to resolve this issue?
Fortify is raising an issue, not an error because you are taken input from the process's environment and then opening a path with it without doing any input filtering. Even if you were to add input filtering, the odds are low that Fortify were to recognize it and stop producing the issue. So, in the end, you'll likely set the issue's analysis to Not an issue and just stop worrying about it. But you must first determine if this is a real security concern or a false positive.
When it comes to these specific properties, you're safe. The Java VM sets them so, as long as Java isn't corrupted, you're safe. So mark them as Not an issue and move on.
PS: Yes, Fortify should know that these properties are secure.
Using the Tika library FilenameUtils.normalize solves the fortify issue.
import org.apache.tika.io.FilenameUtils;
String homeDir = System.getProperty("user.home");
String filePath = FilenameUtils.normalize(homeDir +
yourFileName);
File trainFile = new File(filePath);
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 '%';
}
}