Skip to content

Commit

Permalink
clean thttpd: remove check_referer feature (which may be cheat easily)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbar committed Mar 5, 2012
1 parent 564e139 commit 8415dea
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 188 deletions.
131 changes: 2 additions & 129 deletions ludd/src/libhttpd.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -167,8 +167,6 @@ static void cgi_child( httpd_conn* hc );
static int cgi( httpd_conn* hc ); static int cgi( httpd_conn* hc );
static int really_start_request( httpd_conn* hc, struct timeval* nowP ); static int really_start_request( httpd_conn* hc, struct timeval* nowP );
static void make_log_entry( httpd_conn* hc, struct timeval* nowP ); static void make_log_entry( httpd_conn* hc, struct timeval* nowP );
static int check_referer( httpd_conn* hc );
static int really_check_referer( httpd_conn* hc );
static int sockaddr_check( httpd_sockaddr* saP ); static int sockaddr_check( httpd_sockaddr* saP );
static size_t sockaddr_len( httpd_sockaddr* saP ); static size_t sockaddr_len( httpd_sockaddr* saP );
static int my_snprintf( char* str, size_t size, const char* format, ... ); static int my_snprintf( char* str, size_t size, const char* format, ... );
Expand Down Expand Up @@ -203,10 +201,6 @@ free_httpd_server( httpd_server* hs )
free( (void*) hs->cwd ); free( (void*) hs->cwd );
if ( hs->cgi_pattern != (char*) 0 ) if ( hs->cgi_pattern != (char*) 0 )
free( (void*) hs->cgi_pattern ); free( (void*) hs->cgi_pattern );
if ( hs->url_pattern != (char*) 0 )
free( (void*) hs->url_pattern );
if ( hs->local_pattern != (char*) 0 )
free( (void*) hs->local_pattern );
free( (void*) hs ); free( (void*) hs );
} }


Expand All @@ -215,9 +209,7 @@ httpd_server*
httpd_initialize( httpd_initialize(
char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P,
unsigned short port, char* cgi_pattern, int cgi_limit, unsigned short port, char* cgi_pattern, int cgi_limit,
char* cwd, int no_log, FILE* logfp, char* cwd, int no_log, FILE* logfp, int no_symlink_check )
int no_symlink_check, char* url_pattern,
char* local_pattern, int no_empty_referers )
{ {
httpd_server* hs; httpd_server* hs;
static char ghnbuf[256]; static char ghnbuf[256];
Expand Down Expand Up @@ -276,33 +268,10 @@ httpd_initialize(
syslog( LOG_CRIT, "out of memory copying cwd" ); syslog( LOG_CRIT, "out of memory copying cwd" );
return (httpd_server*) 0; return (httpd_server*) 0;
} }
if ( url_pattern == (char*) 0 )
hs->url_pattern = (char*) 0;
else
{
hs->url_pattern = strdup( url_pattern );
if ( hs->url_pattern == (char*) 0 )
{
syslog( LOG_CRIT, "out of memory copying url_pattern" );
return (httpd_server*) 0;
}
}
if ( local_pattern == (char*) 0 )
hs->local_pattern = (char*) 0;
else
{
hs->local_pattern = strdup( local_pattern );
if ( hs->local_pattern == (char*) 0 )
{
syslog( LOG_CRIT, "out of memory copying local_pattern" );
return (httpd_server*) 0;
}
}
hs->no_log = no_log; hs->no_log = no_log;
hs->logfp = (FILE*) 0; hs->logfp = (FILE*) 0;
httpd_set_logfp( hs, logfp ); httpd_set_logfp( hs, logfp );
hs->no_symlink_check = no_symlink_check; hs->no_symlink_check = no_symlink_check;
hs->no_empty_referers = no_empty_referers;


/* Initialize listen sockets. Try v6 first because of a Linux peculiarity; /* Initialize listen sockets. Try v6 first because of a Linux peculiarity;
** like some other systems, it has magical v6 sockets that also listen for ** like some other systems, it has magical v6 sockets that also listen for
Expand Down Expand Up @@ -3384,9 +3353,7 @@ really_start_request( httpd_conn* hc, struct timeval* nowP )
if ( auth_check( hc, hc->expnfilename ) == -1 ) if ( auth_check( hc, hc->expnfilename ) == -1 )
return -1; return -1;
#endif /* AUTH_FILE */ #endif /* AUTH_FILE */
/* Referer check. */
if ( ! check_referer( hc ) )
return -1;
/* Ok, generate an index. */ /* Ok, generate an index. */
return ls( hc ); return ls( hc );
#else /* GENERATE_INDEXES */ #else /* GENERATE_INDEXES */
Expand Down Expand Up @@ -3504,10 +3471,6 @@ really_start_request( httpd_conn* hc, struct timeval* nowP )
} }
#endif /* AUTH_FILE */ #endif /* AUTH_FILE */


/* Referer check. */
if ( ! check_referer( hc ) )
return -1;

/* Is it world-executable and in the CGI area? */ /* Is it world-executable and in the CGI area? */
if ( hc->hs->cgi_pattern != (char*) 0 && if ( hc->hs->cgi_pattern != (char*) 0 &&
( hc->sb.st_mode & S_IXOTH ) && ( hc->sb.st_mode & S_IXOTH ) &&
Expand Down Expand Up @@ -3676,96 +3639,6 @@ make_log_entry( httpd_conn* hc, struct timeval* nowP )
hc->status, bytes, hc->referer, hc->useragent ); hc->status, bytes, hc->referer, hc->useragent );
} }



/* Returns 1 if ok to serve the url, 0 if not. */
static int
check_referer( httpd_conn* hc )
{
int r;
char* cp;

/* Are we doing referer checking at all? */
if ( hc->hs->url_pattern == (char*) 0 )
return 1;

r = really_check_referer( hc );

if ( ! r )
{
cp = hc->hs->server_hostname;
if ( cp == (char*) 0 )
cp = "";
syslog(
LOG_INFO, "%.80s non-local referer \"%.80s%.80s\" \"%.80s\"",
httpd_ntoa( &hc->client_addr ), cp, hc->encodedurl, hc->referer );
httpd_send_err(
hc, 403, err403title, "",
ERROR_FORM( err403form, "You must supply a local referer to get URL '%.80s' from this server.\n" ),
hc->encodedurl );
}
return r;
}


/* Returns 1 if ok to serve the url, 0 if not. */
static int
really_check_referer( httpd_conn* hc )
{
httpd_server* hs;
char* cp1;
char* cp2;
char* cp3;
static char* refhost = (char*) 0;
static size_t refhost_size = 0;
char *lp;

hs = hc->hs;

/* Check for an empty referer. */
if ( hc->referer == (char*) 0 || hc->referer[0] == '\0' ||
( cp1 = strstr( hc->referer, "//" ) ) == (char*) 0 )
{
/* Disallow if we require a referer and the url matches. */
if ( hs->no_empty_referers && match( hs->url_pattern, hc->origfilename ) )
return 0;
/* Otherwise ok. */
return 1;
}

/* Extract referer host. */
cp1 += 2;
for ( cp2 = cp1; *cp2 != '/' && *cp2 != ':' && *cp2 != '\0'; ++cp2 )
continue;
httpd_realloc_str( &refhost, &refhost_size, cp2 - cp1 );
for ( cp3 = refhost; cp1 < cp2; ++cp1, ++cp3 )
if ( isupper(*cp1) )
*cp3 = tolower(*cp1);
else
*cp3 = *cp1;
*cp3 = '\0';

/* Local pattern? */
if ( hs->local_pattern != (char*) 0 )
lp = hs->local_pattern;
else
{
/* Not vhosting, use the server name. */
lp = hs->server_hostname;
if ( lp == (char*) 0 )
/* Couldn't figure out local hostname - give up. */
return 1;
}

/* If the referer host doesn't match the local host pattern, and
** the filename does match the url pattern, it's an illegal reference.
*/
if ( ! match( lp, refhost ) && match( hs->url_pattern, hc->origfilename ) )
return 0;
/* Otherwise ok. */
return 1;
}


char* char*
httpd_ntoa( httpd_sockaddr* saP ) httpd_ntoa( httpd_sockaddr* saP )
{ {
Expand Down
7 changes: 1 addition & 6 deletions ludd/src/libhttpd.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ typedef struct {
int no_log; int no_log;
FILE* logfp; FILE* logfp;
int no_symlink_check; int no_symlink_check;
char* url_pattern;
char* local_pattern;
int no_empty_referers;
} httpd_server; } httpd_server;


/* A connection. */ /* A connection. */
Expand Down Expand Up @@ -163,9 +160,7 @@ typedef struct {
extern httpd_server* httpd_initialize( extern httpd_server* httpd_initialize(
char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P,
unsigned short port, char* cgi_pattern, int cgi_limit, unsigned short port, char* cgi_pattern, int cgi_limit,
char* cwd, int no_log, FILE* logfp, char* cwd, int no_log, FILE* logfp, int no_symlink_check);
int no_symlink_check, char* url_pattern,
char* local_pattern, int no_empty_referers );


/* Change the log file. */ /* Change the log file. */
extern void httpd_set_logfp( httpd_server* hs, FILE* logfp ); extern void httpd_set_logfp( httpd_server* hs, FILE* logfp );
Expand Down
29 changes: 0 additions & 29 deletions ludd/src/ludd.8
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -270,35 +270,6 @@ error, which is number 401, you would put your HTML into the file
"errors/err401.html". "errors/err401.html".
If no custom error file is found for a given error number, then the If no custom error file is found for a given error number, then the
usual built-in error page is generated. usual built-in error page is generated.
.SH "NON-LOCAL REFERERS"
.PP
Sometimes another site on the net will embed your image files in their
HTML files, which basically means they're stealing your bandwidth.
You can prevent them from doing this by using non-local referer filtering.
With this option, certain files can only be fetched via a local referer.
The files have to be referenced by a local web page.
If a web page on some other site references the files, that fetch will
be blocked.
There are three config-file variables for this feature:
.TP
.B urlpat
A wildcard pattern for the URLs that should require a local referer.
This is typically just image files, sound files, and so on.
For example:
.nf
urlpat=**.jpg|**.gif|**.au|**.wav
.fi
For most sites, that one setting is all you need to enable referer filtering.
.TP
.B noemptyreferers
By default, requests with no referer at all, or a null referer, or a
referer with no apparent hostname, are allowed.
With this variable set, such requests are disallowed.
.TP
.B localpat
A wildcard pattern that specifies the local host or hosts.
This is used to determine if the host in the referer is local or not.
If not specified it defaults to the actual local hostname.
.SH SYMLINKS .SH SYMLINKS
.PP .PP
thttpd is very picky about symbolic links. thttpd is very picky about symbolic links.
Expand Down
25 changes: 1 addition & 24 deletions ludd/src/thttpd.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ static char* data_dir;
static int do_chroot, no_log, no_symlink_check; static int do_chroot, no_log, no_symlink_check;
static char* cgi_pattern; static char* cgi_pattern;
static int cgi_limit; static int cgi_limit;
static char* url_pattern;
static int no_empty_referers;
static char* local_pattern;
static char* logfile; static char* logfile;
static char* throttlefile; static char* throttlefile;
static char* hostname; static char* hostname;
Expand Down Expand Up @@ -660,9 +657,7 @@ main( int argc, char** argv )
hs = httpd_initialize( hs = httpd_initialize(
hostname, hostname,
gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0, gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0,
port, cgi_pattern, cgi_limit, cwd, no_log, logfp, port, cgi_pattern, cgi_limit, cwd, no_log, logfp, no_symlink_check );
no_symlink_check, url_pattern,
local_pattern, no_empty_referers );
if ( hs == (httpd_server*) 0 ) if ( hs == (httpd_server*) 0 )
{ {
syslog ( LOG_ERR, "Could not perform initialization. Exiting." ); syslog ( LOG_ERR, "Could not perform initialization. Exiting." );
Expand Down Expand Up @@ -889,9 +884,6 @@ parse_args( int argc, char** argv )
#else /* CGI_LIMIT */ #else /* CGI_LIMIT */
cgi_limit = 0; cgi_limit = 0;
#endif /* CGI_LIMIT */ #endif /* CGI_LIMIT */
url_pattern = (char*) 0;
no_empty_referers = 0;
local_pattern = (char*) 0;
throttlefile = (char*) 0; throttlefile = (char*) 0;
hostname = (char*) 0; hostname = (char*) 0;
logfile = (char*) 0; logfile = (char*) 0;
Expand Down Expand Up @@ -1074,21 +1066,6 @@ read_config( char* filename )
value_required( name, value ); value_required( name, value );
cgi_limit = atoi( value ); cgi_limit = atoi( value );
} }
else if ( strcasecmp( name, "urlpat" ) == 0 )
{
value_required( name, value );
url_pattern = e_strdup( value );
}
else if ( strcasecmp( name, "noemptyreferers" ) == 0 )
{
no_value_required( name, value );
no_empty_referers = 1;
}
else if ( strcasecmp( name, "localpat" ) == 0 )
{
value_required( name, value );
local_pattern = e_strdup( value );
}
else if ( strcasecmp( name, "throttles" ) == 0 ) else if ( strcasecmp( name, "throttles" ) == 0 )
{ {
value_required( name, value ); value_required( name, value );
Expand Down

0 comments on commit 8415dea

Please sign in to comment.