Florian Weimer wrote... > The Nagios web front end does not HTML-escape status strings reported > by monitored services. As a result, these services can perform the > usual cross-site scripting attacks, or worse. compromise the browser > and gain access to the management network.
The patch attached * backports the sanitazion prepared but not completed in 2.10. * Works around the still empty "strip_plugin_html" in 2.10 by calling "html_encode". * Fixes encoding of 8bit characters. * Adds more space to "temp_expansion" in "html_encode", taken from CVS http://nagios.cvs.sourceforge.net/nagios/nagios/cgi/cgiutils.c?r1=1.44.2.5&r2=1.44.2.6 See my recent mail to nagios-devel for details. Note that the patch against include/cgiutils.h.in will fail if the recent patches due to #448371/CVE-2007-5624 have been applied. This can be cured easily. Status: Works for me Christoph
diff -urN nagios2-2.6.ORIG/cgi/avail.c nagios2-2.6/cgi/avail.c
--- nagios2-2.6.ORIG/cgi/avail.c 2006-04-06 00:33:32.000000000 +0200
+++ nagios2-2.6/cgi/avail.c 2007-11-06 11:16:56.000000000 +0100
@@ -3417,7 +3417,7 @@
printf("<td
class='logEntries%s'>%s</td>",bgclass,end_date_time);
printf("<td class='logEntries%s'>%s</td>",bgclass,duration);
printf("<td
class='logEntries%s'>%s%s</td>",ebgclass,entry_type,state_type);
- printf("<td
class='logEntries%s'>%s</td>",bgclass,(temp_as->state_info==NULL)?"":temp_as->state_info);
+ printf("<td
class='logEntries%s'>%s</td>",bgclass,(temp_as->state_info==NULL)?"":html_encode(temp_as->state_info));
printf("</tr>\n");
}
@@ -4038,7 +4038,7 @@
/* down times */
printf("<tr CLASS='dataOdd'><td CLASS='hostDOWN'
rowspan=3>DOWN</td>");
- printf("<td CLASS='dataOdd'>Unscheduled</td><td
CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td
class='dataOdd'>%2.3f%%</td></tr>\n",time_down_unscheduled_string,percent_time_down_unscheduled,percent_time_down_known);
+ printf("<td CLASS='dataOdd'>Unscheduled</td><td
CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td
class='dataOdd'>%2.3f%%</td></tr>\n",time_down_unscheduled_string,percent_time_down_unscheduled,percent_time_down_unscheduled_known);
printf("<tr CLASS='dataOdd'><td
CLASS='dataOdd'>Scheduled</td><td CLASS='dataOdd'>%s</td><td
CLASS='dataOdd'>%2.3f%%</td><td
class='dataOdd'>%2.3f%%</td></tr>\n",time_down_scheduled_string,percent_time_down_scheduled,percent_time_down_scheduled_known);
printf("<tr CLASS='hostDOWN'><td CLASS='hostDOWN'>Total</td><td
CLASS='hostDOWN'>%s</td><td CLASS='hostDOWN'>%2.3f%%</td><td
class='hostDOWN'>%2.3f%%</td></tr>\n",time_down_string,percent_time_down,percent_time_down_known);
diff -urN nagios2-2.6.ORIG/cgi/cgiutils.c nagios2-2.6/cgi/cgiutils.c
--- nagios2-2.6.ORIG/cgi/cgiutils.c 2006-11-13 19:40:34.000000000 +0100
+++ nagios2-2.6/cgi/cgiutils.c 2007-11-06 11:18:08.000000000 +0100
@@ -1345,7 +1345,7 @@
char * html_encode(char *input){
int len,output_len;
int x,y;
- char temp_expansion[7];
+ char temp_expansion[10];
len=(int)strlen(input);
output_len=(int)sizeof(encoded_html_string);
@@ -1366,8 +1366,9 @@
y++;
}
+#ifdef NOT_SO_SURE_ABOUT_THIS
/* spaces are encoded as non-breaking spaces */
- else if((char)input[x]<=(char)' '){
+ else if((char)input[x]==(char)' '){
encoded_html_string[y]='\x0';
if((int)strlen(encoded_html_string)<(output_len-6)){
@@ -1375,11 +1376,30 @@
y+=6;
}
}
+#endif
+
+ else if((char)input[x]==(char)'<'){
+
+ encoded_html_string[y]='\x0';
+ if((int)strlen(encoded_html_string)<(output_len-4)){
+ strcat(encoded_html_string,"<");
+ y+=4;
+ }
+ }
+
+ else if((char)input[x]==(char)'>'){
+
+ encoded_html_string[y]='\x0';
+ if((int)strlen(encoded_html_string)<(output_len-4)){
+ strcat(encoded_html_string,">");
+ y+=4;
+ }
+ }
/* for simplicity, everything else gets represented by its
numeric value */
else{
encoded_html_string[y]='\x0';
- sprintf(temp_expansion,"&#%d;",(unsigned int)input[x]);
+ sprintf(temp_expansion,"&#%d;",(unsigned char)input[x]);
if((int)strlen(encoded_html_string)<(output_len-strlen(temp_expansion))){
strcat(encoded_html_string,temp_expansion);
y+=strlen(temp_expansion);
@@ -1394,6 +1414,16 @@
+/* strips dangerous HTML from plugin output */
+char * strip_plugin_html(char *input){
+
+ /* TODO */
+ /* Use html_encode for the time being */
+ return html_encode(input);
+ }
+
+
+
/* determines the log file we should use (from current time) */
void get_log_archive_to_use(int archive,char *buffer,int buffer_length){
struct tm *t;
Binary files nagios2-2.6.ORIG/cgi/.cgiutils.c.swp and
nagios2-2.6/cgi/.cgiutils.c.swp differ
diff -urN nagios2-2.6.ORIG/cgi/extinfo.c nagios2-2.6/cgi/extinfo.c
--- nagios2-2.6.ORIG/cgi/extinfo.c 2006-10-09 17:59:02.000000000 +0200
+++ nagios2-2.6/cgi/extinfo.c 2007-11-06 11:16:56.000000000 +0100
@@ -995,9 +995,9 @@
printf("<TR><TD CLASS='dataVar'>Host Status:</td><td
CLASS='dataVal'><DIV
CLASS='%s'> %s %s </DIV></td></tr>\n",bg_class,state_string,(temp_hoststatus->problem_has_been_acknowledged==TRUE)?"(Has
been acknowledged)":"");
- printf("<TR><TD CLASS='dataVar'>Status Information:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_hoststatus->plugin_output==NULL)?"":temp_hoststatus->plugin_output);
+ printf("<TR><TD CLASS='dataVar'>Status Information:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_hoststatus->plugin_output==NULL)?"":strip_plugin_html(temp_hoststatus->plugin_output));
- printf("<TR><TD CLASS='dataVar'>Performance Data:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_hoststatus->perf_data==NULL)?"":temp_hoststatus->perf_data);
+ printf("<TR><TD CLASS='dataVar'>Performance Data:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_hoststatus->perf_data==NULL)?"":html_encode(temp_hoststatus->perf_data));
printf("<TR><TD CLASS='dataVar'>Current Attempt:</TD><TD
CLASS='dataVal'>%d/%d</TD></TR>\n",temp_hoststatus->current_attempt,temp_hoststatus->max_attempts);
@@ -1305,9 +1305,9 @@
}
printf("<TR><TD CLASS='dataVar'>Current Status:</TD><TD
CLASS='dataVal'><DIV
CLASS='%s'> %s %s </DIV></TD></TR>\n",bg_class,state_string,(temp_svcstatus->problem_has_been_acknowledged==TRUE)?"(Has
been acknowledged)":"");
- printf("<TR><TD CLASS='dataVar'>Status Information:</TD><TD
CLASS='dataVal'>%s</TD></TR>\n",(temp_svcstatus->plugin_output==NULL)?"":temp_svcstatus->plugin_output);
+ printf("<TR><TD CLASS='dataVar'>Status Information:</TD><TD
CLASS='dataVal'>%s</TD></TR>\n",(temp_svcstatus->plugin_output==NULL)?"":strip_plugin_html(temp_svcstatus->plugin_output));
- printf("<TR><TD CLASS='dataVar'>Performance Data:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_svcstatus->perf_data==NULL)?"":temp_svcstatus->perf_data);
+ printf("<TR><TD CLASS='dataVar'>Performance Data:</td><td
CLASS='dataVal'>%s</td></tr>\n",(temp_svcstatus->perf_data==NULL)?"":html_encode(temp_svcstatus->perf_data));
printf("<TR><TD CLASS='dataVar'>Current Attempt:</TD><TD
CLASS='dataVal'>%d/%d</TD></TR>\n",temp_svcstatus->current_attempt,temp_svcstatus->max_attempts);
diff -urN nagios2-2.6.ORIG/cgi/history.c nagios2-2.6/cgi/history.c
--- nagios2-2.6.ORIG/cgi/history.c 2006-03-21 22:31:46.000000000 +0100
+++ nagios2-2.6/cgi/history.c 2007-11-06 11:16:56.000000000 +0100
@@ -901,7 +901,7 @@
if(display_frills==TRUE)
printf("<img align='left' src='%s%s'
alt='%s' title='%s'>",url_images_path,image,image_alt,image_alt);
- printf("[%s] %s<br
clear='all'>\n",date_time,temp_buffer);
+ printf("[%s] %s<br
clear='all'>\n",date_time,strip_plugin_html(temp_buffer));
found_line=TRUE;
}
}
diff -urN nagios2-2.6.ORIG/cgi/notifications.c nagios2-2.6/cgi/notifications.c
--- nagios2-2.6.ORIG/cgi/notifications.c 2006-10-09 17:59:02.000000000
+0200
+++ nagios2-2.6/cgi/notifications.c 2007-11-06 11:16:56.000000000 +0100
@@ -714,7 +714,7 @@
printf("<td
CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",date_time);
printf("<td CLASS='notifications%s'><a
href='%s?type=contacts#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(contact_name),contact_name);
printf("<td CLASS='notifications%s'><a
href='%s?type=commands#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(method_name),method_name);
- printf("<td
CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",temp_buffer);
+ printf("<td
CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",strip_plugin_html(temp_buffer));
printf("</tr>\n");
}
}
diff -urN nagios2-2.6.ORIG/cgi/showlog.c nagios2-2.6/cgi/showlog.c
--- nagios2-2.6.ORIG/cgi/showlog.c 2006-03-21 22:31:46.000000000 +0100
+++ nagios2-2.6/cgi/showlog.c 2007-11-06 11:16:56.000000000 +0100
@@ -513,7 +513,7 @@
if(display_frills==TRUE)
printf("<img align='left' src='%s%s' alt='%s'
title='%s'>",url_images_path,image,image_alt,image_alt);
- printf("[%s] %s<br
clear='all'>\n",date_time,(temp_buffer==NULL)?"":temp_buffer);
+ printf("[%s] %s<br
clear='all'>\n",date_time,(temp_buffer==NULL)?"":strip_plugin_html(temp_buffer));
}
printf("</DIV></P>\n");
diff -urN nagios2-2.6.ORIG/cgi/status.c nagios2-2.6/cgi/status.c
--- nagios2-2.6.ORIG/cgi/status.c 2006-10-09 17:59:02.000000000 +0200
+++ nagios2-2.6/cgi/status.c 2007-11-06 11:16:56.000000000 +0100
@@ -1729,7 +1729,7 @@
printf("<TD CLASS='status%s'
nowrap>%s</TD>\n",status_bg_class,date_time);
printf("<TD CLASS='status%s'
nowrap>%s</TD>\n",status_bg_class,state_duration);
printf("<TD
CLASS='status%s'>%d/%d</TD>\n",status_bg_class,temp_status->current_attempt,temp_status->max_attempts);
- printf("<TD
CLASS='status%s'>%s </TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output);
+ printf("<TD
CLASS='status%s'>%s </TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":strip_plugin_html(temp_status->plugin_output));
printf("</TR>\n");
@@ -2113,7 +2113,7 @@
printf("<TD
CLASS='status%s'>%s</TD>\n",status_class,status);
printf("<TD CLASS='status%s'
nowrap>%s</TD>\n",status_bg_class,date_time);
printf("<TD CLASS='status%s'
nowrap>%s</TD>\n",status_bg_class,state_duration);
- printf("<TD
CLASS='status%s'>%s </TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output);
+ printf("<TD
CLASS='status%s'>%s </TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":strip_plugin_html(temp_status->plugin_output));
printf("</TR>\n");
}
diff -urN nagios2-2.6.ORIG/include/cgiutils.h.in
nagios2-2.6/include/cgiutils.h.in
--- nagios2-2.6.ORIG/include/cgiutils.h.in 2006-01-20 18:34:53.000000000
+0100
+++ nagios2-2.6/include/cgiutils.h.in 2007-11-06 11:16:56.000000000 +0100
@@ -470,6 +470,7 @@
char * url_encode(char *); /* encodes a
string in proper URL format */
char * html_encode(char *); /* encodes a
string in HTML format (for what the user sees) */
+char * strip_plugin_html(char *); /* strips
dangerous HTML from plugin output */
void get_time_breakdown(unsigned long,int *,int *,int *,int *); /*
given total seconds, get days, hours, minutes, seconds */
signature.asc
Description: Digital signature

