Hp Fortify: Path Manipulation erroe - c#

I am getting the hp fortify warning for the following code:
FileStream fs = null;
StreamWriter writer = null;
try
{
fs = new FileStream(sFileName, FileMode.Open, FileAccess.Write);// Path Manipulation error
writer = new StreamWriter(fs);
I am not deleting the file in my code, So if user provide the path of some config its safe from my code, So I am not sure why this is giving warning?
Can anyone please suggest me any alternative?

Fortify doesn't know what the file is, where it is, or anything else. Write the code in a way that Fortify can see that the application is protected from malicious users.
Validate the path so that I can't pass a file named ../../../../cmdshell.aspx, don't rely on filesystem permissions. I'm assuming that at some later time you want to read that file, do the same kind of validation there.
I would also validate MIME type, file size, and check for weird characters.

Related

File gets locked after setting attributes

I have a method which saves the object into the file. The object gets modified and saved multiple times. The problem is that when I'm trying to save object for the second time into the same file, I'm getting the UnautorizedAccessException. Here is the code:
public void Save(string path)
{
string fileName = String.Format("{0}\\{1}", path, DataFileName);
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, this);
File.SetAttributes(fileName, FileAttributes.Hidden);
}
}
What's the most interesting, is that if I comment the line
File.SetAttributes(fileName, FileAttributes.Hidden);
problem disappears. How comes? And how can I solve this problem?
MSDN says this about FileMode.Create:
Specifies that the operating system should create a new file. If the
file already exists, it will be overwritten. This requires
FileIOPermissionAccess.Write permission. FileMode.Create is equivalent
to requesting that if the file does not exist, use CreateNew;
otherwise, use Truncate. If the file already exists but is a hidden
file, an UnauthorizedAccessException exception is thrown.
Which is exactly what you are seeing. So the solution seems to be either use a different mode, or as suggested in the comments, unhide -> save -> hide.

Empty File Content Which Used by Another Process

I have a log file of my application, I do some manipulation by sided application on the log file.
At the end of the manipulation, I want to delete the file - which is not possible becuase file is used, so I just want to empty it - delete the contents.
I tried:
using (FileStream stream = File.Open(query.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
using (StreamWriter writer = new StreamWriter(stream, true))
{
writer.Write("");
reader.Close();
}
}
and:
using (FileStream stream = File.Open(query.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
stream.SetLength(0);
stream.Close();
}
and:
System.IO.File.WriteAllText(#"path", string.Empty);
Notihg works.
How to overrride file content?
Not at all. It will crash, because file is being used by another process
Well, it probably isn't another process, it probably is yours. You'll have to do this after closing the log file. But there's a more general fix for that. Go back to the code that creates the log file and add the FileShare.Delete option.
This option allows deleting files that are in use. You can now simply use File.Delete() in your code, even if the log file is still opened. This will put the file in a "delete pending" state, anybody that tries to open it will be slapped with an access denied error. The file on the disk will automatically disappear when the last handle to the file is closed.
Yet another useful option is FileOptions.DeleteOnClose. Now it is completely automatic, the file is automatically deleted without you having to do anything at all. I can't tell which one is best in your case, you probably want to avoid deleting the log file when your program crashed so FileShare.Delete is best.
You can use the below code too
System.IO.File.WriteAllText(#"Path of your file",string.Empty);

File already being accessed error

I have a few files in \AppData\Roaming that my app is writing to. I create the files when the application starts like this:
private void Form1_Load(object sender, EventArgs e)
{
DirectoryInfo _File = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), #"MyApp\myfile.txt"));
}
Later, when I write to the file with a button click, I get an error saying that the file is already in use and cannot be accessed. How would I fix this?
The code to write to the file is correct because when I remove the code above and make the files myself, the application writes to them without any issues. Therefore, I dont think the problem is with the code I use to write to the files. But, here it is for reference:
var myfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), #"MyApp\myfile.txt"));
StreamWriter sw = new StreamWriter(myfile);
sw.WriteLine(textBox1.text);
sw.Close();
Thanks in advance for any help!
There are a few concepts at play here and I am not sure that we have enough information to definitively address the root problem, but I will give you a few pointers.
You need to be aware of the FileMode, FileAccess and FileShare enumerations.
The first, FileMode, specifies what you intend to do with regard to the file's existence. There are various options, documented in the link above. mI don't think that you have a problem here, but it bears mentioning.
The second, FileAccess, concerns your intended interaction with the file (read, write, or both). If you ask for access to read, then anyone else who opens the file or had it open already (including that web browser control) must have allowed sharing with other readers.
The final one, FileShare, defines who you are willing to share access to the file with. You can specify that others can read it, others can write to it, both, or neither.
The code that you are using is accessing the file using the very simplest defaults, which may be incompatible with the WebBrowser's access mode. Here's what I'd suggest instead:
var myfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), #"MyApp\myfile.txt"));
using (var fs = new FileStream(myfile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)) {
using (var sw = new StreamWriter(fs)) {
// You probably want to move to the end of the file before writing...
fs.Seek(0, SeekOrigin.End);
sw.WriteLine(textBox1.text);
sw.Close();
}
}
This very clearly expresses your intent, as well as the fact that you are willing to share with others who might read or write (we know the webbrowser will not write to the file, but for some reason maybe it is trying to open it with write intent anyway).
For file operations (as well as anytime your are accessing unmanaged resources) your best bet is to only grab a handle to the file long enough to perform the operation you want and then release it.
In your case, you are opening the resource, then trying to open it again later. Change this. Don't create the files until you are actually going to do something with it. Also, look into the USING clause. You want to release it as soon as you are done reading or writing from it.
Try to Access the FileInfo object to create/append/write files as follows, the file is already been taken by FileInfo class,
use as following,
FileInfo fi1 = new FileInfo(path);
//Create a file to write to.
using (StreamWriter sw = fi1.CreateText())
{
sw.WriteLine("Hello");
sw.WriteLine("And");
sw.WriteLine("Welcome");
}
//Open the file to read from.
using (StreamReader sr = fi1.OpenText())
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
Try using using.
using (StreamWriter sw = new StreamWriter(myfile))
{
sw.Write(textBox1.text);
}

Auto-loading file on program startup

Ok, so here's a bit of code. I'm having an issue where I want to save to a pre-defined location, and I want to have a pre-defined name for a file. Neither FileStream nor StreamWriter allows you to set both of those paramters as far as I can tell, based on what I've seen on MSDN.
FileStream fs = new FileStream("PermaServerList", FileMode.Create, FileAccess.Write);
StreamWriter hiddensw = new StreamWriter(#"Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments", false);
So, if you look at that, how would I get it to save a file called "PermaServerList" to the location "My Documents", regardless of the version of Windows they're using? I don't want to hard code in a location, I want it to always be whatever My Documents is in their particular version.
Alternatively, the idea behind this is that every time the program starts, I want it to load the list they last saved automatically. Is there a -simple- way to do this? Right now, the idea is that I'll just save to their chosen location, and then make a second copy in my pre-defined location and just load that on program startup. Ideas?
Yes, you're simply trying to store and read user data, which can be easily dealt with using app.config settings file.
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "PermaServerList.txt");
using (StreamWriter writer = new StreamWriter(fileName)) {
writer.WriteLine("wooo");
}
That's how you'd write to the file, for example. The SpecialFolfer enum will get you the location of the "My Documents" directory every time, regardless of what version of Windows they're using, or whether the folder is mapped to a network location, etc.
I'm not sure what you mean by "load the file when the program starts"; I assume your issue is that you need the directory location, beyond that it's just a question of opening it as a stream and working with it.

File Encryption and Decryption issue

I've been playing around with encrypting and decrypting files in VC# Express 2010.
All the tutorials and documentation I've seen require two FileStreams in order to encrypt the file - one for reading the unencrypted version, and the other for encrypting. When I actually wrote the code it kept throwing an error telling me it could not open the file because it was opened by another process at the output filestream.
I'm assuming that's because the file is opened by the input filestream. So that means I have to specify a different filename? So even after the operation is successful I'll now have the original unencrypted file in the directory and a separate encrypted version? Doesn't that defeat the point? Or am I doing something wrong here? My code is similar to this...
public string filename = "test.xml";
using (FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read))
using (FileStream output = new FileStram(filename, FileMode.Open, FileAccess.Write))
using (....all the crypto stream and transform stuff...)
{
...do the encryption....
}
You're right but it's not defeating the point. The (streaming) crypto APIs are intended to encrypt from Src to Dst. Think encrypting output while sending/receiving over a network etc. This keeps them simple, as they should be.
You complicate the issue by using the same file for Src and Dst. That is not totally impossible but like Copying a File over itself it needs some extra care.
Consider that in general, encrypting will increase the File size. So it is not safe to Encrypt a file in place. Decrypting might be, but I wouldn't risk it.
What you need is a Temp file and a rename action after completion.
In your example, you can't create a separate filestream for both input and output on the same file, but you can create a handle that will read and write. The FileAccess enum has the flags attribute, so you'd just say var handle = new FileStream(filename, FileAccess.Read | FileAccess.Write); The obvious downside to this is you are going to have data lost if your encryption doesn't complete successfully.
I recommend having a separate file for the output though, atleast that way you won't lose data if your program breaks unexpectedly. If the encryption completes successfully, then delete the original and rename the encrypted file with the original file name.
Use File.ReadAllBytes. Then those bytes post to your encryptor, must work.
There is another parameter where you can specify whether or not to allow another process to read or write to the file.
openFile is a string that represents the file name.
using (FileStream fileIn = new FileStream(openFile, FileMode.Open, FileAccess.Read, FileShare.Write))
using (FileStream fileOut = new FileStream(openFile, FileMode.Open, FileAccess.Write, FileShare.Open))
This way, you can read and write to the same file.
while (myfileStream.Position < fileLength)
{
fileIn.Read(buffer, 0, 51200);
buffer = encrypt(buffer);
fileOut.Write(buffer, 0, 51200);
}
While this is easy and you don't have to write to a temporary file or have to move/rename etc, this can be really dangerous because if the encryption breaks suddenly for some reason, you will lose data!
Also, the encrypt function is something I implemented. AesCryptoServiceProvider along with CryptoStream can be used :)

Categories