Skip to content

Commit e759b33

Browse files
committed
Fix CSV injection issue if server responds with a malicious Server string & CSV output is opened in Excel or other spreadsheet app. Potentially malicious cell start characters are now prefaced with a ' mark. Thanks to Adam (@bytesoverbombs) for letting me know!
Also fixed a crash in the outdated plugin if the $sepr field ends up being something that triggers a panic in split().
1 parent 098177b commit e759b33

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

Diff for: program/plugins/nikto_outdated.plugin

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ sub nikto_outdated {
8888
$sepr = substr($sepr, (length($sepr) - 1), 1);
8989

9090
# break up ID string on $sepr
91-
my @T = split(/$sepr/, $mark->{'banner'});
91+
my @T = split(/\\$sepr/, $mark->{'banner'});
9292

9393
# assume last is version...
9494
for ($i = 0 ; $i < $#T ; $i++) { $MATCHSTRING .= "$T[$i] "; }

Diff for: program/plugins/nikto_report_csv.plugin

+25-16
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ sub csv_host_start {
5353
my ($handle, $mark) = @_;
5454
$mark->{'banner'} =~ s/"/\\"/g;
5555
my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'};
56-
print $handle "\"$hostname\","
57-
. "\"$mark->{'ip'}\","
58-
. "\"$mark->{'port'}\"," . "\"\"," . "\"\"," . "\"\","
59-
. "\"$mark->{'banner'}\"\n";
56+
print $handle "\"" . csv_safecell($hostname) . "\","
57+
. "\"" . csv_safecell($mark->{'ip'}) . "\","
58+
. "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"\"," . "\"\"," . "\"\","
59+
#. "\"" . $mark->{'banner'} . "\"\n";
60+
. "\"" . csv_safecell($mark->{'banner'}) . "\"\n";
6061
return;
6162
}
6263

@@ -67,33 +68,41 @@ sub csv_item {
6768
foreach my $uri (split(' ', $item->{'uri'})) {
6869
my $line = '';
6970
my $hostname = $item->{'mark'}->{'vhost'} ? $item->{'mark'}->{'vhost'} : $item->{'mark'}->{'hostname'};
70-
$line .= "\"$hostname\",";
71-
$line .= "\"$item->{'mark'}->{'ip'}\",";
72-
$line .= "\"$item->{'mark'}->{'port'}\",";
71+
$line .= "\"" . csv_safecell($hostname) . "\",";
72+
$line .= "\"" . csv_safecell($item->{'mark'}->{'ip'}) . \",";
73+
$line .= "\"" . csv_safecell($item->{'mark'}->{'port'}) . "\",";
7374

7475
$line .= "\"";
7576
if ($item->{'osvdb'} ne '') { $line .= "OSVDB-" . $item->{'osvdb'}; }
7677
$line .= "\",";
7778

7879
$line .= "\"";
79-
if ($item->{'method'} ne '') { $line .= $item->{'method'}; }
80+
if ($item->{'method'} ne '') { $line .= csv_safecell($item->{'method'}); }
8081
$line .= "\",";
8182

8283
$line .= "\"";
8384
if (($uri ne '') && ($mark->{'root'} ne '') && ($uri !~ /^$mark->{'root'}/))
84-
{ $line .= $mark->{'root'} . $uri; }
85-
else { $line .= $uri; }
85+
{ $line .= csv_safecell($mark->{'root'}) . $uri; }
86+
else { $line .= csv_safecell($uri); }
8687
$line .= "\",";
8788

88-
my $msg = $item->{'message'};
89-
$uri=quotemeta($uri);
90-
my $root = quotemeta($mark->{'root'});
91-
$msg =~ s/^$uri:\s//;
92-
$msg =~ s/^$root$uri:\s//;
89+
my $msg = $item->{'message'};
90+
$uri=quotemeta($uri);
91+
my $root = quotemeta($mark->{'root'});
92+
$msg =~ s/^$uri:\s//;
93+
$msg =~ s/^$root$uri:\s//;
9394
$msg =~ s/"/\\"/g;
94-
$line .= "\"$msg\"";
95+
$line .= "\"" . csv_safecell($msg) ."\"";
9596
print $handle "$line\n";
9697
}
9798
}
9899

100+
###############################################################################
101+
# prevent CSV injection attacks
102+
sub csv_safecell {
103+
my $celldata = $_[0] || return;
104+
if ($celldata =~ /^[=+@-]/) { $celldata = "'" . $celldata; }
105+
return $celldata;
106+
}
107+
99108
1;

0 commit comments

Comments
 (0)