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;
$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};