UnauthorizedAccessException while scanning directory 'User\Documents\My Music' - c#-4.0

Question: Why do I get this error while scanning a users 'My Documents' folder, but not when I scan the 'My Music/My Pictures/My Videos' directory?
Secondary, less important question: Is there a way to avoid this without having to specifically filter these folders out, or using a try/catch block?
I prefer answers that teach me how to fish, instead of just giving me fish. Just at this point I am not sure where I need to look to specifically answer this question. I've read through documents about elevating permissions and iterating through the file system, and spent a good week looking for why I can set DirectoryInfo on 'User\My Music' but not 'User\Documents\My Music'(link) and just would enjoy a little boost in a different direction in regards to learning more.
I catch the initial 'UnauthorizedAccessException' that is thrown initially when attempting Directory.GetFiles('path', "*", SearchOption.AllDirectories) where path is the users 'My Documents'. To handle the exception I know that I need to walk the directory manually. Which works, returning the files from the sub-directories.
The code for the initial GetFiles function:
public static string[] GetFiles(string path)
{
string[] files;
try
{
files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
}
catch(UnauthorizedAccessException ex)
{ files = WalkDirectory(path); }
return files;
}
public static string[] WalkDirectory(string path)
{
List<string> files = new List<string>();
DirectoryInfo dir = new DirectoryInfo(path);
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
try
{
files.AddRange(WalkDirectory(subDir.FullName));
}
catch(UnauthorizedAccessException ex)
{
// complete fail to walk directory listed
throw ex;
}
}
foreach (FileInfo file in dir.GetFiles())
{
files.Add(file.FullName);
}
}
This works out perfectly, until the code attempts to walk the hidden folders: My Music, My Pictures, or My Videos. No matter how I try and re-code to walk the hidden files, I keep receiving the UnauthorizedAccessException.
I understand completely that I am going to code around this. Mainly what I am curious to know, is why is the exception happening under a users folder?
An asssumption I am making is that the folder is a symlink to another directory, because I can make the path ?:\users directory\user\My (Music, Pictures, or Videos) and the code walks those directories then without any issues. This only happens when trying to scan the directory files after setting them from within the users My Documents.
OS: Windows 7
User Privliages: Administrator
Application Elevated to run as administrator

I was speaking about this with a friend, who is not technical, but knows enough tech to hold a conversation and he helped me narrow this question down further. This is actually a duplicate question and was answered at Check if a file is real or a symbolic link.
The folder is a symbolic link that was placed there for backwards compatibility purposes according to this article on TechRepublic: Answers to some common questions about symbolic links under the section Windows Vista and Windows 7 have built-in symbolic links paragraph 2.
In order to specifically avoid attempting to scan this directory without a Try/Catch block on an UnauthorizedAccessException the folder attributes need to be checked to determine if the folder or file in question is a symbolic link. Which again was answered in the above listed stackoverflow question.

Related

Fortify Path Manipulation error

Fority Scan reported "Path Manipulation" security issues in following snippet
String filePath = getFilePath(fileLocation, fileName);
final File file = new File(filePath);
LOGGER.info("Saving report at : " + filePath);
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(file));
fileWriter.write(fileContent);
so i am checking for blacklisted characters in fileLocation and throwing exception, still the Fortify is throwing the exception.
try {
String filePath = getFilePath(fileLocation, fileName);
if (isSecurePath(filePath)) {
final File file = new File(filePath);
LOGGER.info("Saving report at : " + filePath);
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(file));
fileWriter.write(fileContent);
} else {
throw new Exception("Security Issue. File Path has blacklisted characters");
}
} catch (final Exception e) {
LOGGER.error("Unable to prepare mail attachment : ", e);
message = "Mail cannot be send, Unable to prepare mail attachment";
}
private boolean isSecurePath(String filePath) {
String[] blackListChars = {".."};
return (StringUtils.indexOfAny(filePath, blackListChars)< 0);
}
should i ignore the scan report or what would be the correct fix for this?
Firstly SCA is a static analysis tool, so can't check your custom validation to determine whether it works correctly or not, as this is something a dynamic tool such as WebInspect is designed to do.
Secondly, blacklisting is a poor way of securing anything, whitelisting is the far more secure method and the fact you're mentioning blacklisting validation to stdout would entice an attacker. This is because you have to account for every single possible way of being attacked, including ways that may not have been discovered yet, so could easily become out of date before the software is even released.
Thirdly, this definitely wouldn't suffice against stopping path manipulation since you're only accounting for people looking for relative paths and more specifically relative paths above the current directory.
There's no way you have of detecting if somebody specifies a full path, or if somebody goes to a directory that's a symbolic link to a separate directory altogether, along with a couple of other possible alternative attacks.
Ideally you should follow the recommendations shown by SCA and have a very specific allowed paths & filenames. Where this isn't possible, use a whitelisting technique to specify the only characters that are allowed, and then validate to specify that it's not for example a SMB share or a full path specified. If it doesn't validate according to the specification of what users should be specifying, reject it.
Doing this will get rid of the issue itself, but SCA will likely still show the issue in the results (again due to the differences between static vs dynamic analysis). This can be worked around by auditing it as such or creating a custom cleanse rule for the function that validates the issue.

How can I count the files inside a folder of project solution?

I want to develop a windows phone based application in which I need to put the number of files in a folder (this folder is already a part of the project) to a list so that at run time I can access those files. If anybody can give me idea of how to do that then it will be great help.
In normal WPF applications we can write code like
DirectoryInfo di = new DirectoryInfo("D:\\Tempo");
FileInfo[] fi = di.GetFiles("*", SearchOption.AllDirectories);
MessageBox.Show(fi.Length.ToString());
But Windows phone inside solution how do I do that?
I can get a single file access by this code
if (Application.GetResourceStream(new Uri("/WindowsPhone;component/Folder/file09.jpg", UriKind.Relative)) != null)
{
MessageBox.Show("Hi");
}
But inside that folder there are many files and I want to put them into list so at run time I can access those images. But the user won't be knowing about that so it should be a C# code, not a XAML code. Any help would be great.
It's pretty easy.
Make sure you add the specific folder to the Solution. Along with any files you want in that folder.
Make sure each file's Properties are set like so:
Build Action: Content
Copy to Output Directory: Do not copy
Make sure the application had loaded before calling
Lets say I had a folder called "Testfiles" and I want to read from it then:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
ReadAllFilesFromFolder("Testfiles");
}
// TODO: recursion to get subfolders and files (maybe?)
public async void ReadAllFilesFromFolder(string folder_name)
{
var package = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assetsFolder = await package.GetFolderAsync(folder_name);
foreach (var file in await assetsFolder.GetFilesAsync())
{
// TODO: whatever you want to do with file
// string filename = file.Name;
}
}

How do I support multiple server.pid files?

I am running play on multiple machines in our datacenter. We loadbalance the hell out of everything. On each play node/VM I'm using Apache and an init.d/play script to start and stop the play service.
The problem is that our play websites are hosted on shared network storage. This makes deployment really nice, you deploy to one place and the website is updated on all 100 machines. Each machine has a mapped folder "/z/www/PlayApp1" where the play app lives.
The issue is that when the service starts or stops the server.pid file is being written to that network location where the apps files live.
The problem is that as I bring up 100 nodes, the 100th node will override the PID file with it's pid and now that pid file only represents the correct process ID for 1 out of 100 nodes.
So how do I get play to store the pid file locally and not with the app files on the network share? I'll need each server's PID file to reflect that machines actual process.
We are using CentOS (Linux)
Thanks in advance
Josh
According to https://github.com/playframework/play/pull/43 it looks like there is a --pid_file command line option; it might only work with paths under the application root so you might have to make directories for each distinct host (which could possibly be symlinks)
I have 0 experience with Play so hopefully this is helpful information.
I don't even think it should run a second copy, based on the current source code. The main function is:
public static void main(String[] args) throws Exception {
File root = new File(System.getProperty("application.path"));
if (System.getProperty("precompiled", "false").equals("true")) {
Play.usePrecompiled = true;
}
if (System.getProperty("writepid", "false").equals("true")) {
writePID(root);
}
:
blah blah blah
}
and writePID is:
private static void writePID(File root) {
String pid = ManagementFactory.getRuntimeMXBean().getName().split("#")[0];
File pidfile = new File(root, PID_FILE);
if (pidfile.exists()) {
throw new RuntimeException("The " + PID_FILE + " already exists. Is the server already running?");
}
IO.write(pid.getBytes(), pidfile);
}
meaning it should throw an exception when you try to run multiple copies using the same application.path.
So either you're not using the version I'm looking at or you're discussing something else.
It seems to me it would be a simple matter to change that one line above:
File root = new File(System.getProperty("application.path"));
to use a different property for the PID file storage, one that's not on the shared drive.
Although you'd need to be careful, root is also passed to Play.int so you should investigate the impact of changing it.
This is, after all, one of the great advantages of open source software, inasmuch as you can fix the "bugs" yourself.
For what it's worth, I'm not a big fan of the method you've chosen for deployment. Yes, it simplifies deployment but upgrading your servers is an all-or-nothing thing which will cause you grief if you accidentally install some dodgy software.
I much prefer staged deployments so I can shut down non-performing nodes as needed.
Change your init script to write the pid to /tmp or somewhere else machine-local.
If that is hard, a symlink might work.

While parsing into a root folder how can I distinguish the upcoming is whether a file or a folder in C language?

I want to parse through a root folder which is entered by the user by using multi threading and multi processing at different versions.But how can I distinguish while I am parsing through a root folder whether the next is a folder or a file?To summarize I want to learn how I can distinguish the upcoming is a file or a folder.I wanna learn this because if it is a folder then I let opening this folder to a dynamically thread and/or process.If it is a file the existing thread or process can continue its work without any necessarity to create any different thread and/or process.I hope I can express my problem.I am waiting your answers.Thank you.
You can check whether a path refers to a file or directory using the stat() function, and checking the st_mode field on the returned structure (see http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html).
On Windows, you can use GetFileAttributesEx to get the file attributes, which you can check to see if it is a file or a directory.
Note that whatever you use may be subject to a race condition if the file system is being updated by another thread or process at the same time, as the file/directory may be deleted and/or changed after you checked it and before you access it.
Here are some quick samples. It will be up to you to thread from multiple root locations, call these recursively, and sync all the data.
Under *nix systems;
struct dirent *entry;
while ((entry = readdir("/root")) != NULL)
{
if (entry->d_type == DT_DIR)
{
// do something
}
}
closedir(dir);
Under Windows:
WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile(("C:\\root" + "*.*").c_str(), &findData);
do
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// do something
}
} while (FindNextFile(hFind, &findData));
FindClose(hFind);

How do I open a file with my application?

Ok, you know how in programs like Microsoft Excel, or Adobe Acrobat Reader you can click on a file in explorer and it will open with the associated program. That's what I want my application to do. Now, I know how to set up the file associations in Windows so that it knows the default program for each extension. My question is how do I get my application to open the file when I double click the file.
I've searched the web using google, I've searched the msdn site, and I've searched several forums including this one but I haven't found anything that explains how to accomplish this. I'm guessing it has something to do with the parameters of the main method but that's just a guess.
If someone can point me in the right direction I can take it from there. Thanks in advance for your help.
Shane
Setting up the associations in windows will send the filename to your application on the command line.
You need to read the event args in your applications main function in order to read the file path and be able to open it in your application.
See this and this to see how to access the command line arguments in your main method.
static void Main(string[] args)
{
System.Console.WriteLine("Number of command line parameters = {0}", args.Length);
foreach (string s in args)
{
System.Console.WriteLine(s);
}
}
When you open the file, with associations set as you described, your application will be started with the first argument containing the filepath to your file.
You can try this out in a simple way by printing out the args from your main method, after you open your application by clicking on the associated file. The 0th element should be the path to your file.
Now, if you successfully reached this point, the all you need to do now is read the contents of the given file. I'm sure you'll find more than plenty of resources here on how to do that.
I guess this is what you are looking for:
FileInfo fi = new FileInfo(sfd.FileName); //the file you clicked or saved just point
//to the right file location to determine
//full filename with location info
// opening file
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #fi.FullName;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
You will need to create registry-keys for your file-extension. This page describes well, which keys you'll need to set (see «3. How do I create file associations?»).

Resources