First published: 4th April 1997
Publishing Pages with PUT
One of the most common questions we get asked is
whether Apache supports web publishing with the PUT method.
Netscape Navigator Gold, AOLPress and Amaya all support this
method of publishing pages. Technically the answer is yes,
Apache supports that method. However it does not come with any
scripts or programs which actually implement the publishing
behaviour. This article explains what the PUT method is, how it
can be used in Apache, and what is required to support
publishing with it. It also gives a basic script to handle
publishing, and explains why this script should be used very
carefully to prevent security problems.
First published in Apache Week issue 59 (4th
April 1997).
How Apache Supports GET, POST and PUT
When a browser requests a normal page from a server, it uses
the "GET" method. This is the standard way to get back
information from a server. The information itself may come
from a static page, a CGI program, a server-side include page
or any other source handled by the server. By definition it
is safe for a browser to obtain a page by GET as many times
as it likes - it will never cause any permanent action on the
server (such as entering a product order).
To perform a permanent action on the server, the "POST"
method is used. This method must be handled by a program or
script, and the browser should not re-request a POST page
without getting the user to confirm it. This POST method is
used when a script or program requires a lot of form data
input or when the request makes the server perform a real
action such as entering an order.
The "PUT" method is similar to the POST method in that it can
cause information to be updated on the server. The difference
is that the POST method is normally handed a script which is
explicitly named by the resource (that is, something that
already exists), while a PUT request could be directed at a
resource which does not (yet) exist. Another difference is
that the POST method can be used in response to a form, while
the PUT method can only contain a single data item. The
PUT method is suited for publishing pages.
There is some confusion about whether Apache supports the PUT
method. In fact, Apache handles PUT exactly like it handles
the POST method. That is, it supports it, but in order for it
to do anything useful you need to supply a suitable CGI
program. This is on contrast to the GET method, which Apache
supports internally by sending back files or SSI documents.
Using the PUT Method
If you have a script which is capable of handling PUT
requests, you can easily configure Apache to support that
script. This is done with the Script directive.
This specifies a script (i.e. a CGI program) to be run
whenever a PUT request is received. For example, if you put
your CGI program which handles PUT requests into
/cgi-bin/put, you would add this like
Script PUT /cgi-bin/put
into your srm.conf or access.conf (depending on whether you
want your entire contents to handled by this script, or just
a specific subdirectory). Note that you also need to make
sure that this script is executable, by either placing it in
a ScriptAlias directory, or giving it a suitable
extension and turning on CGI execution for that extension.
The CGI script has to be able to accept a page sent it, and
look and the request URL to decide where to place the file.
If it is successful it should return a status of 201 or 204
if everything went ok.
The basic operation of a PUT script should be:
-
Check that request comes from the PUT method
-
Get the file to update or create from PATH_TRANSLATED
-
Read the data (read CONTENT_LENGTH bytes from standard
input)
-
Write the data to the file
-
Return a 201 or 204 status.
A simplistic script to implement PUT handling like this
is available in put1.
Among aother limitations, this script does not check to
see if you are attempting to upload a CGI script or if
the destination is a directory. However the main failing
is that it implements no security checks, and if you have
a secure setup it will not even have permission to update
the files.
The Security Isssues
Configuring Apache is the easy part: the hard part is
creating a server environment and script which are
secure. Some of the main security requirements are:
-
Make sure the PUT script can only be run by authorised
users
-
Make sure that the script can update only web content
files
-
Make sure the authorised users can only update their
pages, not other people's pages on the same server
The first issue can be addressed by making sure that the
script is protected by username and password
authentication.
The second issue is more complex. To be able to update
the files on your server the script must have enough
permission to write or create the content files. This in
itself is a security risk, since it means if a bug or
security hole is found in any of your other CGI programs
anyone on the Internet could potentially change any of
your files. On most servers the httpd process runs a some
relatively unprivileged user, such as "nobody". This user
should not own or have write access to any of the files
on the server. So the first problem with generating a
secure PUT script is determining how the script can get
permissions to update files owned by a different user.
One way of doing this, new in Apache 1.2 betas, is to use
the "suEXEC" code. This allows a script to be run as a
different user. This comes with Apache but is not
installed by default, because of the security risks it
can create if used inappropriately. You need to install
it, and arrange it so that the PUT script is executed as
the user that owns your web files. In this case, it would
be sensible to ensure that this user does not have write
access to any other parts of the file system, such as
your Apache configuration files or .htaccess files.
The final security issue applies if you have multiple
content providers (such as different customers) where you
cannot trust them not to try to update each other's
pages. There are several ways to add fix this:
-
If the customers are in different virtual hosts, use
the suEXEC mechanism to give each customer a different
Unix username and execute the script as that user.
-
Use a different PUT script for each customer, with
individual access authentication for each user, and
hard-code the paths that they are allowed to update
into the script.
-
Add lots of careful checks into the PUT script to
ensure that each REMOTE_USER can only update pages in
their area
Using PUT Publishing
Netscape Navigator Gold, AOLPress and Amaya can publish
pages with the PUT method. Assuming you have a PUT script
which provides a level of security you are happy with,
this section explains how to use these programs to
publish pages. Other Web publishing program should be
similar.
To publish pages, you need to configure your server as
given above. This section shows how to do this in more
detail with better user security. First, decide which
areas of your document tree you want to allow people to
publish to. For this example, we will assume people can
publish to any page on the server. You need to add a
Script PUT directive into the
<Directory> section for the directory
where you want to enable PUT uploading, and put the PUT
script into a user-authenticated directory. For example
<Directory /usr/local/etc/httpd/htdocs>
Script PUT /cgi-bin-putusers/put.cgi
</Directory>
<Directory /usr/local/etc/httpd/cgi-bin-putusers>
AuthType Basic
AuthName "Authorised PUT Publishers"
AuthUserFile /usr/local/etc/httpd/htpasswd-putusers
Require valid-user
</Directory>
ScriptAlias /cgi-bin-putusers /usr/local/etc/httpd/cgi-bin-putusers
You will have to modify this for your setup. You also
need to enter a username and password into the
htpasswd-putusers file using htpasswd. Note
that there are many other ways to configure user
authentication for a PUT script, including using a
<Files> to apply a restriction to just
the PUT script, or using <LIMIT PUT>
to limit just the PUT method scripts within your existing
cgi-bin directory.
With this configuration, all PUT requests will be handled
by the named script
(/usr/local/etc/httpd/cgi-bin-putusers/put.cgi).
Now all you need to do is author a page then select the
publish function. In AOLPress and Amaya, you do File,
Save (or File, Save As) and type the full URL of the
location to publish the file to (e.g.
http://www.my_server.com/first.html).
In Navigator Gold, select File, Publish. In the "Upload
Files to this location" box, enter the full URL of the
page to create. For example, if your server is called
www.my_server.com and you want to upload to a file called
"first.html" in the document root, you would enter
http://www.my_server.com/first.html
Also enter the username and password you created in the
htpasswd-putusers file.
With AOLPress, select File|Save As, then type the full
URL of the page to upload into the "Location" box.
Put Scripts
There are few scripts available which implement PUT
handling securely. For this reason the general
recommendation for using publishing functions is to use
FTP rather than HTTP where possible. However if you want
to implement PUT-based publishing, you might like to
start which one of these programs:
The issues raised in the above section on security apply
to these programs as well, so before you use them review
the source code, install them in a user-authenticated
area, and make sure that when run from the httpd server
they only have write permission to the content files you
want to be able to update.
|