Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Oct 2006 09:26:11 +0300
From:      "Alex Samorukov" <samm@os2.kiev.ua>
To:        "FreeBSD gnats submit" <FreeBSD-gnats-submit@FreeBSD.org>
Cc:        samm@os2.kiev.ua
Subject:   ports/104784: www/awstats - fix for the security problems
Message-ID:  <1161757571.14550@samm.local>
Resent-Message-ID: <200610250630.k9P6UJxn094661@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         104784
>Category:       ports
>Synopsis:       www/awstats - fix for the security problems
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 25 06:30:19 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Alex Samorukov
>Release:        FreeBSD 6.1-RELEASE i386
>Organization:
Shevchenko Didkovskiy and Partners 
>Environment:


System: FreeBSD 6.1-RELEASE #2: Wed May 17 22:22:18 EEST 2006
    root@samm.local:/usr/obj/usr/src/sys/SAMMKRNL



>Description:


Awstats 5.5 is known have a command injection vulnerability. I backported fix for this problems from cvs version and put it as patch file. I`m sure that this fix security problems with awstats so port can be unbroken. Also i decided to maintain this port, because i`m using awstats and can support it.


>How-To-Repeat:





>Fix:


diff -ruN --exclude=CVS /usr/ports/www/awstats/Makefile /usr/home/samm/src/ports/awstats/Makefile
--- /usr/ports/www/awstats/Makefile	Wed Sep 13 07:19:39 2006
+++ /usr/home/samm/src/ports/awstats/Makefile	Wed Oct 25 09:18:17 2006
@@ -7,18 +7,14 @@
 
 PORTNAME=	awstats
 PORTVERSION=	6.5
-PORTREVISION=	1
+PORTREVISION=	2
 PORTEPOCH=	1
 CATEGORIES=	www
 MASTER_SITES=	${MASTER_SITE_SOURCEFORGE}
 MASTER_SITE_SUBDIR=	${PORTNAME}
 
-MAINTAINER=	ports@FreeBSD.org
+MAINTAINER=	samm@os2.kiev.ua
 COMMENT=	Free real-time logfile analyzer to get advanced web statistics
-
-FORBIDDEN=	Command Injection Vulnerability
-DEPRECATED=	${FORBIDDEN}
-EXPIRATION_DATE=2006-12-01
 
 RUN_DEPENDS=	${SITE_PERL}/Net/XWhois.pm:${PORTSDIR}/net/p5-Net-XWhois
 
diff -ruN --exclude=CVS /usr/ports/www/awstats/files/patch-awstats.pl-security /usr/home/samm/src/ports/awstats/files/patch-awstats.pl-security
--- /usr/ports/www/awstats/files/patch-awstats.pl-security	Thu Jan  1 03:00:00 1970
+++ /usr/home/samm/src/ports/awstats/files/patch-awstats.pl-security	Wed Oct 25 09:16:17 2006
@@ -0,0 +1,91 @@
+--- wwwroot/cgi-bin/awstats.pl	Wed Oct 25 09:05:29 2006
++++ wwwroot/cgi-bin/awstats.pl	Wed Oct 25 09:02:30 2006
+@@ -1131,7 +1131,18 @@
+ 	my $configdir=shift;
+ 	my @PossibleConfigDir=();
+ 
+-	if ($configdir) { @PossibleConfigDir=("$configdir"); }
++	if ($configdir)
++	{
++		# If from CGI, overwriting of configdir is only possible if AWSTATS_ENABLE_CONFIG_DIR defined
++		#if ($ENV{'GATEWAY_INTERFACE'} && ! $ENV{"AWSTATS_ENABLE_CONFIG_DIR"})
++		#{
++		#	error("Sorry, to allow overwriting of configdir parameter from an AWStats CGI usage, environment variable AWSTATS_ENABLE_CONFIG_DIR must be set to 1");
++		#}
++		#else
++		#{
++			@PossibleConfigDir=("$configdir");
++		#}
++	}
+ 	else { @PossibleConfigDir=("$DIR","/etc/awstats","/usr/local/etc/awstats","/etc","/etc/opt/awstats"); }
+ 
+ 	# Open config file
+@@ -4439,6 +4450,7 @@
+ 	my $stringtoclean=shift;
+ 	$stringtoclean =~ s/</&lt;/g;
+ 	$stringtoclean =~ s/>/&gt;/g;
++	$stringtoclean =~ s/|//g;
+ 	return $stringtoclean;
+ }
+ 
+@@ -5534,7 +5546,7 @@
+ 	    $QueryString =~ s/&/&amp;/g;
+ 	}
+ 
+-	$QueryString = CleanFromCSSA($QueryString);
++	$QueryString = CleanFromCSSA(&DecodeEncodedString($QueryString));
+ 
+     # Security test
+ 	if ($QueryString =~ /LogFile=([^&]+)/i)				{ error("Logfile parameter can't be overwritten when AWStats is used from a CGI"); }
+@@ -5542,26 +5554,26 @@
+ 	# No update but report by default when run from a browser
+ 	$UpdateStats=($QueryString=~/update=1/i?1:0);
+ 
+-	if ($QueryString =~ /config=([^&]+)/i)				{ $SiteConfig=&DecodeEncodedString("$1"); }
+-	if ($QueryString =~ /diricons=([^&]+)/i)			{ $DirIcons=&DecodeEncodedString("$1"); }
+-	if ($QueryString =~ /pluginmode=([^&]+)/i)			{ $PluginMode=&Sanitize(&DecodeEncodedString("$1"),1); }
+-	if ($QueryString =~ /configdir=([^&]+)/i)			{ $DirConfig=&Sanitize(&DecodeEncodedString("$1")); }
+-	# All filters
+-	if ($QueryString =~ /hostfilter=([^&]+)/i)			{ $FilterIn{'host'}=&DecodeEncodedString("$1"); }			# Filter on host list can also be defined with hostfilter=filter
+-	if ($QueryString =~ /hostfilterex=([^&]+)/i)		{ $FilterEx{'host'}=&DecodeEncodedString("$1"); }			#
+-	if ($QueryString =~ /urlfilter=([^&]+)/i)			{ $FilterIn{'url'}=&DecodeEncodedString("$1"); }			# Filter on URL list can also be defined with urlfilter=filter
+-	if ($QueryString =~ /urlfilterex=([^&]+)/i)			{ $FilterEx{'url'}=&DecodeEncodedString("$1"); }			#
+-	if ($QueryString =~ /refererpagesfilter=([^&]+)/i)	{ $FilterIn{'refererpages'}=&DecodeEncodedString("$1"); }	# Filter on referer list can also be defined with refererpagesfilter=filter
+-	if ($QueryString =~ /refererpagesfilterex=([^&]+)/i) { $FilterEx{'refererpages'}=&DecodeEncodedString("$1"); }	#
++	if ($QueryString =~ /config=([^&]+)/i)				{ $SiteConfig=&Sanitize("$1"); }
++	if ($QueryString =~ /diricons=([^&]+)/i)			{ $DirIcons="$1"; }
++	if ($QueryString =~ /pluginmode=([^&]+)/i)			{ $PluginMode=&Sanitize("$1",1); }
++	if ($QueryString =~ /configdir=([^&]+)/i)			{ $DirConfig=&Sanitize("$1"); }	
++ 	# All filters
++	if ($QueryString =~ /hostfilter=([^&]+)/i)			{ $FilterIn{'host'}="$1"; }			# Filter on host list can also be defined with hostfilter=filter
++	if ($QueryString =~ /hostfilterex=([^&]+)/i)		{ $FilterEx{'host'}="$1"; }			#
++	if ($QueryString =~ /urlfilter=([^&]+)/i)			{ $FilterIn{'url'}="$1"; }			# Filter on URL list can also be defined with urlfilter=filter
++	if ($QueryString =~ /urlfilterex=([^&]+)/i)			{ $FilterEx{'url'}="$1"; }			#
++	if ($QueryString =~ /refererpagesfilter=([^&]+)/i)	{ $FilterIn{'refererpages'}="$1"; }	# Filter on referer list can also be defined with refererpagesfilter=filter
++	if ($QueryString =~ /refererpagesfilterex=([^&]+)/i) { $FilterEx{'refererpages'}="$1"; }	#
+ 	# All output
+-	if ($QueryString =~ /output=allhosts:([^&]+)/i)		{ $FilterIn{'host'}=&DecodeEncodedString("$1"); }			# Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed
+-	if ($QueryString =~ /output=lasthosts:([^&]+)/i)	{ $FilterIn{'host'}=&DecodeEncodedString("$1"); }			# Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed
+-	if ($QueryString =~ /output=urldetail:([^&]+)/i)	{ $FilterIn{'url'}=&DecodeEncodedString("$1"); }			# Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed
+-	if ($QueryString =~ /output=refererpages:([^&]+)/i)	{ $FilterIn{'refererpages'}=&DecodeEncodedString("$1"); }	# Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed
++	if ($QueryString =~ /output=allhosts:([^&]+)/i)		{ $FilterIn{'host'}="$1"; }			# Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed
++	if ($QueryString =~ /output=lasthosts:([^&]+)/i)	{ $FilterIn{'host'}="$1"; }			# Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed
++	if ($QueryString =~ /output=urldetail:([^&]+)/i)	{ $FilterIn{'url'}="$1"; }			# Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed
++	if ($QueryString =~ /output=refererpages:([^&]+)/i)	{ $FilterIn{'refererpages'}="$1"; }	# Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed
+ 
+ 	# If migrate
+ 	if ($QueryString =~ /(^|-|&|&amp;)migrate=([^&]+)/i)	{
+-		$MigrateStats=&DecodeEncodedString("$2"); 
++		$MigrateStats=&Sanitize("$2"); 
+ 		$MigrateStats =~ /^(.*)$PROG(\d{0,2})(\d\d)(\d\d\d\d)(.*)\.txt$/;
+ 		$SiteConfig=$5?$5:'xxx'; $SiteConfig =~ s/^\.//;		# SiteConfig is used to find config file
+ 	}
+@@ -5625,8 +5637,6 @@
+ if ($QueryString =~ /(^|&|&amp;)databasebreak=(\w+)/i)	{ $DatabaseBreak=$2; }
+ if ($QueryString =~ /(^|&|&amp;)updatefor=(\d+)/i)		{ $UpdateFor=$2; }
+ if ($QueryString =~ /(^|&|&amp;)noloadplugin=([^&]+)/i)	{ foreach (split(/,/,$2)) { $NoLoadPlugin{&Sanitize("$_",1)}=1; } }
+-#Removed for security reasons
+-#if ($QueryString =~ /(^|&|&amp;)loadplugin=([^&]+)/i)		{ foreach (split(/,/,$2)) { $NoLoadPlugin{&Sanitize("$_",1)}=-1; } }
+ if ($QueryString =~ /(^|&|&amp;)limitflush=(\d+)/i)		{ $LIMITFLUSH=$2; }
+ # Get/Define output
+ if ($QueryString =~ /(^|&|&amp;)output(=[^&]*|)(.*)(&|&amp;)output(=[^&]*|)(&|$)/i) { error("Only 1 output option is allowed","","",1); }


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1161757571.14550>