Reputation: 11
We have got a site (eg abc.com) that is built in classic ASP and hosted on IIS 6.0. We have got a content folder in IIS 6.0, which consists of static files like PDF or XLS. We came to know recently that in various search engines, direct links of our website (www.abc.com/content/xyz.PDF) to PDF/xls are getting displayed in the search results and any user can access those files directly. As these files should be accessible to only logged in users, what is the way of preventing the anonymous users from accessing those files directly. We are using cookie and database for authenticating a valid user. The actions we have taken so far are:-
1) Included robots.txt in our website and through various webmaster tools, prevented the listing of direct links in the search results but we don’t think it is the optimal solution.
2) In our website there were various functionalities, through which the links to direct access of PDF’s were used to show it to the user. That we have stopped by not showing the direct URL path to the user.
Questions: - As we are using IIS6.0 and classic ASP, is there any way to implement anything at IIS level to prevent direct access of PDF/XLS files. Like, if the user types ‘www.abc.com/temp/xyz.PDF’ or the url consisting of .pdf/.xls should be intercepted by our asp or any other page first for the authentication(to check the user is logged in or not) and based on that it should allow to open.
Upvotes: 1
Views: 3511
Reputation: 1
David code falls in "intFilelength \ chunck" : chunck is 0. Insert a declaration:
Dim chunck
chunck = 2^13 '8K
Many others related questions tells also about:
Call Response.AddHeader("Cache-Control", "private, max-age=1")
Upvotes: 0
Reputation: 1613
Our company have a similar type of website, with lots of file that must not be accessible by anyone except the user who uploaded the file. We solved it like this:
<a href='downloadFile.asp?fileID=2341'>appManual.pdf</a>
Example of 'download-file-code'
dim filePath
'Is user logged on?
if Session("userID") > 0 then
'Good, the user is logged on.
'See if we can find the file the user is requesting
filePath = GetFilePAthFromDatabaseByID(request("fileID"))
if filePath != "" AND DoFileExists(filePath) then
'We found the file, send it to clients browser
SendFileToClient(filePath)
else
response.write "Sorry, we can't find the file with ID = " & request("fileID")
end if
else
response.write "Sorry, you are not allowed to download files unless you are logged on"
end if
Function DoFileExists(filePath)
dim fso
Set fso = Server.CreateObject("Scripting.FileSystemObject")
if fso.FileExists(filePath) then
'return value
DoFileExists = true
else
'return value
DoFileExists = false
end if
End Function
Function SendFileToClient(strFile,strFileEnd)
dim objText, strContentDisp, strFilename, strm, fso, fsofile, intFilelength, icount, oldScriptTimeout
strFilename = strFile
'Important that buffer is set to false to be able to handle big documents extending the buffer size
'the binary documents is sent in chunks to the client.......
'Leaving buffer to true will cut-off the binary stream at "buffer full" and the document is not readable by the client.
Response.Buffer = False
Set strm = Server.CreateObject("ADODB.Stream")
strm.Open
strm.Type = 1
Set fso = Server.CreateObject("Scripting.FileSystemObject")
if not fso.FileExists(strFilename) then
Response.Write("The corresponding file does not exist")
Response.End
end if
Set fsofile = fso.GetFile(strFilename)
intFilelength = fsofile.size
strm.LoadFromFile(strFilename)
'All the known filetypes below will be sent to the browser as a known MIME type, this will embed and open the documents
'directly in the browser.
'If some of the document types are to be opened in an full application instead of a browser embedded application, just comment out
'the case section containing the extension type and the file will be downloaded as an "application/octet-stream"
'Default Content-Disposition
strContentDisp = "filename=" & fsofile.name
select case ucase(strFileEnd)
Case "TIF", "TIFF"
Response.ContentType = "image/tiff"
Case "GIF"
Response.ContentType = "image/gif"
Case "JPEG", "JPG"
Response.ContentType = "image/jpeg"
Case "PNG"
Response.ContentType = "image/png"
Case "BMP"
Response.ContentType = "image/bmp"
Case "PDF"
Response.ContentType = "application/pdf"
Case "XLS"
Response.ContentType = "application/vnd.ms-excel"
Case "DOC"
Response.ContentType = "application/msword"
Case "TXT"
Response.ContentType = "text/plain"
Case "HTM", "HTML"
Response.ContentType = "text/html"
Case "XML"
Response.ContentType = "text/xml"
Case Else
strContentDisp = "attachment; filename=" & fsofile.name
Response.ContentType = "application/octet-stream"
Response.CharSet = "UTF-8"
End Select
Response.AddHeader "Content-Disposition", strContentDisp
'Remove setting of content-length when using IIS 7.5 since it does not work there
Response.AddHeader "Content-Length", intFilelength
'Set the Timeout to a large value when downloading big documents
oldScriptTimeout = Server.ScriptTimeout
Server.ScriptTimeout = 30000
For icount = 1 To intFilelength \ chunk
If Not Response.IsClientConnected Then Exit For
Response.BinaryWrite strm.Read(chunk)
Next
If intFilelength Mod chunk > 0 Then
If Response.IsClientConnected Then
Response.BinaryWrite strm.Read(intFilelength Mod chunk)
End If
End If
Response.Flush
Response.Buffer = True
'Reset the original timeout
Server.ScriptTimeout = oldScriptTimeout
strm.Close
Set strm = Nothing
set fsofile = Nothing
End Function
Example of custom 404-page
<%
dim downloadURL, url, urlPattern, arrTmpUrl, arrTmp
dim filename, fileID
' ** Base path for downloads (new)
downloadURL = "http://www.yourDomain.com/downloadFile.asp?fileID="
' ** Fetch QUERY_STRING (this tells us which page the user tried to access)
url = Request.ServerVariables("QUERY_STRING")
' ** URL pattern (did the user try to download a content file?)
urlPattern = "^(http://|http://www.|www.)yourDomain.(se|com):80/(ContentDir|AltContentDir)/[a-zA-Z0-9_åäöÅÄÖ .]{2,100}/?$"
arrTmpUrl = split(url,"404;")
if 1 = (UBound(arrTmpUrl) - LBound(arrTmpUrl)) then
if RegExTest(arrTmpUrl(UBound(arrTmpUrl)), urlPattern) Then
arrTmp = split(arrTmpUrl(UBound(arrTmpUrl)),"/")
filename = trim(arrTmp(UBound(arrTmp)))
'See if we can find the file name in database
fileID = GetFileIDFromDatabaseByName(filename)
if fileID > 0 then
downloadURL = downloadURL & Cstr(fileID)
'Redirect user to proper download link
response.redirect downloadURL
else
'We did not find a matching file
'Show standard 404 page
ShowStd404Page("We did not find a matching file")
end if
else
'The URL did not match the pattern
'Show standard 404 page
ShowStd404Page("no match")
End if
else
'The queryString did not look like as expected
'Show standard 404 page
ShowStd404Page("unexpected queryString")
End if
%>
Upvotes: 2