>From 3107f838f6d3949d09a220cf8cb6c04ca5b0c4e7 Mon Sep 17 00:00:00 2001
From: Michael Friedrich <michael.friedrich@univie.ac.at>
Date: Fri, 10 Jun 2011 09:49:47 +0200
Subject: [PATCH] fix xss vulnerability in config/statusmap.cgi trackerids #207 #224

the main cause for this in config.cgi is the lack to really
escaping malicious html strings like the injected JS example
are showing.

the proposed fix only targets the local expander form, while you
can also use the other config locations (e.g. hosts) to also
use the expand GET attribute and inject that.

even more, some escape_html_tag=1 setting in cgi.cfg will prevent
the most. but setting this to 0 (disabling for e.g. check_multi
output) will cause more evil than expected.

this patch addresses all possible use cases and fixes them
accordingly. next to that, it also includes the statusmaps.cgi
fix too.

refer to https://dev.icinga.org/issues/1605 for a detailed
analysis.
---
 cgi/config.c    |   40 ++++++++++++++++++++--------------------
 cgi/statusmap.c |    2 +-
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/cgi/config.c b/cgi/config.c
index 8f5b0a4..a58f265 100644
--- a/cgi/config.c
+++ b/cgi/config.c
@@ -109,7 +109,7 @@ void print_expand_input(int type){
 	else if (type==DISPLAY_HOSTESCALATIONS){	seldesc=" Escalations for Host";	}
 	printf("<tr><td align=left class='reportSelectSubTitle'>Show Only%s:</td></tr>\n",seldesc);
 	printf("<tr><td align=left class='reportSelectItem'><input type='text' name='expand'\n");
-	printf("value='%s'>",html_encode(to_expand,FALSE));
+	printf("value='%s'>",escape_string(to_expand));
 	}
 
 int main(void){
@@ -464,7 +464,7 @@ void display_hosts(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Host%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P><DIV ALIGN=CENTER>\n");
 	printf("<TABLE BORDER=0 CLASS='data'>\n");
@@ -794,7 +794,7 @@ void display_hostgroups(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Host Group%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -869,7 +869,7 @@ void display_servicegroups(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Service Group%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -948,7 +948,7 @@ void display_contacts(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Contact%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1130,7 +1130,7 @@ void display_contactgroups(void){
 
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Contact Group%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1204,7 +1204,7 @@ void display_services(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Service%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":"s Named or on Host "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":"s Named or on Host "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1530,7 +1530,7 @@ void display_timeperiods(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Time Period%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1715,7 +1715,7 @@ void display_commands(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Command%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":" "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P><DIV ALIGN=CENTER>\n");
 	printf("<TABLE BORDER=0 CLASS='data'>\n");
@@ -1762,7 +1762,7 @@ void display_servicedependencies(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Service Dependencie%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":"s Involving Host "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":"s Involving Host "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1869,7 +1869,7 @@ void display_serviceescalations(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Service Escalation%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":"s on Host "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":"s on Host "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -1997,7 +1997,7 @@ void display_hostdependencies(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Host Dependencie%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":"s Involving Host "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":"s Involving Host "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -2088,7 +2088,7 @@ void display_hostescalations(void){
 	        }
 
 	printf("<P><DIV ALIGN=CENTER CLASS='dataTitle'>Host Escalation%s%s</DIV></P>\n",
-		(*to_expand=='\0'?"s":"s for Host "),(*to_expand=='\0'?"":html_encode(to_expand,FALSE)));
+		(*to_expand=='\0'?"s":"s for Host "),(*to_expand=='\0'?"":escape_string(to_expand)));
 
 	printf("<P>\n");
 	printf("<DIV ALIGN=CENTER>\n");
@@ -2275,9 +2275,9 @@ void display_command_expansion(void){
 	if ((*to_expand)!='\0'){
 		arg_count[0]=0;
 
-		printf("<TR CLASS='dataEven'><TD CLASS='dataEven'>To expand:</TD><TD CLASS='dataEven'>%s",command_args[0]);
+		printf("<TR CLASS='dataEven'><TD CLASS='dataEven'>To expand:</TD><TD CLASS='dataEven'>%s",escape_string(command_args[0]));
 		for (i=1;(i<MAX_COMMAND_ARGUMENTS)&&command_args[i];i++)
-			printf("!<FONT\n   COLOR='%s'>%s</FONT>",hash_color(i),command_args[i]);
+			printf("!<FONT\n   COLOR='%s'>%s</FONT>",hash_color(i),escape_string(command_args[i]));
 		printf("\n</TD></TR>\n");
 
 		/* check all commands */
@@ -2335,7 +2335,7 @@ void display_command_expansion(void){
 								if (command_args[i]){
 									if (*(command_args[i])!='\0') printf("<FONT COLOR='%s'><B>%s%s%s</B></FONT>",
 										hash_color(i),((lead_space[i]>0)||(trail_space[i]>0)?"<U>&zwj;":""),
-										html_encode(command_args[i],FALSE),((lead_space[i]>0)||(trail_space[i]>0)?"&zwj;</U>":""));
+										escape_string(command_args[i]),((lead_space[i]>0)||(trail_space[i]>0)?"&zwj;</U>":""));
 									else printf("<FONT COLOR='#0000FF'>(empty)</FONT>");
 									}
 								else printf("<FONT COLOR='#0000FF'>(undefined)</FONT>");
@@ -2360,13 +2360,13 @@ void display_command_expansion(void){
 					if (arg_count[i]==0){
 						printf("<TR CLASS='%s'><TD CLASS='%s' ALIGN='right'><FONT COLOR='#FF0000'>unused:</FONT></TD>\n",bg_class,bg_class);
 						printf("<TD CLASS='%s'>$ARG%u$=<FONT COLOR='%s'>%s%s%s</FONT></TD></TR>\n",bg_class,i,hash_color(i),
-							((lead_space[i]>0)||(trail_space[i]>0)?"<U>&zwj;":""),html_encode(command_args[i],FALSE),
+							((lead_space[i]>0)||(trail_space[i]>0)?"<U>&zwj;":""),escape_string(command_args[i]),
 							((lead_space[i]>0)||(trail_space[i]>0)?"&zwj;</U>":""));
 						}
 					else if (arg_count[i]>1){
 						printf("<TR CLASS='%s'><TD CLASS='%s' ALIGN='right'>used %u x:</TD>\n",bg_class,bg_class,i);
 						printf("<TD CLASS='%s'>$ARG%u$=<FONT COLOR='%s'>%s%s%s</FONT></TD></TR>\n",bg_class,i,hash_color(i),
-							((lead_space[i]>0)||(trail_space[i]>0)?"<U>&zwj;":""),html_encode(command_args[i],FALSE),
+							((lead_space[i]>0)||(trail_space[i]>0)?"<U>&zwj;":""),escape_string(command_args[i]),
 							((lead_space[i]>0)||(trail_space[i]>0)?"&zwj;</U>":""));
 						}
 					if ((lead_space[i]>0)||(trail_space[i]>0)){
@@ -2407,13 +2407,13 @@ void display_command_expansion(void){
 			if (!arg_count[0]){
 				printf("<TR CLASS='dataOdd'><TD CLASS='dataOdd' ALIGN='right'><FONT\n");
 				printf("COLOR='#FF0000'>Error:</FONT></TD><TD CLASS='dataOdd'><FONT COLOR='#FF0000'>No\n");
-				printf("command &quot;%s&quot; found</FONT></TD></TR>\n",html_encode(command_args[0],FALSE));
+				printf("command &quot;%s&quot; found</FONT></TD></TR>\n",escape_string(command_args[0]));
 				}
 		}
 
 	printf("<TR CLASS='dataEven'><TD CLASS='dataEven'>To expand:</TD><TD CLASS='dataEven'><FORM\n");
 	printf("METHOD='GET' ACTION='%s'><INPUT TYPE='HIDDEN' NAME='type' VALUE='command'><INPUT\n",CONFIG_CGI);
-	printf("TYPE='text' NAME='expand' SIZE='100%%' VALUE='%s'>\n",html_encode(to_expand,FALSE));
+	printf("TYPE='text' NAME='expand' SIZE='100%%' VALUE='%s'>\n",escape_string(to_expand));
 	printf("<INPUT TYPE='SUBMIT' VALUE='Go'></FORM></TD></TR>\n");
 
 	printf("</TABLE>\n");
diff --git a/cgi/statusmap.c b/cgi/statusmap.c
index a77352d..7f8bc3f 100644
--- a/cgi/statusmap.c
+++ b/cgi/statusmap.c
@@ -2404,7 +2404,7 @@ void print_layer_url(int get_method){
 
 	for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){
 		if(get_method==TRUE)
-			printf("&layer=%s",temp_layer->layer_name);
+			printf("&layer=%s",escape_string(temp_layer->layer_name));
 		else
 			printf("<input type='hidden' name='layer' value='%s'>\n",escape_string(temp_layer->layer_name));
 	        }
-- 
1.7.1.1

