From: eldy <> Date: Fri, 21 Jul 2006 22:45:55 +0000 (+0000) Subject: Add some comments on how XSS is working and goal of CleanXSS function X-Git-Tag: AWSTATS_6_6_BETA~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22c6619fbaa628a5ee258744cbf579905ddebc32;p=thirdparty%2FAWStats.git Add some comments on how XSS is working and goal of CleanXSS function --- diff --git a/wwwroot/cgi-bin/awstats.pl b/wwwroot/cgi-bin/awstats.pl index 229c1212..864993f1 100644 --- a/wwwroot/cgi-bin/awstats.pl +++ b/wwwroot/cgi-bin/awstats.pl @@ -4395,12 +4395,20 @@ sub Sanitize { #------------------------------------------------------------------------------ # Function: Clean a string of HTML tags to avoid 'Cross Site Scripting attacks' # and clean | char. +# A XSS attack is providing an AWStats url with XSS code that is executed +# when page loaded by awstats CGI is loaded from AWStats server. Such a code +# can be +# This make the browser sending a request to the attacker server that contains +# cookie used for AWStats server sessions. Attacker can this way caught this +# cookie and used it to go on AWStats server like original visitor. For this +# resaon, parameter received by AWStats must be sanitized by this function +# before beeing put inside a web page. # Parameters: stringtoclean # Input: None # Output: None # Return: cleanedstring #------------------------------------------------------------------------------ -sub CleanFromCSSA { +sub CleanXSS { my $stringtoclean=shift; $stringtoclean =~ s//>/g; @@ -4942,7 +4950,7 @@ sub ShowHostInfo { #------------------------------------------------------------------------------ sub ShowURLInfo { my $url=shift; - my $nompage=CleanFromCSSA($url); + my $nompage=CleanXSS($url); # Call to plugins' function ShowInfoURL foreach my $pluginname (keys %{$PluginsLoaded{'ShowInfoURL'}}) { @@ -4954,7 +4962,7 @@ sub ShowURLInfo { if (length($nompage)>$MaxLengthOfShownURL) { $nompage=substr($nompage,0,$MaxLengthOfShownURL)."..."; } if ($ShowLinksOnUrl) { - my $newkey=CleanFromCSSA($url); + my $newkey=CleanXSS($url); if ($LogType eq 'W' || $LogType eq 'S') { # Web or streaming log file if ($newkey =~ /^http(s|):/i) { # URL seems to be extracted from a proxy log file print "".XMLEncode($nompage).""; @@ -5502,7 +5510,8 @@ if ($ENV{'GATEWAY_INTERFACE'}) { # Run from a browser as CGI $QueryString =~ s/&/&/g; } - $QueryString = CleanFromCSSA(&DecodeEncodedString($QueryString)); + # Remove all XSS vulnerabilities coming from AWStats parameters + $QueryString = CleanXSS(&DecodeEncodedString($QueryString)); # Security test if ($QueryString =~ /LogFile=([^&]+)/i) { error("Logfile parameter can't be overwritten when AWStats is used from a CGI"); } @@ -5515,11 +5524,11 @@ if ($ENV{'GATEWAY_INTERFACE'}) { # Run from a browser as CGI 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 =~ /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'}="$1"; } # Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed @@ -5551,7 +5560,8 @@ else { # Run from command line $QueryString .= "$NewLinkParams"; } - $QueryString = CleanFromCSSA($QueryString); + # Remove all XSS vulnerabilities coming from AWStats parameters + $QueryString = CleanXSS($QueryString); # Security test if ($ENV{'AWSTATS_DEL_GATEWAY_INTERFACE'} && $QueryString =~ /LogFile=([^&]+)/i) { error("Logfile parameter can't be overwritten when AWStats is used from a CGI"); } @@ -8118,7 +8128,7 @@ if (scalar keys %HTMLOutput) { if ($HTMLOutput{'allhosts'}) { &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Host'},\%_host_h,\%_host_p); } if ($HTMLOutput{'lasthosts'}) { &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Host'},\%_host_h,\%_host_l); } foreach my $key (@keylist) { - my $host=CleanFromCSSA($key); + my $host=CleanXSS($key); print "".($_robot_l{$key}?'':'')."$host".($_robot_l{$key}?'':'').""; &ShowHostInfo($key); if ($ShowHostsStats =~ /P/i) { print "".($_host_p{$key}?$_host_p{$key}:" ").""; } @@ -8161,7 +8171,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Host'},\%_host_h,\%_host_p); foreach my $key (@keylist) { - my $host=CleanFromCSSA($key); + my $host=CleanXSS($key); print "$host"; &ShowHostInfo($key); if ($ShowHostsStats =~ /P/i) { print "".($_host_p{$key}?$_host_p{$key}:" ").""; } @@ -8412,7 +8422,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,1,\%_unknownreferer_l,\%_unknownreferer_l); foreach my $key (@keylist) { - my $useragent=XMLEncode(CleanFromCSSA($key)); + my $useragent=XMLEncode(CleanXSS($key)); print "$useragent"; print "".Format_Date($_unknownreferer_l{$key},1).""; print "\n"; @@ -8437,7 +8447,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,1,\%_unknownrefererbrowser_l,\%_unknownrefererbrowser_l); foreach my $key (@keylist) { - my $useragent=XMLEncode(CleanFromCSSA($key)); + my $useragent=XMLEncode(CleanXSS($key)); print "$useragent".Format_Date($_unknownrefererbrowser_l{$key},1)."\n"; $total_l+=1; $count++; @@ -8653,7 +8663,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Refer'},\%_se_referrals_h,((scalar keys %_se_referrals_p)?\%_se_referrals_p:\%_se_referrals_h)); # before 5.4 only hits were recorded foreach my $key (@keylist) { - my $newreferer=$SearchEnginesHashLib{$key}||CleanFromCSSA($key); + my $newreferer=$SearchEnginesHashLib{$key}||CleanXSS($key); my $p_p; my $p_h; if ($TotalSearchEnginesPages) { $p_p=int($_se_referrals_p{$key}/$TotalSearchEnginesPages*1000)/10; } if ($TotalSearchEnginesHits) { $p_h=int($_se_referrals_h{$key}/$TotalSearchEnginesHits*1000)/10; } @@ -8711,7 +8721,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Refer'},\%_pagesrefs_h,((scalar keys %_pagesrefs_p)?\%_pagesrefs_p:\%_pagesrefs_h)); foreach my $key (@keylist) { - my $nompage=CleanFromCSSA($key); + my $nompage=CleanXSS($key); if (length($nompage)>$MaxLengthOfShownURL) { $nompage=substr($nompage,0,$MaxLengthOfShownURL)."..."; } my $p_p; my $p_h; if ($TotalRefererPages) { $p_p=int($_pagesrefs_p{$key}/$TotalRefererPages*1000)/10; } @@ -8753,8 +8763,8 @@ if (scalar keys %HTMLOutput) { foreach my $key (@keylist) { my $mot; # Convert coded keywords (utf8,...) to be correctly reported in HTML page. - if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanFromCSSA(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } - else { $mot = CleanFromCSSA(DecodeEncodedString($key)); } + if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanXSS(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } + else { $mot = CleanXSS(DecodeEncodedString($key)); } my $p; if ($TotalKeyphrases) { $p=int($_keyphrases{$key}/$TotalKeyphrases*1000)/10; } print "".XMLEncode($mot)."$_keyphrases{$key}$p %\n"; @@ -8782,8 +8792,8 @@ if (scalar keys %HTMLOutput) { foreach my $key (@keylist) { my $mot; # Convert coded keywords (utf8,...) to be correctly reported in HTML page. - if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanFromCSSA(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } - else { $mot = CleanFromCSSA(DecodeEncodedString($key)); } + if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanXSS(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } + else { $mot = CleanXSS(DecodeEncodedString($key)); } my $p; if ($TotalKeywords) { $p=int($_keywords{$key}/$TotalKeywords*1000)/10; } print "".XMLEncode($mot)."$_keywords{$key}$p %\n"; @@ -8810,9 +8820,9 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxRowsInHTMLOutput,1,\%_sider404_h,\%_sider404_h); foreach my $key (@keylist) { - my $nompage=XMLEncode(CleanFromCSSA($key)); + my $nompage=XMLEncode(CleanXSS($key)); #if (length($nompage)>$MaxLengthOfShownURL) { $nompage=substr($nompage,0,$MaxLengthOfShownURL)."..."; } - my $referer=XMLEncode(CleanFromCSSA($_referer404_h{$key})); + my $referer=XMLEncode(CleanXSS($_referer404_h{$key})); print "$nompage"; print "$_sider404_h{$key}"; print "".($referer?"$referer":" ").""; @@ -10243,7 +10253,7 @@ if (scalar keys %HTMLOutput) { my $count=0; &BuildKeyList($MaxNbOf{'RefererShown'},$MinHit{'Refer'},\%_se_referrals_h,((scalar keys %_se_referrals_p)?\%_se_referrals_p:\%_se_referrals_h)); foreach my $key (@keylist) { - my $newreferer=$SearchEnginesHashLib{$key}||CleanFromCSSA($key); + my $newreferer=$SearchEnginesHashLib{$key}||CleanXSS($key); print "- $newreferer"; print "".($_se_referrals_p{$key}?$_se_referrals_p{$key}:'0').""; print "$_se_referrals_h{$key}"; @@ -10335,8 +10345,8 @@ if (scalar keys %HTMLOutput) { foreach my $key (@keylist) { my $mot; # Convert coded keywords (utf8,...) to be correctly reported in HTML page. - if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanFromCSSA(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } - else { $mot = CleanFromCSSA(DecodeEncodedString($key)); } + if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanXSS(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } + else { $mot = CleanXSS(DecodeEncodedString($key)); } my $p; if ($TotalKeyphrases) { $p=int($_keyphrases{$key}/$TotalKeyphrases*1000)/10; } print "".XMLEncode($mot)."$_keyphrases{$key}$p %\n"; @@ -10367,8 +10377,8 @@ if (scalar keys %HTMLOutput) { foreach my $key (@keylist) { my $mot; # Convert coded keywords (utf8,...) to be correctly reported in HTML page. - if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanFromCSSA(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } - else { $mot = CleanFromCSSA(DecodeEncodedString($key)); } + if ($PluginsLoaded{'DecodeKey'}{'decodeutfkeys'}) { $mot=CleanXSS(DecodeKey_decodeutfkeys($key,$PageCode||'iso-8859-1')); } + else { $mot = CleanXSS(DecodeEncodedString($key)); } my $p; if ($TotalKeywords) { $p=int($_keywords{$key}/$TotalKeywords*1000)/10; } print "".XMLEncode($mot)."$_keywords{$key}$p %\n"; @@ -10543,7 +10553,7 @@ if (scalar keys %HTMLOutput) { &BuildKeyList($MaxNbOfExtra[$extranum],$MinHitExtra[$extranum],\%{'_section_' . $extranum . '_h'},\%{'_section_' . $extranum . '_h'}); } foreach my $key (@keylist) { - my $firstcol = CleanFromCSSA(DecodeEncodedString($key)); + my $firstcol = CleanXSS(DecodeEncodedString($key)); $total_p+=${'_section_' . $extranum . '_p'}{$key}; $total_h+=${'_section_' . $extranum . '_h'}{$key}; $total_k+=${'_section_' . $extranum . '_k'}{$key};