Fortify security finding -- CWE 22 Path Manipulation - java

I have the below code to get the lastest modified file by given directory and the prefix of the filename.
When I ran the HPE fortify analysis it gave me "Path manipulation" findings.
Can you guys guide me how to fix this finding?
What is the best and secure approach to access filesystem for a web application?
public static File getLatestFilefromDirWithFileName(String archivesDirectoryPath, String fileStartWith){
File archivesDirectory = new File(archivesDirectoryPath);
FilenameFilter textFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.startsWith(fileStartWith)) {
return true;
} else {
return false;
}
}
};
File[] filesInArchiveDir = archivesDirectory.listFiles(textFilter);
if (filesInArchiveDir == null || filesInArchiveDir.length == 0) {
return null;
}
File lastModifiedFile = filesInArchiveDir[0];
for (int i = 1; i < filesInArchiveDir.length; i++) {
if (lastModifiedFile.lastModified() < filesInArchiveDir[i].lastModified()) {
lastModifiedFile = filesInArchiveDir[i];
}
}
return lastModifiedFile;
}

You must ensure that archivesDirectoryPath do not allow to access sensible folders.
One way to do it, is to validate that the specified folder will be located in a white list of location. This white list could either be define in your code or configurable by "administrator" users. Trying to process a folder that is not on this list should raise Exception.
You can check that no /../ are used in folder name, but checking that the resulting folder is part of your white list should be enough.

Related

What is the right way to check if a file is in a directory?

I am not asking how to check if a file exists or how to check if a file is in a specific directory level. Rather I want to know how to check if an existing file is anywhere underneath a specified directory.
Obviously if a file is a direct child of a directory that is easy to check. But what I want to be able to do is efficiently check if an existing file is in a directory including any possible subdirectory. I'm using this in an Android project where I am keeping fine grain control over my cache and I want a utility method to check if a file I may be manipulating is in my cache folder.
Example:
cache dir
/ \
dir file1
/ \
file2 file3
isCacheFile(file2) should return true
Currently I have a method that does it like so
private static final File cacheDir = AssetManager.getInstance().getCacheDir(); // Not android.content.res.AssetManager
private static final String cacheDirName = cacheDir.getAbsolutePath();
public static boolean isCacheFile(File f) {
if (!f.exists()) return false;
return f.getAbsolutePath().startsWith(cacheDirName);
}
However, I am inclined to believe there is a better way to do this. Does anyone have any suggestions?
If you have a known path (in the form of File f), and you want to know if it is inside a particular folder (in the form of File cacheDir), you could simply traverse the chain of parent folders of your file and see if you meet the one you are looking for.
Like this:
public static boolean isCacheFile(File f) {
while (f.getParentDir()!=null) {
f = f.getParentDir();
if (f.equals(cacheDir)) {
return true;
}
}
return false;
}
boolean isContains(File directory){
File[] contents = directory.listFiles();
if (contents != null) {
for(int i = 0; i < contents.length; i++){
if(contents[i].isDirectory())
isContains(contents[i]);
else if(contents[i].getName().equals(*your_file_name*))
return true;
}
}
return false;
}
You could do it by recursion, by calling if the file exists in each sub-directory.
first check if the file exists in the root directory.
boolean exist = new File(rootDirectory, temp).exists();
then if the file wasn't in the root directory, then list all the files and call the method again in the sub-directoy files recursionally until you find the file or there are no more sub-directories.
public String getPathFromFileName(String dirToStart,Sring fileName){
File f = new File(dirToStart);
File[] list = f.listFiles();
String s="null";
for(int i=0;i<list.length;i++){
if(list[i].isFile()){
//is a file
if(fileName.equals(list[i])){
s=dirToStart+"/"+fileName;
break;
}
}else{
//is a directory search further.
getPathFromFileName(dirToStart+list[i]);
}
}
return s;
}
call this method by passing the parent directory name and the file name to search in subdirectories.
you check the return value if it is not equal to "null", then the files path is returned.

Stack Overflow error from recursive directory traversal

When I'm running this method I immediately get a stack overflow exception so obviously the method keeps recursively calling itself however I'm not sure why. For reference the file structure I'm testing it with is a load of folders and in those folders are files, no other folders
public void files(File[] f)
{
if(f == null){
return;
}
else
{
for(int i = 0; i < f.length; i++)
{
if(f[i].isFile() && (f[i].getName().contains(".mp3") || f[i].getName().contains(".m4a"))) //iterate through files and check if each file matches the required criteria
{
String fullname = f[i].getName();
Log.v("full name", fullname);
String name = null;
if(fullname.contains(".mp3"))
{
name = fullname.substring(0, fullname.lastIndexOf(".mp3"));
}
else if(fullname.contains(".m4a")) //Removing file extensions of music file so they can be displayed using an appropriate name
{
name = fullname.substring(0, fullname.lastIndexOf(".m4a"));
}
list.add(name);
mp3.add(f[i]);
Log.v("added", name);
}
if(f[i].isDirectory())
{
File inner[] = files[i].listFiles();
files(inner);
}
}
}
}
Maybe some of the files are "." and ".." which means , i think, the current folder and back one folder.
So in your isDirectory() part of the if check also check if f[i]!="." and f[i]!=".."
if(f[i].isDirectory() and f[i]!="." and f[i]!="..")
{
File inner[] = files[i].listFiles();
files(inner);
}
EDIT:
As #Jon said, try to add more debug to it and see where it breaks exactly.
LATER EDIT:
For future readers, the problem was here:
//File inner[] = files[i].listFiles();
File inner[] = f[i].listFiles();
So super dumb mistake on my part, when copying the code from a previous non recursive implementation I forgot to change files to f in
if(f[i].isDirectory())
{
File inner[] = files[i].listFiles();
files(inner);
}

Use Java to find a File within a directory using only a Name

I'm trying to write this script that takes an Excel sheet, gets all the names of files from the cells, and moves each of those files to a specific folder. I've already got most of the code done, I just need to be able to search for each file in the source directory using just its title. Another problem is that I'm searching for multiple file types (.txt, .repos, .xlsx, .xls, .pdf, and some files don't have extensions), I only can search by the file name without the extension.
In my findAndMoveFiles method, I've got an ArrayList of each File and a Guava Multimap of XSSFCells to Strings (a cell is one cell from the Excel file and a String is the name of the folder it needs to go into, one to many relationship) as parameters. What I've got right now for the method is this.
public static void findAndMoveFiles(List<File> files, Multimap<XSSFCell, String> innerCells) {
// For each file, get its values (folders), and put that file in each of those folders
for (XSSFCell cell : innerCells.keySet()) {
// find the file in the master directory
//Finder f = new Finder();
//if (f.canBeFound(FOLDER, cell.getStringCellValue())) {
File file = find(FOLDER, cell.getStringCellValue());
//System.out.println(file.getAbsolutePath());
//List<String> values = new ArrayList(innerCells.get(cell));
/*for (String folder : values) {
File copy = file;
if (copy != null) {
System.out.println(folder);
System.out.println(copy.getAbsolutePath());
if (copy.renameTo(new File("C:\\strobell\\" + folder + "\\" + copy.getAbsolutePath()))) {
System.out.println(copy.getName() + " has been moved successfully.");
} else {
System.out.println(copy.getName() + " has failed to move.");
}
}
}*/
//}
}
}
public static File find(File dir, String fileName) {
String files = "";
File[] listOfFiles = dir.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getAbsolutePath();
if (files.equals(fileName)) {
return listOfFiles[i];
}
}
}
return null;
}
I commented out parts because it wasn't working. I was getting NullPointerExceptions because some files were being returned as null. I know that it's returning null, but each file should be found.
If there are any 3rd party libraries that can do this, that would be amazing, I've been racking my brain on how to do this properly.
Instead of
File[] listOfFiles = dir.listFiles();
use
File[] listOfFiles = dir.list(new FileNameFilter() {
public boolean accept(File dir, String name) {
if( /* code to check if file name is ok */ ) {
return true;
}
return false;
}
}););
Then you can code your logic on the file names in the condition.

Java File API in Windows 7 issue

Basically, I'm just trying to run a list of all the files in a folder using the list function from the Java File class:
artistList = (new File(myPathName)).list();
But what I get is some missing files, even after I have "show hidden files" in Windows 7. I'm wondering where these files are.
If it helps, the path I'm searching in is a folder like /media which I have organized into /media/artist/album/title.mp3 for all my song data. The extra files I end up finding up are AlbumArt jpeg files (and I used songbird version 9 beforehand to sort the folders first, I'm just trying to rename the match the ID3 tags myself with a small Java program).
With the organisation you descibed there will be no media files in the directory /media where your search / listing starts, you have to navigate trought subdirectories untill you reach /media/artist/album from there on you can get files that you actualy looking for. Also you might have to add a filter to list method and implement the filter's accept method to kick out thumbnails and hidden meta-files.
Here a piece of code (untested) that could help you
private final static Set<String> mediaExtensions;
static {
mediaExtensions = new HashSet<String>();
mediaExtensions.add(".mp3");
mediaExtensions.add(".wav");
mediaExtensions.add(".ogg");
// and so on
}
public static void list(File file, List<File> result) {
if(file.isFile()) {
result.add(file);
} else if(file.isDirectory()) {
File files[] = file.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
boolean accept = false;
int i = pathname.getName().lastIndexOf('.');
if(i != -1) {
String ext = pathname.getName().substring(i);
accept = (! pathname.isHidden()) &&
mediaExtensions.contains(ext);
}
return accept;
}
});
if(files != null) {
for(File f : files) {
list(f, result);
}
}
}
}

find same file with in many directories in hierarchical directories in java

I am trying to get a report file which is generated for many applications and stored in directories. But i am not able to get every report when i search through java. Can any 1 please help me with this matter.
if you want to search the file in a directory that has subdirectory and goes on then use a recursive search.you can see an example here http://www.exampledepot.com/egs/java.io/TraverseTree.html
http://www.java2s.com/Code/Java/File-Input-Output/Searchforfilesrecursively.htm
private static File find(File dir, String name) {
File result = null; // no need to store result as String, you're returning File anyway
File[] dirlist = dir.listFiles();
for(int i = 0; i < dirlist.length; i++) {
if(dirlist[i].isDirectory()) {
result = find(dirlist[i], name);
filedetails.add(result);
if (dirlist==null)
break;
// recursive call found the file; terminate the loop
} else if(dirlist[i].getName().matches(name)) {
return dirlist[i]; // found the file; return it
}
}
return result; // will return null if we didn't find anything
}
here is snippet where i am trying details of the file in a vector .
File Dir = new File("D:\\log");
File[] Dir2 = Dir.listFiles(); //Dir2 is inner directory
for(int j=0;j
/* The add gets the same file names which as differnt path and that vector can stored and used */

Categories