You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1997/11/14 10:50:28 UTC
Re: general/1402: Relative Symlinks are handled improperly
On 14 Nov 1997 stig@hackvan.com wrote:
> Dean Gaudet wrote:
> >
> > An idea just occured to me: a really cheap way to protect a root
> > filesystem from being served is to check st_dev in the stat structure and
> > only allow serving from particular devices. Hmmm.
>
> Bing! A fine idea! Great. Excellent. This would help a great deal!
Try this module. I'm running it now ... it will take a few tweaks to get
it to work with 1.2 though. Probably just change the logging call and
delete a few structure elements from the module structure.
Dean
/*
* mod_allowdev: prohibit files from being served unless they're
* on a listed device.
*
* Author: Dean Gaudet <dg...@arctic.org>
*/
/*
* Usage: Go down there and hard code the list of devices from
* which you allow content to be served. Stick an appropriate
* "AddModule modules/extra/mod_allowdev.o" directive at the
* very bottom of your src/Configuration file, rebuild.
*/
/* TODO: Add a config directive "AllowDev" which takes a
* filename, stats the file to find out what device it is on.
* Fail gracefully, if the file doesn't exist, it's fine to
* continue, you're not going to allow files to be served which
* wouldn't otherwise be serveable.
*
* TODO: Device numbers should be easy to hash.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
/* don't ask why we run this in header_parse phase ... well ok,
* go ahead, ask. It's because there's no other way to protect
* against the Satisfy directive.
*/
static int check_device(request_rec *r)
{
if (r->finfo.st_mode == 0) {
return DECLINED;
}
switch (r->finfo.st_dev) {
/* hard code the list of acceptable devices here */
case 0x0303:
case 0x1602:
return DECLINED;
}
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
"mod_allowdev: request to %s is on device 0x%x, forbidden",
r->uri, r->finfo.st_dev);
return HTTP_FORBIDDEN;
}
module MODULE_VAR_EXPORT allowdev_module =
{
STANDARD_MODULE_STUFF,
NULL, /* initializer */
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
NULL,
NULL, /* handlers */
NULL, /* filename translation */
NULL, /* check_user_id */
NULL, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
NULL, /* fixups */
NULL, /* logger */
check_device, /* header parser */
NULL, /* child_init */
NULL, /* child_exit */
NULL /* post read-request */
};
#if 0
/* If you don't know how to figure out the device number, just compile
* this program, and run it with a list of files, one per device
* you're interested in. It'll stat them and tell you their device
* numbers.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
void main(int argc, char **argv)
{
struct stat buf;
while (++argv, --argc) {
if (stat (argv[0], &buf) == -1) {
fprintf(stderr, "stat(%s) error: %s\n", argv[0], strerror(errno));
continue;
}
printf("0x%x\t%s\n", buf.st_dev, argv[0]);
}
exit(0);
}
#endif
Re: general/1402: Relative Symlinks are handled improperly
Posted by Dean Gaudet <dg...@arctic.org>.
On Fri, 14 Nov 1997, Dean Gaudet wrote:
> On 14 Nov 1997 stig@hackvan.com wrote:
>
> > Dean Gaudet wrote:
> > >
> > > An idea just occured to me: a really cheap way to protect a root
> > > filesystem from being served is to check st_dev in the stat structure and
> > > only allow serving from particular devices. Hmmm.
> >
> > Bing! A fine idea! Great. Excellent. This would help a great deal!
>
> Try this module. I'm running it now ... it will take a few tweaks to get
> it to work with 1.2 though. Probably just change the logging call and
> delete a few structure elements from the module structure.
Ack, here's v0.02. header_parse is the wrong phase to use, because it's
not run by subrequests. So for example:
% ln -s /etc/passwd pwhack
% echo '<!--#include file="pwhack"-->' >pw.shtml
would be able to include /etc/passwd.
This is fixed by using the fixup phase instead.
Dean
/*
* mod_allowdev: prohibit files from being served unless they're
* on a listed device. v0.02.
*
* Author: Dean Gaudet <dg...@arctic.org>
*/
/*
* Usage: Go down there and hard code the list of devices from
* which you allow content to be served. Stick an appropriate
* "AddModule modules/extra/mod_allowdev.o" directive at the
* very bottom of your src/Configuration file, rebuild.
*/
/* TODO: Add a config directive "AllowDev" which takes a
* filename, stats the file to find out what device it is on.
* Fail gracefully, if the file doesn't exist, it's fine to
* continue, you're not going to allow files to be served which
* wouldn't otherwise be serveable.
*
* TODO: Device numbers should be easy to hash.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
/* This runs as a fixup because we don't want it to be affected
* by any "Satisfy" directive. It must always be satisfied.
* fixups happen to also be run for all requests and subrequests.
*/
static int check_device(request_rec *r)
{
if (r->finfo.st_mode == 0) {
return DECLINED;
}
switch (r->finfo.st_dev) {
/* Hard code the list of acceptable devices here, don't worry
* about the "DECLINED" that's just the way of saying "this
* module doesn't have any reason to stop this request".
*/
case 0x0303:
case 0x1602:
return DECLINED;
}
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
"mod_allowdev: request to %s is on device 0x%x, forbidden",
r->uri, r->finfo.st_dev);
return HTTP_FORBIDDEN;
}
module MODULE_VAR_EXPORT allowdev_module =
{
STANDARD_MODULE_STUFF,
NULL, /* initializer */
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
NULL,
NULL, /* handlers */
NULL, /* filename translation */
NULL, /* check_user_id */
NULL, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
check_device, /* fixups */
NULL, /* logger */
NULL, /* header parser */
NULL, /* child_init */
NULL, /* child_exit */
NULL /* post read-request */
};
#if 0
/* If you don't know how to figure out the device number, just compile
* this program, and run it with a list of files, one per device
* you're interested in. It'll stat them and tell you their device
* numbers.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
void main(int argc, char **argv)
{
struct stat buf;
while (++argv, --argc) {
if (stat (argv[0], &buf) == -1) {
fprintf(stderr, "stat(%s) error: %s\n", argv[0], strerror(errno));
continue;
}
printf("0x%x\t%s\n", buf.st_dev, argv[0]);
}
exit(0);
}
#endif