ports/104784: www/awstats - fix for the security problems
Alex Samorukov
samm at os2.kiev.ua
Wed Oct 25 06:30:20 UTC 2006
>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 at 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 at FreeBSD.org
+MAINTAINER= samm at 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/</</g;
+ $stringtoclean =~ s/>/>/g;
++ $stringtoclean =~ s/|//g;
+ return $stringtoclean;
+ }
+
+@@ -5534,7 +5546,7 @@
+ $QueryString =~ s/&/&/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 =~ /(^|-|&|&)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 =~ /(^|&|&)databasebreak=(\w+)/i) { $DatabaseBreak=$2; }
+ if ($QueryString =~ /(^|&|&)updatefor=(\d+)/i) { $UpdateFor=$2; }
+ if ($QueryString =~ /(^|&|&)noloadplugin=([^&]+)/i) { foreach (split(/,/,$2)) { $NoLoadPlugin{&Sanitize("$_",1)}=1; } }
+-#Removed for security reasons
+-#if ($QueryString =~ /(^|&|&)loadplugin=([^&]+)/i) { foreach (split(/,/,$2)) { $NoLoadPlugin{&Sanitize("$_",1)}=-1; } }
+ if ($QueryString =~ /(^|&|&)limitflush=(\d+)/i) { $LIMITFLUSH=$2; }
+ # Get/Define output
+ if ($QueryString =~ /(^|&|&)output(=[^&]*|)(.*)(&|&)output(=[^&]*|)(&|$)/i) { error("Only 1 output option is allowed","","",1); }
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list