![]() |
|
|
#1 (permalink) |
|
Registered User
Join Date: Jul 2004
Posts: 34
|
How to stop public access to files
Hi
I have a site (in classic ASP with SQL database) that has a login page & all subsequent pages are checked to ensure only logged in users can view them. I have SQL injection protection code to stop any dodgy login attempts. I have a couple of questions: (1) what's the general opinion on whether this level of security is adequate? I'm hardly trying to stop people looking at National Security documentation, just don't want Joe Public to see the pages (they get kicked back ot the login page if they try & access a page if not logged in). (2) My registered users are allowed to upload files and I store these in an uploads folder under wwwroot. However, there is nothing to stop Joe Public typing in the URL of the uploaded file & viewing it direct, as I cannot implement my ASP security check on, for example, an uploaded Excel file. Would really appreciate any thoughts or recommendations. Cheers Alan |
|
|
|
|
|
#2 (permalink) |
|
Administrator
Join Date: Oct 2003
Posts: 1,484
|
What you talk about is potentially quite a large security issue. We had a problem with a site a year or so ago who had a similar set up. An unauthorised user managed to upload his own webpage which gave him access to a large part of the server. Since then Catalyst2 has not been as open with its security policy and should that attack happen again the most it could do is compromise your own site.
My strong advice to you is - get it fixed. If you can't find a way of fixing it using what you know then Catalyst2 do offer an extra to password protect individual folders.
__________________
Jason Robbins jason@catalyst2.com |
|
|
|
|
|
#3 (permalink) |
|
Registered User
Join Date: Jul 2004
Posts: 34
|
Thanks for that Jas, although I'm not 100% sure I understand which part of my issue you were replying to.
Are you saying that my general level of security (ie having logins & checking logged-in status on each page) is inadequate? If so, what other solutions might be suggested? If you are refering to allowing the logged in users to upload files, I thought this was reasonably common practice. Lastly, if it's the fact that some of the authorised users might maliciously upload code, then I don't know what else I can do. Is this where I should create an "uploads" folder outside the wwwroot folder so any uploaded scripts cannot be run through the website? Apologies for all the questions & if I've misunderstood your response! Cheers Alan |
|
|
|
|
|
#4 (permalink) | |
|
Administrator
Join Date: Oct 2003
Posts: 1,484
|
Quote:
Creating a folder outside the wwwroot would be good, the folder password protect extra on your upload folder would be the other option.
__________________
Jason Robbins jason@catalyst2.com |
|
|
|
|
|
|
#6 (permalink) |
|
Registered User
Join Date: Jul 2004
Posts: 34
|
With regard to password protecting the upload folder, how would this stop an authorised user uploading a dodgy script & running it? Presumably if they have access to the site (ie are authorised), they will need the password to the uploads folder? Or is this folder password protected and only my code has the password in order to write files to it?
Apologies if they are silly questions but I'd like to get to the bottom of the correct solution! Cheers again Alan |
|
|
|
|
|
#7 (permalink) |
|
Bring me your problems :p
Join Date: Jan 2003
Location: /dev/ahhhhhhhhh
Posts: 3,537
|
Al,
No you are correct in that regard, password protecting the upload folder wouldn't stop people with access uploading anything dodgy, however it does narrow the scope somewhat as I assume you wouldn't give out the details to everyone? |
|
|
|
|
|
#8 (permalink) |
|
Registered User
Join Date: Jul 2004
Posts: 34
|
Hi
Sorry, been up to other things so haven't replied. I would only allocate the password to trusted individuals, so I don't think it woul dbe a problem. Going back to the downloads folder outside wwwroot, how could this work? What would the url be for accessing, for example, a document called test.doc on the domain www.mydomain.com? Currently it would be www.mydomain.com/downloads/test.doc, but as discussed earlier this would bypass any authority level checking I do in my scripts. If I upload test.doc to the root of my domain, or into a downloads folder that is at the same level as the wwwroot folder, how do I let my users get to it? www.mydomain.com/testdoc sends people into the wwwroot folder. Many thanks Alan |
|
|
|
|
|
#9 (permalink) |
|
Administrator
Join Date: Oct 2003
Posts: 1,484
|
That's the point - there would not be a url to access the uploaded files from. Thus the end user could not upload something malicious and then execute it. This sounds like it would work for your situation.
You could make a page that streamed the files from they're store directly to the users browser (again would mean they couldn't execute any code). This is something I do quite frequently in my solutions.
__________________
Jason Robbins jason@catalyst2.com |
|
|
|
|
|
#11 (permalink) |
|
Administrator
Join Date: Oct 2003
Posts: 1,484
|
I dont have a nice neat example kicking around. Everytime I use the theory it ends up being wrapped in many layers of business logic but the below code (writen in c#) should give you a rough idea as to the code needed, a lot of it could be compacted down into something much more simple.
Code:
private void GetFileFromCache(int fileID)
{
Data.File file;
byte[] fileData;
try
{
file = new Data.File(fileID);
fileData = Data.FileCache.GetFileBytes(fileID);
}
catch (System.IndexOutOfRangeException)
{
return;
}
catch (System.IO.FileNotFoundException)
{
return;
}
catch (System.IO.DirectoryNotFoundException)
{
return;
}
Response.Clear();
Response.ContentType = FileContentType(file.FileExtention);
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.Name + "\"");
Response.AddHeader("Content-Length", fileData.Length.ToString());
Response.OutputStream.Write(fileData, 0, fileData.Length);
Response.End();
}
private string FileContentType(string extension)
{
switch (extension.ToLower())
{
case ".doc":
return "application/msword";
case ".zip":
return "application/zip";
case ".xls":
return "application/vnd.ms-excel";
case ".gif":
return "image/gif";
case ".jpg":
return "image/jpeg";
case ".wav":
return "audio/wav";
case ".mp3":
return "audio/mpeg3";
case ".mpg":
return "video/mpeg";
case ".rtf":
return "application/rtf";
case ".pdf":
return "application/pdf";
case ".ppt":
return "application/x-mspowerpoint";
case ".bmp":
return "image/bmp";
case ".tif":
return "image/tiff";
case ".html":
return "Text/HTML";
case ".htm":
return "Text/HTML";
case ".docm":
return "application/vnd.ms-word.document.macroEnabled.12";
case ".docx":
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
case ".dotm":
return "application/vnd.ms-word.template.macroEnabled.12";
case ".dotx":
return "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
case ".potm":
return "application/vnd.ms-powerpoint.template.macroEnabled.12";
case ".potx":
return "application/vnd.openxmlformats-officedocument.presentationml.template";
case ".ppam":
return "application/vnd.ms-powerpoint.addin.macroEnabled.12";
case ".ppsm":
return "application/vnd.ms-powerpoint.slideshow.macroEnabled.12";
case ".ppsx":
return "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
case ".pptm":
return "application/vnd.ms-powerpoint.presentation.macroEnabled.12";
case ".pptx":
return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
case ".xlam":
return "application/vnd.ms-excel.addin.macroEnabled.12";
case ".xlsb":
return "application/vnd.ms-excel.sheet.binary.macroEnabled.12";
case ".xlsm":
return "application/vnd.ms-excel.sheet.macroEnabled.12";
case ".xlsx":
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
case ".xltm":
return "application/vnd.ms-excel.template.macroEnabled.12";
case ".xltx":
return "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
default:
return "application/octet-stream";
}
}
public static string GetFileLocation(int fileID)
{
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
return FindFileCacheFolder(new FileInfo(new Uri(a.CodeBase).LocalPath).Directory) + @"\" + fileID + ".dat";
}
protected static string FindFileCacheFolder(DirectoryInfo currentDir)
{
if (currentDir.GetDirectories(RelativeFileCachePath).GetLength(0) > 0)
return currentDir.GetDirectories(RelativeFileCachePath)[0].FullName;
else
return FindFileCacheFolder(currentDir.Parent);
}
public static byte[] GetFileBytes(int fileID)
{
return System.IO.File.ReadAllBytes(GetFileLocation(fileID));
}
__________________
Jason Robbins jason@catalyst2.com |
|
|
|
|
|
#12 (permalink) |
|
Registered User
Join Date: Jul 2004
Posts: 34
|
All sorted.
Thanks for the pointers Jas - much appreciated. I have now sorted out a directory behind wwwroot & streamed the required documents direct to the browser - works a treat for all required document types! Cheers Alan |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|