[icinga-checkins] icinga.org: icinga-core/rbartels/cgi-current: Limited the amount of chi vars excepted by cgis #1644

git at icinga.org git at icinga.org
Thu Jun 16 22:37:36 CEST 2011


Module: icinga-core
Branch: rbartels/cgi-current
Commit: a9730bfdd7f92dc581cf621e66757a7fd7a24438
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=a9730bfdd7f92dc581cf621e66757a7fd7a24438

Author: Ricardo Bartels <ricardo at bitchbrothers.com>
Date:   Thu Jun 16 22:37:01 2011 +0200

Limited the amount of chi vars excepted by cgis #1644

refs: #1644

* Limited to 1000 Pairs of "var=value"
* added const to cgiutils.h "MAX_CGI_INPUT_PAIRS"

Tested with 10000 and it was still working.

---

 cgi/cmd.c          |    2 +-
 cgi/getcgi.c       |   76 +++++++++++++++++++++++++++------------------------
 cgi/status.c       |    3 +-
 include/cgiutils.h |    1 +
 4 files changed, 44 insertions(+), 38 deletions(-)

diff --git a/cgi/cmd.c b/cgi/cmd.c
index 4fd0174..001e3d5 100644
--- a/cgi/cmd.c
+++ b/cgi/cmd.c
@@ -71,7 +71,7 @@ extern comment *comment_list;
  @{**/
 #define MAX_AUTHOR_LENGTH		64
 #define MAX_COMMENT_LENGTH		1024
-#define NUMBER_OF_STRUCTS		500		/**< Set a limit of 500 structs, which is around 125 checks total */
+#define NUMBER_OF_STRUCTS		((MAX_CGI_INPUT_PAIRS*2)+100)		/**< Depends on amount of MAX_CGI_INPUT_PAIRS */
 /** @}*/
 
 /** @name ELEMET TEMPLATE TYPES
diff --git a/cgi/getcgi.c b/cgi/getcgi.c
index 061a3a2..c3f406b 100644
--- a/cgi/getcgi.c
+++ b/cgi/getcgi.c
@@ -24,6 +24,7 @@
 
 #include "../include/config.h"
 #include "../include/getcgi.h"
+#include "../include/cgiutils.h"
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -37,6 +38,17 @@ void sanitize_cgi_input(char **cgivars){
 	int x,y,i;
 	int keep;
 
+	/* Added by Ricardo B. 2011-06-16
+	   Somehow on POST the plus gets turned into HEX so we have to convert it back to blank after all parsing is done.
+	*/
+	for(strptr=cgivars[i=0];strptr!=NULL;strptr=cgivars[++i]){
+
+		for(x=0,y=0;strptr[x]!='\x0';x++){
+			if(strptr[x]=='+')
+				strptr[x]=' ';
+		}
+	}
+
 	/* don't strip for now... */
 	return;
 
@@ -55,13 +67,13 @@ void sanitize_cgi_input(char **cgivars){
 #endif
 			if(keep==1)
 				strptr[y++]=strptr[x];
-		        }
+		}
 
 		strptr[y]='\x0';
-	        }
+	}
 
 	return;
-        }
+}
 
 
 /* convert encoded hex string (2 characters representing an 8-bit number) to its ASCII char equivalent */
@@ -93,7 +105,7 @@ unsigned char hex_to_char(char *input){
 	outchar=(unsigned char)outint;
 
 	return outchar;
-        }
+}
 
 
 
@@ -113,14 +125,13 @@ void unescape_cgi_input(char *input){
 		else if(input[x]=='%'){
 			input[y]=hex_to_char(&input[x+1]);
 			x+=2;
-		        }
-		else
+		}else
 			input[y]=input[x];
-	        }
+	}
 	input[y]='\x0';
 
 	return;
-        }
+}
 
 
 
@@ -156,12 +167,11 @@ char **getcgivars(void){
 			if(cgiinput==NULL){
 				printf("getcgivars(): Could not allocate memory for CGI input.\n");
 				exit(1);
-			        }
+			}
 			cgiinput[0]='\x0';
-		        }
-		else
+		}else
 			cgiinput=strdup(getenv("QUERY_STRING"));
-	        }
+	}
 
 	else if(!strcmp(request_method,"POST") || !strcmp(request_method,"PUT")){
 
@@ -175,7 +185,7 @@ char **getcgivars(void){
 		if(strlen(content_type) && strncasecmp(content_type,"application/x-www-form-urlencoded",33)){
 			printf("getcgivars(): Unsupported Content-Type.\n");
 			exit(1);
-		        }
+		}
 
 		content_length_string=getenv("CONTENT_LENGTH");
 		if(content_length_string==NULL)
@@ -184,24 +194,23 @@ char **getcgivars(void){
 		if(!(content_length=atoi(content_length_string))){
 			printf("getcgivars(): No Content-Length was sent with the POST request.\n") ;
 			exit(1);
-		        }
+		}
 		/* suspicious content length */
 		if((content_length<0) || (content_length>=INT_MAX-1)){
 			printf("getcgivars(): Suspicious Content-Length was sent with the POST request.\n");
 			exit(1);
-			}
+		}
 
 		if(!(cgiinput=(char *)malloc(content_length+1))){
 			printf("getcgivars(): Could not allocate memory for CGI input.\n");
 			exit(1);
-		        }
+		}
 		if(!fread(cgiinput,content_length,1,stdin)){
 			printf("getcgivars(): Could not read input from STDIN.\n");
 			exit(1);
-		        }
+		}
 		cgiinput[content_length]='\0';
-	        }
-	else{
+	}else{
 
 		printf("getcgivars(): Unsupported REQUEST_METHOD -> '%s'\n",request_method);
 		printf("\n");
@@ -217,13 +226,7 @@ char **getcgivars(void){
 		printf("\n");
 
 		exit(1);
-	        }
-
-	/* change all plus signs back to spaces */
-	for(i=0;cgiinput[i];i++){
-		if(cgiinput[i]=='+')
-			cgiinput[i]=' ';
-	        }
+	}
 
 	/* first, split on ampersands (&) to extract the name-value pairs into pairlist */
 	/* allocate memory for 256 name-value pairs at a time, increasing by same
@@ -232,20 +235,22 @@ char **getcgivars(void){
 	if(pairlist==NULL){
 		printf("getcgivars(): Could not allocate memory for name-value pairlist.\n");
 		exit(1);
-	        }
+	}
 	paircount=0;
 	nvpair=strtok(cgiinput,"&");
 	while(nvpair){
 		pairlist[paircount++]=strdup(nvpair);
+		if(paircount>MAX_CGI_INPUT_PAIRS)
+			break;
 		if(!(paircount%256)){
 			pairlist=(char **)realloc(pairlist,(paircount+256)*sizeof(char **));
 			if(pairlist==NULL){
 				printf("getcgivars(): Could not re-allocate memory for name-value pairlist.\n");
 				exit(1);
-			        }
-		        }
+			}
+		}
 		nvpair=strtok(NULL,"&");
-	        }
+	}
 
 	/* terminate the list */
 	pairlist[paircount]='\x0';
@@ -255,20 +260,19 @@ char **getcgivars(void){
 	if(cgivars==NULL){
 		printf("getcgivars(): Could not allocate memory for name-value list.\n");
 		exit(1);
-	        }
+	}
 	for(i=0;i<paircount;i++){
 
 		/* get the variable name preceding the equal (=) sign */
 		if((eqpos=strchr(pairlist[i],'='))!=NULL){
 			*eqpos='\0';
 			unescape_cgi_input(cgivars[i*2+1]=strdup(eqpos+1));
-		        }
-		else
+		}else
 			unescape_cgi_input(cgivars[i*2+1]=strdup(""));
 
 		/* get the variable value (or name/value of there was no real "pair" in the first place) */
 		unescape_cgi_input(cgivars[i*2]=strdup(pairlist[i]));
-	        }
+	}
 
 	/* terminate the name-value list */
 	cgivars[paircount*2]='\x0';
@@ -284,7 +288,7 @@ char **getcgivars(void){
 
 	/* return the list of name-value strings */
 	return cgivars;
-        }
+}
 
 
 
@@ -296,4 +300,4 @@ void free_cgivars(char **cgivars){
 		free(cgivars[x]);
 
 	return;
-        }
+}
diff --git a/cgi/status.c b/cgi/status.c
index d99a59c..f1e9436 100644
--- a/cgi/status.c
+++ b/cgi/status.c
@@ -1815,7 +1815,8 @@ void show_service_detail(void){
 
 			/* Checkbox for service(s) */
 			if (is_authorized_for_read_only(&current_authdata)==FALSE)
-				printf("<TD CLASS='status%s' nowrap align='center'><input onclick=\"isValidForSubmit('tableform');\" type='checkbox' name='hostservice' value='%s^%s'></TD>\n",status_bg_class,url_encode(temp_status->host_name),temp_status->svc_description);
+				printf("<TD CLASS='status%s' nowrap align='center'><input onclick=\"isValidForSubmit('tableform');\" type='checkbox' name='hostservice' value='%s^",status_bg_class,url_encode(temp_status->host_name));
+				printf("%s'></TD>\n",url_encode(temp_status->svc_description));
 
 			if(enable_splunk_integration==TRUE)
 				display_splunk_service_url(temp_service);
diff --git a/include/cgiutils.h b/include/cgiutils.h
index fc00e6b..faaa85f 100644
--- a/include/cgiutils.h
+++ b/include/cgiutils.h
@@ -521,6 +521,7 @@ extern "C" {
 
 #define MAX_MESSAGE_BUFFER              4096
 
+#define MAX_CGI_INPUT_PAIRS		1000		/**< max number of cgi vars excepted */
 
 /************************** DISPLAY STYLE  ********************************/
 





More information about the icinga-checkins mailing list