First, it is important to understand possible threats to the integrity of a system running the WN server. There are two types of threat which this document addresses separately: (1) external, from a client or purported client on a remote host, and (2) local, from a user with an account on the server host.
After reading this section you may wish to look at the section on file ownership and permissions.
The basic philosophy of WN security is that by default no client requests are granted. Permission to serve a document must be explicitly granted by the maintainer. The WN server keeps a small data base in each directory of its data hierarchy which contains information about files to be served from that directory. In particular no document can be served unless explicit permission to serve it is given in such a data base.
[For more information on these data base files the Overview Chapter is a good place to start. These files are very easy to create and maintain; see the chapter on creating a data hierarchy.]
Despite this strong security foundation several additional steps are prudent. The most important is that the maintainer must assure that no untrusted person has write access to any part of the WN hierarchy. For example an "incoming" anonymous ftp directory should never be part of a WN hierarchy (better yet don't have one at all), because an attacker might be able to put a data base there granting illicit access to some documents on the server system for which the user id running the server has read permission. There are several defenses against such a "counterfeit" data base and we discuss them next.
The -t and -T options. These options allow you to specify a trusted owner or group owner (not both) for index.cache files. To do this use the "-t uid#" or "-T gid#" option to wn or swn. When invoked with only the -t argument (or the -T argument) wn or swn will not serve a document unless the index.cache file listing it has the prescribed owner or gid. This uid# or gid# should be that of the maintainer not the user id under which wn or swn runs. Indeed, for security reasons if the server has been started as root and changed to another uid it will refuse to use an index.cache file whose owner is the uid under which it is running. If on your server all index.cache files are created by a single user or a single group I strongly recommend using the -t or -T option.
This added security is weakened somewhat if you use the -u option which allows index.cache files owned by untrusted users, but only permits them to grant access to files owned by the same user as the index.cache file. This option might be appropriate if you permit users to have their own homepage on your server. It would allow users to serve documents which they own but no others. If both the -u and the -t argument are used the -u takes effect except the trusted user specified with the -t option is exempt from its restrictions.
When the server is run it must assume the permissions of some user on the host. Which user is determined when you run the "configure" perl script or by defining USER_ID in config.h. It is important this USER_ID have as few permissions as possible. On many systems there is a user called "nobody" with minimal permissions. The numeric user_id of "nobody" is a good choice and is the default choice of the WN configure script. Of course the server must have read permission on all the files served but it should not have write permission for any directory or file other than its log files. If the syslog option for logging is enabled there is not even any need for write permission on a log file. A good practice is to have all the files in your hierarchy which you intend to serve be owned by the maintainer or their creator. They should be world readable (assuming they are for general consumption) but with restricted write permission. The files in your hierarchy should not be owned by the user id under which WN will run.
WN does not by default use the chroot system call to further restrict the files which the server can access. Doing so would enhance security at the expense of extra work for the maintainer. The effect of this is to prevent the server from even internally accessing any file which is not in your data directory. If you are especially concerned about security you may wish to run one of the public domain TCP wrappers in conjunction with WN which will allow you to use the chroot system call. This can simultaneously enhance security for other TCP services like anonymous ftp.
However, there are many needs which can only be met by scripts. The greatest danger in their use is that even though the script is under the control of the maintainer, the arguments passed to it can be set by a potential attacker. WN supports the CGI or "Common Gateway Interface" protocol (see the chapter on CGI in this guide) for executing scripts. Under this protocol there are three ways by which arguments are passed to scripts. The first of these is used when processing HTML forms which use the GET method. Under this method all arguments are put in environment variables and the script must extract them from the environment. Moreover, they have been placed in a URL encoded format by the browser and must be decoded by the script. Thus if the request is of type GET, the arguments are examined to see if they contain an '='. If they do, it is assumed that this is a CGI form response (something like name=John&toppings=pepperoni). In this case the script is executed with no arguments and the argument string is placed in an environment variable where the script can read it. This is fairly safe from the server point of view but the script writer must exercise great care.
The second method is for HTML forms using the POST method. In this case everything posted by the client (in URL-encoded form) must be sent to the standard input of the CGI script. Thus if the request is of type POST, information is read from the client and put in a temporary file on disk. Then the script is executed with no arguments and its standard input comes from this file. Security is the responsibility of the script writer. It is not so dangerous to have arguments come from standard input but the script writer must still exercise care.
Finally if the GET request has arguments but no '=' it is assumed to be an ISINDEX type request and the script should be executed with the given arguments. While the CGI specification does not permit the altering of arguments, it does say that if the arguments pose any security problems it is permissible to put the string in an environment variable and execute the script with no arguments, just as in the CGI forms case described above. WN takes a very strict view on this subject and considers any characters other than space and alphanumeric characters as a security problem. Accordingly, if it finds any other character in an argument it will put all arguments in the appropriate environmental variable and run the script with no command line arguments.
Again let me say the script writer must exercise great care. I can't emphasize this too strongly. When you run a CGI script the server almost completely absolves itself of security responsibility and dumps that responsibility on the script writer. Most authors of freely distributed CGI scripts are not fully cognizant of potential security holes they may open up. Running insecure scripts created locally or obtained from Usenet postings is almost certainly the single greatest risk to a WN server site. To find out more about writing secure CGI scripts I strongly recommend that you read the relevant sections of Lincoln Stein's WWW Security FAQ and the CGI security page maintained by Paul Phillips.
If it is possible make sure that no untrusted user has write access to any part of your WN hierarchy. As mentioned above an attacker with write access to your hierarchy can create an index.cache file which will give access to anything on your server which is readable by the user id under which WN runs. Even worse, she can create a shell script and a index.cache file permitting it to be executed, so it can be executed with all the permissions of that user id. A good rule of thumb is:
Always assume that everyone with write access to any part of your data hierarchy has all the permissions of the userid under which your server runs!This should not be true if you are using some of the command line options described above, but it is good practice to behave as if it were true.
Sometimes it is not possible or desirable to deny write access to your WN hierarchy. For example, you may need to allow all users to have a homepage in their home directory or in some other designated place. There are two important things to do in this case.
The first of these is run the server with the -u option. This has the effect of requiring that every file served (including wrappers and includes) have the same owner as the index.cache file which grants it permission to be served. This means that untrusted users can only serve files which they own. This will prevent a user from serving /etc/passwd, but will not prevent him from making his own copy of /etc/passwd and serving that. If the -t or -T option is also used then index.cache files owned by the trusted user or trusted group are exempt from this requirement and they may grant permission to serve any file the server can read. For security reasons the server will refuse to use an index.cache file which is a symbolic link to another file.
The -e or -E command line options mentioned above are also a good idea in this case, to prevent any execution of scripts or at least restrict their execution to trusted index.cache files.
You should note that when run in its default configuration there is no way to use password authentication to prevent users on your system, who can create index.cache files, from gaining access to files you are serving. They can simply make a symbolic link in their part of the hierarchy to the file you want to restrict and a index.cache file permitting it to be served. Since the server has access to the restricted file it will serve it if it is listed in a index.cache file. This simple threat can be avoided by using the -u option described above, but the number of potential threats is quite large. For example, if the -e or -E option is not used a hostile user could write a CGI script which reads the sensitive files and mails them to himself. In general I would strongly advise against trying to have sensitive documents (protected by password or .access files) and potentially hostile users on the same server. I would also strongly advise against allowing potentially hostile CGI scripts, executed includes or external modules. They can be disallowed through the use of the -E or -e command line options. If they are not disallowed a CGI script can alter or destroy log files. A hostile authorization module could collect user passwords.
The -u and -E options greatly enhance security, but it is important to keep the following principle in mind. You should assume that any permissions you grant to the userid under which WN runs are also granted to every user who can create an index.cache file in your data hierarchy.
The other method of limiting access is by password with the HTTP 1.0 Basic Authentication Scheme. This is about as secure as using passwords with ftp to protect information. This scheme is flawed in that it involves the transmission of essentially unencoded passwords over the network. It is relatively easy for unscrupulous people to obtain "sniffer" software which allows eavesdropping on all local network traffic. This means, in particular, that it is possible to intercept passwords of other users.
For security reasons when you use authwn or any Authorization-Module you are required to use either the -t or -T option or the -a or -A option when the server is run and to have the index.cache file in the protected directory owned by the trusted user or group. This is to guard against counterfeit authentication modules.
This particular problem is remedied by the "Digest" authentication scheme. Digest authentication is supported experimentally by WN, but has the rather severe drawback that no publicly available clients currently support it. It is experimental, because I have no client to test it and hence it has barely been tested. I believe it will be a standard part of HTTP 1.1 and at that time will significantly improve security of password protected directories.
The Authorization-Realm directive, used whenenver an authentication module is used, is to notify the client that for any document on this server with the same realm as this one, the same password / username combination will be valid, so the client need not ask the user for a username and password, but can reuse the one supplied for the first document with this realm. For security reasons you should always put your host and domain name in the realm. This may at least discourage attempts at other sites to forge your realm in order to collect user passwords. Your users should also be warned never to enter their password if the realm displayed when they are prompted for a password contains a different hostname than the one in the URL they are trying to access.
Both Basic authentication and access control by IP address become much more vulnerable if the potential attack comes from users who can create index.cache files for another part of your server's data hierarchy. I would recommend against trying to use either to protect information from users with home pages on your server.
If no potentially hostile users can create servable documents on your system the mechanisms described above provide protection adequate for many purposes. If I were an information provider selling access to a collection of information on my server, I would be comfortable using the numeric IP address to limit access to my paying customers. On the other hand I would not want any of these mechanisms used to protect my bank records.
With these options no CGI programs or filters or script output includes are permitted. Also the POST method is not accepted (an error is returned for a POST request). Furthermore only index.cache files owned by the user specified in the -t option are used. The server should be run as "nobody" (the default) and the numeric user id specified with -t should be the maintainer's
This is configuration is obtained by running with the -E option. and the -u option. The -E option is similar to the -e option except that index.cache files owned by a trusted user id or trusted group id (set with the -t or -T option) are exempt from the restrictions. The -u option requires that in order to be served a file must be owned by the owner of the index.cache file which lists it. Trusted users as specified with -t or -T are exempt from this restriction also.
Probably the most controversial security "feature" of WN is that it greatly restricts the set of characters which can be used in file or path names. Dangerous characters are not disallowed -- instead only characters presumed safe are allowed. The currently allowed characters are alphanumeric characters and '_', '-', '.', '+','/', and '%'. The same restrictions are applied to the PATHINFO part of URL's for CGI scripts. This sometimes has caused problems with CGI scripts that like to include unusual characters in file names or PATHINFO. Also the server will attempt to resolve all "../" references while staying in the server data hierarchy. If these references would result in a request for a document outside the server data hierarchy the request is treated like a request containing illegal path characters. In particular with "verbose logging" turned on, a message like "SECURITY Found bad character (%X hex) in path" is logged.
To defend against a "denial of service" attack the server will refuse a POST request with post data in excess of 1 megabyte. This does not defend against multiple requests with large POST data. The maximum allowed size of POST data can be altered by changing the value of "MAX_POST" in the file wn/wn.c.