Brian Hvarregaard
Brian Hvarregaard

Reputation: 4209

How do I protect a file from direct download?

I have a webshop im developing, and some of the products need to be downloadable files (e-books, images, mp3 etc.). I have the files stored in a subfolder in my project and just a reference to them in my DB.

I dont want anyone with a direct file link to be able to download them, i want to control this myself. The download should only be available through my shop - that is, my customer area where the user can see all the e-products they have purchased.

How do i protect the files on my disk from being downloaded except by my code?

Upvotes: 2

Views: 2269

Answers (3)

hossein andarkhora
hossein andarkhora

Reputation: 798

from my point of view and grounded in my experience, the best way to prevent your file from downloading directly is to use a handler for downloading files. In my case, I add this code to my web config to prevent the file from direct download

    <system.webServer>
    <security>
        <requestFiltering removeServerHeader="true">
            <hiddenSegments>
                <add segment="FileUploadFolder"/>
                <add segment="File"/>
            </hiddenSegments>
            <verbs allowUnlisted="true">
                <add verb="GET" allowed="true" />
                <add verb="POST" allowed="true" />
                <add verb="*" allowed="false" />
            </verbs>
            <requestLimits maxAllowedContentLength="104857600" />
        </requestFiltering>
    </security>
</system.webServer>

as you can see, I added two folders with the names "FileUploadFolder" and "File" to this part of the webconfig. Until there, you prevent your file and directory. Now you need to let some of your users download some of your files, so I create this method and checked everything there

public ActionResult Download(string Filepath)
{

string filepath = "";
//this line use for deserialaize
filepath = QueryStringCoder.Decode(Filepath);

if (string.IsNullOrEmpty(filepath))
{
    return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
}

// Set the path to the file
string filePath = Server.MapPath(filepath);
if (!System.IO.File.Exists(filePath))
{
    return HttpNotFound();
}

byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
string fileDownloadName = Path.GetFileName(filePath);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileDownloadName);
}

Of course, I sterilize and deserialaize the filepath to enhance the security. Now you can check everything like access or credit to access the files.

I hope it would be useful.

Upvotes: 0

BilalAlam
BilalAlam

Reputation: 1227

There are several ways to prevent the IIS static file handler from serving out the files to a client.

1) Using section in configuration. You can use the hiddenSegments element to specify sub-segment paths that will not be served. Look at %windir%\system32\inetsrv\config\applicationhost.config for how this section is defined and used to prevent access to bin folder and other directories.

<configuration>
    <system.webServer>
        <security>
            <requestFiltering>
                 <hiddenSegments>
                      <add segment="subdirectoryName" />
                 </hiddenSegments>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

2) If you're looking for a simpler "poor-mans" way of blocking static file handler from serving out files, you can make the files "hidden" (from a file system attribute perspective). The static file handler will not serve out hidden files.

Upvotes: 5

Yishai Galatzer
Yishai Galatzer

Reputation: 8862

The easy answer: Don't place these files inside your site, place them outside the root of your site.

You can configure IIS to not serve requests to this folder with request filtering:

I'm assuming these paths are not paths you wanted to serve?

Upvotes: 1

Related Questions