AdmitOne for IIS is an authorization plug in for IIS that is the easiest way to seamlessly authorize access to static content from dynamic ASP pages. With AdmitOne for IIS Webmasters can protect content on their sites using simple but powerful regular expression matching making it just as easy to protect every EXE on a web server as a single directory. AdmitOne also works without the overhead of a binary write from ASP, without password prompts, and without the need for the client to support cookies. AdmitOne for IIS uses unique expiring URL’s that are cryptographically signed with a secret that is shared between AdmitOne and that ASP page called a ticket. The ticket is appended to the URL as a query string giving access to the content for a set period of time. Expiration dates can be short as 1 second to meet almost any security need.
AdmitOne for IIS is the easiest way to secure software, PDF documents, images, HTML pages, and other static content that resides with an ASP application.
CreditsIISRewrite uses Regex++ by Dr John Maddock copyright 1998-2000. Regex++ can be found at http://www.boost.org and is an excellent regular expression library. We thank Dr Maddock for making it available.
Shareware Version LimitationsThe shareware version of the library has all the functionality of the full version but will stop protecting content after 200 requests. Protection is enabled again after the web server is restarted.
System RequirementsIISRewrite is compatible with Microsoft’s ISAPI specification and has been tested on Windows NT 4 running IIS v4 and Windows 2000 running IIS v5.
Installing AdmitOne for IIS will restrict the maximum length of a URL to 4096 bytes. URLs longer than 4096 characters are usually only seen when a text form uses a GET instead of a normal POST operation. Most websites don’t have URLs that exceed this limit because it is beyond the length that many browsers support but AdmitOne for IIS will forbid requests longer than this.
To download a free trial of the software, visit: http://www.qwerksoft.com/products/AdmitOne/download.asp
AdmitOne for IIS is distributed as a zip file. Unpacking the zip file creates an AdmitOne directory containing documentation, a sample configuration file (AdmitOneIIS.ini), the ASP include file (AdmitOne.asp), a test html file (protected.gif), a test ASP page (authorize.asp), and the AdmitOne for IIS DLL (AdmitOneEval.dll).
Installing the program files is simply a matter of making sure that the AdmitOne DLL and its configuration file are in the same directory. We currently use the c:\AdmitOne directory but almost any directory will do. It is highly recommend that the program files NOT be installed in the web server’s home directory for security reasons. The AdmitOne.asp file needs to be copied into web server’s home directory or where ever Include files are normally kept.
The configuration file by default is configured to protect the file named protected.gif that was included in the download. If you want to run the tests copy the gif file named protected.gif into the web server’s home directory along with the ASP files authorize.asp and AdmitOne.asp.
To load AdmitOne into IIS follow these steps:
· Open up Internet Services Manager
· Expand Internet Information Services by double-clicking
· Expand the server name by clicking on the + symbol to the right of the name
· Right click on the name of the website that will be using AdmitOne
· Click properties
· Select the ISAPI Filter tab
· Click Add
· In the Filter Name box enter AdmitOne
· Click browse and select the AdmitOneEval.dll from the installation directory
· Click OK
· Click OK again.
· Restart the web server.
Open up a browser and connect to the website and request /authorize.asp. The authorize.asp page will display 3 links. The first links is an unprotected link directly to /protected.gif that should be denied when clicked. The second link is a ticketed URL that should expire 15 minutes after the page is loaded. Clicking on the second link should display the /protected.gif image. The third link is a ticketed URL that expired 15 minutes ago. Clicking on that URL should be denied. If these test fails check the ISAPI Filter tab to see if the AdmitOne loaded correctly. For issues related to your test configuration, tech support can be contacted at support@qwerksoft.com or through our website at www.qwerksoft.com.
AdmitOne for IIS can protect multiple websites on the same machine. If ALL websites on the machines can share the same configuration file and protection simply install AdmitOne for IIS at the machine level on the web server. If each web site needs its own configuration file each website needs its own copy of the configuration file and DLL in separate directories.
AdmitOne for IIS uses a text based configuration file that can be edited with Notepad or any other text editor. Changes in the configuration file will not take effect until right clicking on the machine in the Internet Services Manager and selecting “Restart IIS”.
Each line of the configuration file contains a configuration directive followed by one or more arguments separated by white space. Arguments that contain spaces should be included in quotation ‘ ” ‘ marks. Lines that begin with hash characters ‘#’ are considered comments and are ignored. A simple configuration file that consists of three configuration directives might look like this:
#My Configuration File
AdmitOneEngine On
AdmitOneSecret myname mysecret
AdmitOneProtect ^/protected/.*
This configuration file consists of a single comment and two configuration directives. The AdmitOneEngine directive turns on AdmitOne protection (required but not interesting). The AdmitOneSecret directive contains the secret “mysecret” that AdmitOne and the ASP page that authorizes the request will share. There can be more than one AdmitOneSecret directive so each secret is given a name to tell them apart. The name of this secret is “myname” and is visible in the ticketed URL’s.
An AdmitOneProtect directive determines what content is protected using a regular expression. The regular expression “^/protected/.*” matches the /protected/ directory in the web servers home directory. Regular expressions are explained more latter but for now it is enough to know that ‘^’ means “starts with” and ‘.*’ means “match anything ”.
AdmitOne for IIS can protect multiple websites on the same machine. If ALL websites on the machines can share the same configuration file and protection simply install AdmitOne for IIS at the machine level on the web server. If each web site needs its own configuration file each website needs its own copy of the configuration file and DLL in separate directories.
Once a URL is protected with the AdmitOneProtect directive a ticket is needed in order to allow access to the content. Tickets are created using the AdmitOneCreateTicket function included in AdmitOne.asp. A simple ASP page that creates a ticketed URL and redirects the request to the URL might look like this:
<!--#include file="AdmitOne.asp"-->
<%
Response. Expires = 0
URL = "http://127.0.0.1/protected.gif"
Expires = DateAdd("h",2,Now)
SecretName = “myname”
Secret = “mysecret”
User = "John Doe"
TicketedURL = AdmitOneCreateTicket (URL, Expires, SecretName, Secret, User)
Response.Redirect(TicketedURL)
%>
The AdmitOneCreateTicket function is contained in the file AdmitOne.asp. In order to get access to that function we need to include it in our ASP page with an include directive. A Response.Expires is included so that browsers or proxy servers don’t cache pages that contain expired tickets.
The AdmitOneCreate Ticket function takes four arguments (URL, Expires, SecretName, Secret, User). The first argument is the URL of the protected file that will be appended with a ticketed and returned to the user. The AdmitOneCreateTicket function can be passed fully qualified or absolute URLs but currently doesn’t handle relative URLs (../../protected.gif).
The second argument is the expiration date of the ticket and in this case is created using the DateAdd function for 2 hours from now. Any valid VBScript date can be used.
The third and fourth arguments are the secretname and secret that should match one of the AdmitOneSecret directives in the configuration file (they are case sensitive!). The secretname is included in the ticket and should be something that can be made public. The secret name should be just that – secret! It should be random and long and above all it should NOT be based on a word in a dictionary.
The last argument can be used to include a user identifier in the URL that is tamper proof. This can be a used when looking at log files to see what users accessed what files or to pass user identifiers between ASP pages on different sites. If the user identifier isn’t needed put “” in the field.
Syntax: AdmitOneEngine on|off
The AdmitOneEngine directive enables or disables processing by
AdmitOne for IIS. When set to off the ISAPI filter passes through all
requests.
This directive can be used to disable AdmitOne for IIS without
uninstalling the filter.
Example:
AdmitOneEngine on
Syntax: AdmitOneLog filename
The AdmitOneLog directive sets the name of the file to which the server
logs any actions it performs. If the name does not begin with a drive letter
then it is assumed to be relative to the Windows NT system32 directory.
The directive should occur only once per configuration file. Commenting
out the AdmitOneLog directive or setting AdmitOneLogLevel to 0 will
disable logging.
Example:
AdmitOneLog “C:\Winnt\system32\logs\rewrite.log”
Syntax: RewriteLogLevel 0-9
The AdmitOneLogLevel directive sets the verbosity level of the
AdmitOne log file. The default level 0 means no logging, while 9 or
more means that practically all actions are logged. To disable the logging
of rewriting actions simply set Level to 0.
Example:
AdmitOneLogLevel 9
Syntax AdmitOneSecret SecretName Secret
The AdmitOneSecret directive provides the shared secret between the
AdmitOneCreateTicket function and AdmitOne for IIS that is used to
authorize a ticket. The AdmitOneSecret directive can be included
multiple times in a single configuration file. The secretname is used to
match a ticket to the correct secret when authorizing the request and
should be unique. Both the secret name and secret are case sensitive.
Multiple AdmitOneSecret directives can be used to change a secret
without breaking existing tickets or giving third parties their own ability to
access your protected content.
Syntax AdmitOneProtect RegularExpression
The AdmitOneProtect directive(s) determines which content on the
website is protected with AdmitOne for IIS. Requested URL’s that match
the regular expression that have a valid ticket are passed to IIS for
processing. URL’s that do not have a valid ticket denied.
It is important to remember that a regular expression should match static
content even if a query string is added to the URL. Otherwise the
protection on an asset ‘/myfile.exe’ could be bypassed simply by
requesting ‘/myfile.exe?bypass’. In most cases simply adding a ‘.*’ to the
end of the regular expression will solve this problem. It is a good
practice to always check to make sure that a AdmitOneProtect
directive cannot be bypassed by adding a query string to the URL.
Example:
Protect the /secure/ directory:
AdmitOneProtect ^/secure/.*
Protect any EXE file on the website
AdmitOneProtect .*\.exe.*
Protect all the directories that are named secure:
AdmitOneProtect .*/secure/.*
Protect all the EXE files in secure directories
AdmitOneProtect .*/secure/.*\.exe.*
Syntax AdmitOneForbiddenURL URL
When a request for a protected URL is presented without a valid ticket
the AdmitOne for IIS will redirect the user to the URL given as an argument
to the AdmitOneForbiddenURL directive. The URL can contain a special
token %URL% that will be expanded to the URL of the requested asset.
The AdmitOneForbiddenURL is optional and if it is not present the
AdmitOne for IIS will simply return a 403 (forbidden) response.
Example:
With this directive:
AdmitOneForbiddenURL http://www.myserver.com/badticket?url=%URL%
If a request were made with an invalid ticket and the requested URL were:
/protected/my assets/test.exe?id=7
The redirect would be:
http://www.myserver.com/badticket?url=%2Fprotected%2Fmy%20assets%2Ftest%2Eexe%3Fid%3D7
AdmitOneExpiredURL
Syntax AdmitOneExpiredURL URL
The AdmitOneExpiredURL operates in the exact same manner as the
AdmitOneForbiddenURL except it is used when the ticket
is valid but the expiration date has passed.
Regular Expressions
There have been many books and papers written about regular expressions and it is impossible to give more than a cursory overview of the syntax. Regular expressions are formulas to match a string with a pattern. A regular expression is made up of normal text and metacharacters, which have special meaning. The table below lists the metacharacters and their meanings.
| Metacharacter | Description |
|---|---|
| Match any single character. The regular expression m.re would match more or mare but not moore. | |
| Matches the end of a line. The regular expression great$ would match “This is great” but not “This is the greatest.” | |
| Matches the beginning of a line. The regular expression ^IIS would match “IIS 21 days” but not “Mastering IIS”. The regular expression ^$ is used to match a null value. | |
| Matches zero or more occurrences of the preceding character. The regular expression a*b would match “ab” “aab” or “b”. The regular expression .* is commonly used as wildcard and will match any number of characters. | |
| This character is used to “turn off” the special meaning of other metacharacters. To have the ‘.’ character mean period and not “any character” precede it with a back slash as in the regular expression index\.html. Forgetting to escape the ‘.’ character is a common mistake. | |
| Match any one of the characters in brackets. The regular expression ^[bcf]at would match bat, cat, or fat but not mat. | |
| Match against a range of characters in the brackets. The regular expression ^[A-Z0-9] would match any alphanumeric character. | |
| Match anything but the characters in the brackets. The regular expression [^0-9A] would match any character except numbers and the letter ‘a.’ | |
| Match either text. For example (dog|cat) would match the string “she has a dog” or “she has a cat” but not “she has a bird.” | |
| Match one or more occurrences of the preceding character. The regular expression a+b would match “ab” or “aaaab” but not “b” | |
| Match zero or one occurrences of the preceding character. The expression a?b would match “ab” or “b” but not “aab” | |
| Treat the characters as a group. When used in a RewriteRule it saves the group in a temporary holding area that can be referenced as $N where N=1-9. |
For an in depth look at regular expressions O’Reilly’s Mastering Regular Expressions (ISBN 1-56592-257-3) is highly recommended.
Many sites specialize in the sale of digital goods such as software, movies, images, PDF documents, and other static items. Many webmasters resorted to wrapping static content in an ASP page and doing a binary write of the content after authorization. Unfortunately this approach has high overhead and breaks 206 (partial content) responses from the web server causing problems with PDF documents and download managers. With AdmitOne for IIS it is easy to grant access to content after the sale with a minimum of overhead and problems.
Some sites don’t sell access to digital content but use that content to attract visitors to their websites. Nothing can be more frustrating than creating great, high demand content but having all the revenue drained away by third party sites that bypass the revenue generating entry pages of a site. With AdmitOne for IIS it is easy to force third party sites to link to entry pages instead deep linking the content.
The shareware industry uses a “try before you buy” model as a way to drive sales. For shareware authors deep linking to content is generates revenue instead of draining revenue. Unfortunately a few crack and warez sites generate downloads which increase costs but don’t increase sales. With AdmitOne for IIS it is easy to create a VBScript script that blocks requests from undesirable sites and then authorizes visitors from other sites to download content.
Sale of Digital Content usually requires after the sale support operations. Customers may need to download content after a hard drive crash, or access to updates and patches. Creating a unique username and password-protected area for each request is time consuming and requires constant maintenance to remove content after a given date. Many support operations simply shortcut the process and share a username and password that is rarely changed. With AdmitOne for IIS it is easy to create a “after the sale” repository that requires little maintainece.