From owner-freebsd-ports-bugs@FreeBSD.ORG Wed Oct 25 06:30:20 2006 Return-Path: X-Original-To: freebsd-ports-bugs@hub.freebsd.org Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9315916A403 for ; Wed, 25 Oct 2006 06:30:20 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 154C243D58 for ; Wed, 25 Oct 2006 06:30:20 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k9P6UJcl094662 for ; Wed, 25 Oct 2006 06:30:19 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k9P6UJxn094661; Wed, 25 Oct 2006 06:30:19 GMT (envelope-from gnats) Resent-Date: Wed, 25 Oct 2006 06:30:19 GMT Resent-Message-Id: <200610250630.k9P6UJxn094661@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Alex Samorukov" Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9352816A47E for ; Wed, 25 Oct 2006 06:26:14 +0000 (UTC) (envelope-from samm@os2.kiev.ua) Received: from em.volia.net (em.volia.net [82.144.192.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id C282243D53 for ; Wed, 25 Oct 2006 06:26:13 +0000 (GMT) (envelope-from samm@os2.kiev.ua) Received: from ip.85.202.156.27.dyn.sub-4.broadband.voliacable.com ([85.202.156.27] helo=samm.local) by em.volia.net with esmtp (Exim 4.63 (FreeBSD)) (envelope-from ) id 1GccDL-000BtI-MT; Wed, 25 Oct 2006 09:26:12 +0300 Message-Id: <1161757571.14550@samm.local> Date: Wed, 25 Oct 2006 09:26:11 +0300 From: "Alex Samorukov" To: "FreeBSD gnats submit" X-Send-Pr-Version: gtk-send-pr 0.4.7 Cc: samm@os2.kiev.ua Subject: ports/104784: www/awstats - fix for the security problems X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Oct 2006 06:30:20 -0000 >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//>/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: