How do I protect a file from direct download? - asp.net-mvc

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?

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.

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?

Related

Configure apple-app-site-association file and upload on server

I am new on iOS development. I am implementing Universal Links in iOS App with ASP.net application.
I have define my associate domain in capabilities under Associated Domains:
applinks:www.abcd.com
And also configure in App Ids on Apple Developer Account. I think app side work is all set .
But I think problem with apple-app-site-association file.
I have written json in a simple text file like below
{
"applinks": {
"apps": [],
"details": [
{
"appID": "8T8932TY.com.AppNameā€,
"paths": ["*"]
}
]
}
}
Now I am stuck here. My application targeting on iOS 9 and above. I am confused that what is the extension of this file with naming apple-app-site-association. If I need to signed in with new certificates or not. And how upload it on server side.
Please guys help me out. I am searching lot for this but not get satisfactory answer.
Thanks
Your example JSON looks fine if substituted with real values for the AppID/AppName. You may want to be specific about what routes you handle but that's up to you - it's a better user experience to only try to handle routes that there's some chance you'll be able to handle, rather than opening your app for every link on your domain and kicking the user out to Safari again if that turns out not to be true.
The apple-app-site-association file should not have any file extension, and should be served from the root of your site, https://example.com/apple-app-site-association, and/or from https://example.com/.well-known/apple-app-site-association.
You say you're supporting iOS 9 and above - the change to check the .well-known route, which is checked first, came in iOS 9.3, so if you want to support below that OS, you're best off putting the file in both locations. See this answer for details.
It's also important that the file is served with the correct MIME-type, for Universal Links it can be served as application/json, and there's no need to sign/encrypt it. Getting it served with the correct MIME-type can be a little annoying if you're not familiar with configuration on your web server, as typically servers will determine the MIME-type from the file extension. You can't give it an extension, as iOS won't check the url with an extension and (IIRC) redirects are not allowed so you can't fake it by doing that either.
So that's a summary of what you're trying to accomplish, but how you do that depends on the web server you're using. For an ASP app that's likely to be IIS, in which case this question and its answers may help you configure your web server correctly. The details of how you upload a file to the root of that server will very much depend on how you've configured it as well.
There is no extension for this apple-app-site-association file. This is just a plain file. You have to host it on the top level of your domain meaning the file location will be https://www.abcd.com/apple-app-site-association Once you host it you can check/validate by using this link https://branch.io/resources/aasa-validator/
For detailed info please refer: https://blog.branch.io/how-to-setup-universal-links-to-deep-link-on-apple-ios-9/
This worked for me.
Created an empty .NET Core project and deployed it to the corresponding Azure web app service.
Using, Advanced tools in Azure portal, nvaigated to the Kudu files of the deployed app service.
Inside the folder "site/wwwroot/wwwroot" created a new folder named ".well-known".
Inside the newly created folder, created a new file named "apple-app-site-association.json".
Edited the newly created json file to hold the app details.
Modifed the file "site/wwwroot/web.config" for the following reasons:
a) Since iOS always calls the URLs without file extension mentioned (https://webapp-sftpint-employeeapp-dev.azurewebsites.net/apple-app-site-association)
we need to forcefully reqrite such URLs to have the file extension. Hence, added the rule in web.config
b) Since the response header should have "application/json" for the content returned from the static file "apple-app-site-association.json",
we added the explicit mentioning of the mimeType as "application/json".
So, the web.config file looks somewhat like this. (only the 'rewrite' and 'staticContent' blocks needs to be added additionally)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\yourproject.dll" stdoutLogEnabled="false" stdoutLogFile=\\?\%home%\LogFiles\stdout hostingModel="inprocess" />
<rewrite>
<rules>`enter code here`
<rule name="apple_json_file">
<match url="^apple-app-site-association" />
<action type="Rewrite" url=".well-known/apple-app-site-association.json" />
</rule>
</rules>
</rewrite>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
</location>
</configuration>

Prevent direct access to files on IIS server

I have two servers, one for my mvc application and the other one as a storage for large files like images etc, both running on Windows Server 2012 R2.
How can I prevent direct access to the files on storage server?
say, mvc is on IP1/ and storage is on IP2/.
Link to a file would be like: IP2/MediaFiles/2015/12/image0001.jpg.
I need only GET requests from IP1 have access to the link above. How?
UPDATE
server1 on IP1 needs to be free of file sharing since media server is on IP2 and we don't need to load files per request on server1's RAM. (server1 will crash soon!) therefore no HttpHandler can be used!
In this question I'm looking for a way to prevent unauthorized users from accessing files on server2 (on IP2) by entering direct address.
Alright I found the solution!
Working on such problems needs some trick gathered from different sources based on your needs. I was looking for a way to prevent unauthorized users from accessing files on file server which is different from your main server. (the main server is authorizing users)
First of all, I blocked ALL incoming requests containing the Url pattern of my sensitive files using IIS rules. Then I wrote some lines of code for file server to handle Http requests using IHttpHandler interface in order to 1) check authorization rules and 2) send exact files to clients without converting them to byte array. And lastly, I used This Link to prettify links to file server! That's all folks ;)
Now:
physical link [blocked] : IP2/MediaFiles/2015/12/image0001.jpg
virtual link : IP2/Please/Find/A/File/By/DB/Id/1 ---> image0001.jpg
All what you wanted is in Web.Config file. You should place it in the root directory of your file storage server if you using IIS there.
In <system.webServer> node you should place this code:
<security>
<ipSecurity allowUnlisted="false"> <!-- this line blocks everybody, except those listed below -->
<clear/> <!-- removes all upstream restrictions -->
<add ipAddress="127.0.0.1" allowed="true"/> <!-- allow requests from the local machine -->
<add ipAddress="IP1" allowed="true"/> <!-- allow the specific IP of IP1 -->
</ipSecurity>
</security>
This rule will be accepted for all subfolders of root folder. If you need to block requests only for specific folder you should place your Web.Config there.

Recommended practice for restricting ImagerResizer module to just one specific route/sub-directory?

What is the recommended practice for restricting ImageResizer to only act on images within a specified sub-directory (in my personal case requiring watermarks only on images within a certain directory via PostRewrite, but apart from a couple sub-directories, I really don't want site-wide images even touching the InterceptModule if I don't have to)?
Configure ignore routes somehow via MvcRoutingShim as referenced without an example in ImageResizer.net documentation.
<location ...> in Web.config:
<location path="some-path/some-directory" inheritInChildApplications="false">
<system.webServer>
<httpModules>
<add name="ImageResizingModule" type="ImageResizer.InterceptModule"/>
</httpModules>
</system.webServer>
</location>
Application.BeginRequest filter out on path.
Or really late filter on PostRewrite (Config.Current.Pipleline.PostRewrite).
Or?
Details:
ASP.NET MVC 5.2.3 (Integrated)
ImageResizer 4.x
IIS 7 (Windows Server 2008 R2)
Handle Config.Current.PostRewrite and set process=no and cache=no in the event parameters (querystring). This will disable ImageResizer interaction with the request.
As mentioned in Configuring ImageResizer to only work in certain directories, you cannot make HttpModules location-specific. They are application-wide, always.
By default, ImageResizer doesn't do anything to images unless you specifically request it via the querystring. It does (with authorizeAllImages="true") permit you to control access via AuthorizeImage, as well as perform URL rewriting via Rewrite and PostRewrite events.
If the images are being served from a VirtualPathProvider, it will enable that to work by assigning the request to StaticFileHandler; but if the images are physical files, it does nothing.
If you want true isolation, you can always set up a child app (sub-application) with a separate application pool, mounted in a subdirectory.

.OTF font not being deployed to Azure

I have an MVC 4 application with an .otf font in the /images folder. It works on my desktop, but when I deploy to azure I get a 404 when trying to access /images/myfont.otf
The font already has the Build Action property set to 'Content'
How can I force Azure to pick this up?
You probably need to configure the IIS to properly serve this file type. You do this by adding the following to the <system.webServer> element in Web.config:
<staticContent>
<mimeMap fileExtension=".otf" mimeType="font/otf" />
</staticContent>
More info
http://www.big.info/2013/06/how-to-use-otf-opentype-format-fonts-on.html
Place the following in web.config in the system.webServer configuration:
<system.webServer>
<staticContent>
<remove fileExtension=".otf" />
<mimeMap fileExtension=".otf" mimeType="font/otf" />
</staticContent>
</system.webServer>
HTTP Error 404 means the content is not found on server. It does mean that when you deploy your application to Windows Azure the content was not in the package.
As you suggested above that you do have .OTF set as content it means that you are asking compiler to treat it as static file and don't build it however specific file will not be copied to the final output folder to be the part of final CSPKG. You would need to set "Copy to output directory" as "copy always" so it can be part of CSPKG and deployed to Azure Cloud service.
Once you set file properties correctly and build your application, you can manually visit to your output folder to the verify that file is there as well as your CSPKG just by unzipping it.
The problem for me is that the files weren't included with the project. They were in the correct file path ((project)/Content/fonts/*), but not considered part of the project (i.e. references by the *.csproj file). The solution was to right click the fonts folder and choose the Include in Project option.
My best bet is that you've got relative paths to your font files within your css.
Are you getting a 403 Forbidden? That might indicate that your filepath's are off.
Try changing your paths from ../filename.otf to something like /Styles/filename.otf (or whatever your path is)

Prevent IIS7/ASP.NET locking directory with images

I have an ASP.NET webapp using the ASP.NET MVC 2 framework. It allows users to upload files to an uploads folder. The issue occurs when an image within a sub-folder is accessed by a web browser:
http://mywebapp/uploads/image_gallery/sub_folder/image.jpg
The uploads folder is static and can't be modified by users, but anything below it is intended to be modifiable.
In the above example, the image_gallery folder becomes locked because w3wp.exe appears to create a handle on the sub_folder directory (using process explorer by sysinternals). I am still able to rename the sub_folder directory and the handle seems to stay with it after a rename, but i can't rename the parent folder (image_gallery in this case).
I can still browse within the folder and view other images and files etc. But can't rename the parent folder.
As this is using the MVC 2 framework i've put in an exclusion for the uploads folder like so:
routes.IgnoreRoute("upload/{*pathInfo}");
into global.asax, so i'm assuming that ASP.NET is serving up those images directly (outside of the MVC framework)
So I guess my question is, is there any way to prevent IIS from putting a handle on specific directories or forcing it to remove a handle? Is the MVC 2 framework doing something tricky even though i have the ignoreroute specified?
Thanks in advance for any tips!
I had the same problem, and after much investigating I've found the culprit:
Web.config
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Setting this option (which makes all http modules run on ALL files, static ones included) to false fixed it for me.
I believe, directory handle gets created in worker processor because ASP.NET typically watches the file system for changes - this allows it to respond to change/addition of config files, new dlls etc.
I suggest that you move from the concept that users can control physical directory structure on the web server. Typically, what user can create is an logical directory structure but physical structure would be controlled by your program logic. Your logic will store the logical structure created by user and its mapping with actual physical structure on the web server.

Resources