aboutsummaryrefslogtreecommitdiffstats
path: root/package/uhttpd
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2010-08-11 00:05:34 +0000
committerJo-Philipp Wich <jow@openwrt.org>2010-08-11 00:05:34 +0000
commit3d99f030820877eb84835fb1be66a7db3f5b0c68 (patch)
treeab165f9195ca06e8c8b635f0edce60ce30c5a706 /package/uhttpd
parenta5371dfe3909f14d45803efcfa5a85446f7954ac (diff)
downloadupstream-3d99f030820877eb84835fb1be66a7db3f5b0c68.tar.gz
upstream-3d99f030820877eb84835fb1be66a7db3f5b0c68.tar.bz2
upstream-3d99f030820877eb84835fb1be66a7db3f5b0c68.zip
uhttpd: add option to reject requests from RFC1918 IPs to public server IPs (DNS rebinding countermeasure)
SVN-Revision: 22589
Diffstat (limited to 'package/uhttpd')
-rw-r--r--package/uhttpd/Makefile2
-rw-r--r--package/uhttpd/files/uhttpd.config5
-rwxr-xr-xpackage/uhttpd/files/uhttpd.init1
-rw-r--r--package/uhttpd/src/uhttpd-utils.c15
-rw-r--r--package/uhttpd/src/uhttpd-utils.h1
-rw-r--r--package/uhttpd/src/uhttpd.c15
-rw-r--r--package/uhttpd/src/uhttpd.h1
7 files changed, 38 insertions, 2 deletions
diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile
index 2ad0816e3a..8a7b5295d9 100644
--- a/package/uhttpd/Makefile
+++ b/package/uhttpd/Makefile
@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=uhttpd
-PKG_RELEASE:=12
+PKG_RELEASE:=13
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_BUILD_DEPENDS := libcyassl liblua
diff --git a/package/uhttpd/files/uhttpd.config b/package/uhttpd/files/uhttpd.config
index acdd62ea4e..534e8f8b29 100644
--- a/package/uhttpd/files/uhttpd.config
+++ b/package/uhttpd/files/uhttpd.config
@@ -12,6 +12,11 @@ config uhttpd main
# Server document root
option home /www
+ # Reject requests from RFC1918 IP addresses
+ # directed to the servers public IP(s).
+ # This is a DNS rebinding countermeasure.
+ option rfc1918_filter 1
+
# Certificate and private key for HTTPS.
# If no listen_https addresses are given,
# the key options are ignored.
diff --git a/package/uhttpd/files/uhttpd.init b/package/uhttpd/files/uhttpd.init
index d543dd84b9..b00b2e281b 100755
--- a/package/uhttpd/files/uhttpd.init
+++ b/package/uhttpd/files/uhttpd.init
@@ -75,6 +75,7 @@ start_instance()
append_bool "$cfg" no_symlinks "-S" 0
append_bool "$cfg" no_dirlists "-D" 0
+ append_bool "$cfg" rfc1918_filter "-R" 0
config_get http "$cfg" listen_http
for listen in $http; do
diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c
index 60badf26df..4a1423c715 100644
--- a/package/uhttpd/src/uhttpd-utils.c
+++ b/package/uhttpd/src/uhttpd-utils.c
@@ -59,6 +59,21 @@ int sa_port(void *sa)
return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
}
+int sa_rfc1918(void *sa)
+{
+ struct sockaddr_in *v4 = (struct sockaddr_in *)sa;
+ unsigned long a = htonl(v4->sin_addr.s_addr);
+
+ if( v4->sin_family == AF_INET )
+ {
+ return ((a >= 0x0A000000) && (a <= 0x0AFFFFFF)) ||
+ ((a >= 0xAC100000) && (a <= 0xAC1FFFFF)) ||
+ ((a >= 0xC0A80000) && (a <= 0xC0A8FFFF));
+ }
+
+ return 0;
+}
+
/* Simple strstr() like function that takes len arguments for both haystack and needle. */
char *strfind(char *haystack, int hslen, const char *needle, int ndlen)
{
diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h
index a6448b63bc..1b18265417 100644
--- a/package/uhttpd/src/uhttpd-utils.h
+++ b/package/uhttpd/src/uhttpd-utils.h
@@ -49,6 +49,7 @@ struct path_info {
const char * sa_straddr(void *sa);
const char * sa_strport(void *sa);
int sa_port(void *sa);
+int sa_rfc1918(void *sa);
char *strfind(char *haystack, int hslen, const char *needle, int ndlen);
diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c
index 82729627e0..be882470ad 100644
--- a/package/uhttpd/src/uhttpd.c
+++ b/package/uhttpd/src/uhttpd.c
@@ -524,7 +524,7 @@ int main (int argc, char **argv)
#endif
while( (opt = getopt(argc, argv,
- "fSDC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0
+ "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0
) {
switch(opt)
{
@@ -648,6 +648,10 @@ int main (int argc, char **argv)
conf.no_dirlists = 1;
break;
+ case 'R':
+ conf.rfc1918_filter = 1;
+ break;
+
#ifdef HAVE_CGI
/* cgi prefix */
case 'x':
@@ -728,6 +732,7 @@ int main (int argc, char **argv)
" -I string Use given filename as index page for directories\n"
" -S Do not follow symbolic links outside of the docroot\n"
" -D Do not allow directory listings, send 403 instead\n"
+ " -R Enable RFC1918 filter\n"
#ifdef HAVE_LUA
" -l string URL prefix for Lua handler, default is '/lua'\n"
" -L file Lua handler script, omit to disable Lua\n"
@@ -932,6 +937,14 @@ int main (int argc, char **argv)
/* parse message header */
if( (req = uh_http_header_recv(cl)) != NULL )
{
+ /* RFC1918 filtering required? */
+ if( conf.rfc1918_filter && sa_rfc1918(&cl->peeraddr) &&
+ !sa_rfc1918(&cl->servaddr) )
+ {
+ uh_http_sendhf(cl, 403, "Forbidden",
+ "Rejected request from RFC1918 IP to public server address");
+ }
+ else
#ifdef HAVE_LUA
/* Lua request? */
if( L && uh_path_match(conf.lua_prefix, req->url) )
diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h
index c8fdaf4846..fd2176ebdd 100644
--- a/package/uhttpd/src/uhttpd.h
+++ b/package/uhttpd/src/uhttpd.h
@@ -69,6 +69,7 @@ struct config {
int no_symlinks;
int no_dirlists;
int network_timeout;
+ int rfc1918_filter;
#ifdef HAVE_CGI
char *cgi_prefix;
#endif