To read the article online, visit http://www.4GuysFromRolla.com/webtech/102099-1.shtml

Creating Secure Documents on the Net

By Brian Atkinson


  • This article will build upon Protecting Everything, originally published on 08-11-99.

    Protecting Everything dealt with the scenario of a programmer wanting to make PDF files of invoices available to specific customers via the web, but the programmer also wanted to keep customers from guessing URLs to view content that belongs to other customers. The question was, "How can i make this project viable and secure?"

    The article offers a viable and semi-secure solution, in that ASP and a database are used to provide a security check and then the Software Artisans SA-FileManager V1.1 component was used to distribute the file. It was also stated in the article that:

    "If someone were to guess the full URL of the PDF files, and typed that URL into their browser, they would be able to view the PDF files; it's not a security flaw, just the nature of the web."

    While this statement is true, there is a way to make this process even more secure, and eliminate the guessing process entirely by placing the PDF files in a non-web accessible folder and having an ActiveX DLL distribute the file(s) that theuser has requested and permitted to view.

    Microsoft Knowledge Base Article Q193998 explores the distribution of Binary files from a folder that is not available via the web. This is accomplished by using an ActiveX DLL. What this means is that customers will not be able to guess file locations by tampering with URLs, because the ActiveX DLL will have to provide the customer with only the content that he or she has requested and what he or she is allowed to view. This process can be used to protect and distribute files of any type, but we will follow the lead of the original article and use PDF files.

    To accomplish this process we will need an HTML page, an ASP page and an ActiveX DLL.

    First create a simple DEFAULT.HTM page that contains a form:

    <HTML> <FORM ACTION="process.asp" METHOD="POST"> <TABLE ALIGN="CENTER" BORDER=0> <TR> <TD ALIGN="LEFT">UserName:</TD> <TD><INPUT TYPE=TEXT LENGTH=8 MAXLENGTH=8 NAME="UserName"></TD> </TR> <TR> <TD ALIGN="LEFT">Password:</TD> <TD><INPUT TYPE=TEXT LENGTH=8 MAXLENGTH=8 NAME="Password"></TD> </TR> <TR> <TD ALIGN="LEFT">FileName:</TD> <TD><INPUT TYPE=TEXT LENGTH=20 MAXLENGTH=20 NAME="FileName"></TD> </TR> <TR> <TD COLSPAN=2 ALIGN=RIGHT> <INPUT TYPE="SUBMIT" VALUE=" Submit ">&nbsp; <INPUT TYPE="SUBMIT" VALUE=" Reset "> </TD> </TR> </TABLE> </FORM> </HTML>

    Next create PROCESS.ASP that will process the form and call the DLL:

    <% Option Explicit %>
    <%
    Response.ExpiresAbsolute = Now() - 1 '<<<<<DECLARATION OF ALL VARIABLES>>>>>' Dim sUserName Dim sPassword Dim sFileName Dim oMyObject '<<<<<OBTAIN ALL VARIABLES>>>>>' sUserName = Server.HTMLEncode(Request.Form("UserName")) sPassword = Server.HTMLEncode(Request.Form("Password")) sFileName = Server.HTMLEncode(Request.Form("FileName")) '<<<<<ENSURE VALID DATA FORMATS>>>>>' If Len(sUserName) > 0 AND Len(sPassword) > 0 Then If sFileName <> "" Then Dim vntStream Response.Buffer = TRUE Response.ContentType = "application/pdf" Set oMyObject = Server.CreateObject("MyObject.BinRead") vntStream = oMyObject.readBinFile("c:\webdocs\" & sFileName) Response.Addheader "Content-Disposition", "inline; filename=" & sFileName Response.CacheControl = "public" Response.BinaryWrite(vntStream) Set oMyObject = Nothing Response.End Else '<<<<<REDIRECT BLANK FILE NAMES>>>>>' Response.Redirect ("error_page.asp?01") End If Else '<<<<<REDIRECT BLANK USERNAME AND PASSWORDS>>>>>' Response.Redirect ("error_page.asp?02") End If
    %>

    The example above is rough indeed, but the general idea is there. You would definitely want to include additional error-checking to ensure that the data being passed to the DLL is valid, and redirect mistakes to an appropriate error page. The database verification code found in the original "Protecting Everything" article was omitted in the ASP file above, because it would probably be better suited if it was located inside the ActiveX DLL.

    The final step is to create the ActiveX DLL. The ActiveX DLL code is fairly straightforward, and the code below is adapted directly from Microsoft's Knowledge Base Article Q193998.

      1. Open Visual Basic 5.0 or later and create a new ActiveX DLL
      2. Rename the project MyObject.
      3. Rename the class module BinRead.
      4. Enter this code:

      Function readBinFile(ByVal bfilename As String)
      	Dim fl As Long
      	Dim binbyte() As Byte
      	Dim binfilestr As String
      
      	On Error GoTo errHandler
      
      	Open bfilename For Binary Access Read As #1
      	f1 = FileLen(bfilename)
      	ReDim binbyte(f1)
      
      	Get #1, , binbyte
      
      	Close #1
      
      	readBinFile = binbyte
      	Exit Function
      
      errHandler:
      	Exit Function
      
      End Function
      

      5. Save the project and compile the DLL in the \winnt\system32 folder.
      6. Register the DLL by typing:

      REGSVR32.EXE C:\winnt\system32\MyObject.dll

      at a command prompt.
      7. You may rename the project and class module to whatever you wish, but notice how the DLL is referenced from the ASP Page, and make sure that you are calling it based on the correct name.
      8. After registering the DLL, open the DEFAULT.HTM file

    Without going in too much detail, these three pieces of code will do the trick. The ActiveX DLL code above does not handle errors gracefully, in that the errHandler just stops the execution of the DLL. This will leave end-users with a blank screen. It is definitely a better idea to give users descriptive error messages, but again this is a little beyond the scope of this document. There are many articles available that go in to great detail on how to develop ActiveX DLLs, that one could use to expand on the Visual Basic code provided above. The article Createing a Server Component with Visual Basic is a great starting point.

    Other Notable Points:
    The Software Artisans SA-FileManager V1.1 component documentation recommends against using their component for the distribution of large files, and this same warning should be applied with the ActiveX DLL component above. I have personally used this code to distribute files of up to 50 Mb, but not without a performance penalty.

    Although the folder C:\webdocs is not a web folder, the IUSR account will still need to have the NTFS READ permission to this directory and its contents. The ActiveX DLL is typically run in the context of the IUSR account (unless a login has occurred), and therefore the IUSR account is actually the NT User that is requesting the file from the C:\webdocs folder.

  • By Brian Atkinson


    Attachments:

  • Download the source for DEFAULT.HTM in Text Format
  • Download the source for PROCESS.ASP in Text Format
  • Download the ActiveX DLL code in Text Format

  • Article Information
    Article Title: Creating Secure Documents on the Net
    Article Author: Brian Atkinson
    Published Date: Wednesday, October 20, 1999
    Article URL: http://www.4GuysFromRolla.com/webtech/102099-1.shtml


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers