Restrict .xml file and .cs file from download - c#

In one of project i saw the below code.
string FileName = Request.QueryString["filename"];
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(Server.MapPath("~/" + FileName));
response.Flush();
response.End();
which is used to download file from server. Now if someone changes filename (like web.config) in query string manually then it downloads config file also.
So please share your knowledge how to restrict from download based on file extension.

That is usually done in IIS. But, if you wanna to it programmatically:
string[] forbiddenExtensions = new string[] {".config", ".abc", ".xml" };
FileInfo fi = new FileInfo(FileName);
if (forbiddenExtensions.Contains(fi.Extension))
{
//throw some error or something...
}

First of all, you'll have to ask yourself whether you want to write code to let users download files present on the file system. The web server itself is perfectly fine handling file downloads and preventing access to files that shouldn't be shared.
If you're sure you want to do this, for example because you want some code to run before every download, then you should look at creating a handler instead. Then the web server will still first determine permissions and whatnot, in order to prevent malicious users from downloading sensitive files, and when allowed, your code will run before the download.
That being said, you don't want to serve files for download from your web root. Instead create a dedicated directory, say, "Downloads", and host your files for download from there. Then use filename = Path.GetFileName(filename) to prevent the user from navigating outside that directory (using .. and/or \).

Related

Transfer file from remote server to local in MVC

I am working with an ASP.NET website that is deployed on a remote server using IIS. When a user logs on to access the site, they have an option to download a file. However, the file gets saved to the remote server rather than the user's local computer.
Is there a way to transfer/copy the file that is saved on the remote server to the user's own local computer? Or some way that I can indicate that the file needs to be saved to the local computer instead of the remote server?
Below is the code I am using to download the files (csv and mat). The mat file download is more complicated than a typical file download, and requires a NuGet package extension. So there is not much flexibility in how the file is create and downloaded, which is why I think it may be simpler to transfer the file from the server to the local computer after everything is saved.
//matCheck and csvCheck are booleans that allow the user to pick one or both of the file formats to download as.
if (matCheck == true)
{
//MLArray and MatFileWriter are part of the nuget extension I mentioned above
List<MLArray> mlList = new List<MLArray>();
mlList.Add(structure);
new MatFileWriter(new FileStream(downloadsPath + FN + ".mat", FileMode.Create), mlList, false);
}
if (csvCheck == true)
{
//sb is the variable created in earlier code storing the csv data to download
System.IO.File.WriteAllText(downloadsPath + FN + ".csv", sb.ToString());
var response = System.Web.HttpContext.Current.Response;
response.BufferOutput = true;
response.Clear();
response.ClearHeaders();
response.ContentEncoding = Encoding.Unicode;
response.AddHeader("content-disposition", "attachment;filename=" + FN + ".csv");
response.ContentType = "text/plain";
response.Write(sb.ToString());
response.End();
}

Failed network error - When downloading a File

I have this code to download files:
WebClient req = new WebClient();
HttpResponse response = HttpContext.Current.Response;
string filePath = file.Path;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = true;
response.AddHeader("Content-Disposition", "attachment; filename=\"" + _fileName + "\"");
response.ContentType = Path.GetExtension(filePath);
byte[] data = req.DownloadData(filePath);
response.BinaryWrite(data);
response.Flush();
response.Close();
Some of the variables like file.path and _fileName are from a list I created to save information from the upload control in asp.net webforms.
This download code works great on all browsers in my computer, but when I passed it to a local machine, it doesn't work at all, on firefox it downloads but I can't open the file, and on chrome it says Failed Network Error.
The files are uploaded on my C: drive, but on the machine they are uploaded on a fileshare that simulates a C: drive. I used logs to understand if he was getting the file properly, and this is what I get:
\\10.50.237.18\opt\Liferay_DATA\eforms\20180126\70edd349-8cd1-4518-a55e-d49dcadb3f7c\0eadc797-7817-4e99-b39a-35f179ec1c5d.pdf
For What I understood, the file is being upload properly. But when I'm trying to download it, it's not working. I know this is a common question, but I check several solutions and I can't seem to make it work. Could you please help me understand what the problem is? Maybe the response.header?

Download Video MP4 file from download URL

I am trying to download a video file (MP4) sitting in Cisco Webex server with C#. The URL I have is a download URL which is not exactly file location. Download URL is actually getting browser to download video file.
I tried 'WebClient' but with no luck. Mine is a console application, therefore I cannot use 'HttpWebRequest' and add the MIME type to IIS. Below is the code that I tried using:
WebClient client = new WebClient();
client.DownloadFile("https://webex.com/lsr.php?RCID=9853e32d921d", #"C:\\Video.mp4");
For now, with my code I am starting an instance of the browser with 'Process.Start("URL")' and have changed the default download location. I know this is not the correct solution therefore I request suggestions.
I don't know if you're still looking for an answer to this or not but I was recently looking for something similar. I wanted to download a video from my web page to the client's browser from my server. I did this and it is successfully downloading.
var fileName = Path.GetFileName( filePath );
HttpResponseBase.Response.ClearContent();
this.Response.ClearHeaders();
this.Response.ContentType = type;
this.Response.AppendHeader( "Content-Disposition", "attachment; filename=" + fileName );
this.Response.BinaryWrite( System.IO.File.ReadAllBytes( filePath ) );
this.Response.End();
I hope it helps!

Force browser to open DOCX files in full word not Word plugin

I have a web application which lists DOCX files within a directory when the users click a link the document opens within the browser using the word plug in. Is it at all possible to force the browser to open the document in full word instead of the word plug in?
This application is running on a corporate network and i have no access to amend any settings on the machines it can only be done from the web server.
They are currently using IE6 and a browser upgrade is not due for several months.
I suspect the answer is it cant be done.
I had a similar problem. I achieve a solution using a Generic Handler.
Add a new GeneriChandler.cs to you project and in the ProcessRequest do this code:
//Search for the file by querystring or other method you did, like name.
string fileId = context.Request.QueryString["fileId"];
FileInfo file = new FileInfo("C:\\" + fileId + ".docx");
context.Response.Clear();
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
context.Response.AddHeader("Content-Length", file.Length.ToString());
context.Response.ContentType = "application/octet-stream";
context.Response.WriteFile(file.FullName);
So if your handler is called MyHandler.ashx you can call the file in the link like that :
File 1

download file to a specific location with Response.BinaryWrite and Server.Mappath possible?

I have varbinary data associated with a file in the DB. This is the code I'm using to download this file on clicking a link -
//a is my attachment object
var r = context.Response;
r.AddHeader("Content-Disposition", "attachment; filename=" + a.FileName);
r.Charset = "";
r.ContentType = a.MIME;
r.BinaryWrite(a.Content.ToArray());
Currently, this file gets downloaded to the Downloads folder. Is there any way to create a new folder in the users system and have this file download there? I read that server.mappath can be used with r.WriteFile, but I'm not quite sure. Can this be done?
No, this is not possible. Otherwise, people could maliciously write all manner of files into specific system directories. Once you send the file down to the user, the control is now out of your hands.

Categories

Resources