Secure download script (Classic ASP)

This technique makes it possible to have a hidden/protected data folder (can be outside the site root) which can only be accessed from the web through the download script.

The script is secured against "parent path" attacks, in that the file name input is not passed on to the function responsible for reading the files. The input is instead matched against the available files in the download folder, and if there is a match, a download is initiated without using any of the input data.

Use the querystring parameter "filename" to request a file.

<%
' Note: Large file downloads will use a lot of memory on the server
' side. A download session will use an amount of memory equal to
' four times the file size of the downloaded file while the download
' is initializing, but it will drop to twice the file size while the
' file is being downloaded.

Option Explicit
Response.Buffer = True

Dim strDLFile
Dim strDLFolder
strDLFile = Left(Request.QueryString("filename"), 75)
strDLFolder = "D:\Sites\protected_download_folder"
'strDLFolder = Server.MapPath("protected_download_folder")
'Use an absolute path or a relative path mapped with Server.MapPath()
'Note: The download folder should never be user input, only the file name.

Call DownloadHandler(strDLFolder, strDLFile)

Sub DownloadHandler(strFolder, strFileName)
  Dim objFso
  Dim objFolder
  Dim objFile
  Dim blnFileOK
  blnFileOK = False
  Set objFso = CreateObject("Scripting.FileSystemObject")
  If AccessAuthorized() = True Then
    If objFso.FolderExists(strFolder) Then
      Set objFolder = objFso.GetFolder(strFolder)
      For Each objFile in objFolder.files
        If objFile.name = strFileName Then
          Call DownloadFile(strFolder & "\" & objFile.name)
          blnFileOK = True
        End If
      Next
      If blnFileOK = False Then
        Response.Status = "404 Not Found"
        Response.Write("The requested file does not exist.")
      End If
    Else
      Response.Status = "404 Not Found"
      Response.Write("Download folder does not exist.")
    End If
  Else
    Response.Status = "403 Forbidden"
    Response.Write("Not authorized.")
  End If
  Set objFso = Nothing
End Sub

Function AccessAuthorized()
  'Put access checks here, for example logged on session state or
  'visitor IPs. Return True to grant access, False to deny.
  AccessAuthorized = True
End Function

Sub DownloadFile(strPathAndFile)
  Dim objFso
  Dim objStream
  Dim strFileName
  If strPathAndFile <> "" Then
    strFileName = Right(strPathAndFile, _
      Len(strPathAndFile) - InStrRev(strPathAndFile, "\"))
    Set objFso = Server.CreateObject("Scripting.FileSystemObject")
    If objFso.FileExists(strPathAndFile) Then
      Response.AddHeader "Content-disposition", "filename=" & strFileName
      Response.ContentType = "application/octet-stream"
      Response.AddHeader "Pragma", "no-cache"
      Response.AddHeader "Expires", "0"
      Set objStream = Server.CreateObject("ADODB.Stream")
      objStream.Type = 1
      objStream.Open
      objStream.LoadFromFile strPathAndFile
      Response.BinaryWrite(objStream.Read())
      objStream.Close
      Set objStream = Nothing
    Else
      Response.Write "The requested file does not exist."
    End If
    Set objFso = Nothing
  End If
End Sub
%>
Tags: asp
Page last updated 2008-06-12 21:43. Some rights reserved (CC by 3.0)