From 3eb482c25c423e935e91a57ec61d36e12d4be8e1 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: May 15 2007 00:53:33 +0000 Subject: Resolves: #186280 Summary: Close potential security vulnerabilities in CGI code (Comment #30,#31) Description: Added the code to escape html characters --- diff --git a/include/libadminutil/admutil.h b/include/libadminutil/admutil.h index 04a0f65..123f1b9 100644 --- a/include/libadminutil/admutil.h +++ b/include/libadminutil/admutil.h @@ -21,7 +21,7 @@ /* * adminutil.h - prototypes for libadminutil * - * $Id: admutil.h,v 1.6 2007/04/04 19:37:41 rmeggins Exp $ + * $Id: admutil.h,v 1.7 2007/05/15 00:53:33 nhosoi Exp $ */ #ifndef __ADMUTIL_H__ @@ -429,10 +429,14 @@ PR_IMPLEMENT(char) *alert_wrd_wrap(char *str, int width, char *linefeed); /* form_post.c */ PR_IMPLEMENT(char) **get_input_ptr(void); -/* Unescape an encoded form variable. */ +/* Unescape an %-encoded form variable. */ /* form_post.c */ PR_IMPLEMENT(void) form_unescape(char *str); +/* Unescape an %-encoded form variable; escape <, >, &, ", ' */ +/* form_post.c */ +PR_IMPLEMENT(char *) form_unescape_url_escape_html(char *str); + /* Initialize a form "post" using the GET method. Send this fn the QS * directly.*/ /* form_post.c */ diff --git a/lib/libadminutil/form_post.c b/lib/libadminutil/form_post.c index c848819..3c5d9b3 100644 --- a/lib/libadminutil/form_post.c +++ b/lib/libadminutil/form_post.c @@ -86,6 +86,96 @@ form_unescape(char *str) str[y] = '\0'; } +/* + * form_unescape_url_escape_html -- 1) unescape escaped chars in URL; + * 2) escape unsecure chars for scripts + * 1) "%##" is converted to one character which value is ##; so is '+' to ' ' + * 2) <, >, &, ", ' are escaped with "&XXX;" format + */ +PR_IMPLEMENT(char *) +form_unescape_url_escape_html(char *str) +{ + register int x = 0, y = 0; + int l = 0; + char digit; + char *rstr = NULL; + + if (NULL == str) { + return NULL; + } + + /* to allocate enough space for the escaped characters */ + for (x = 0, y = 0; str[x] != '\0'; x++) { + if (('<' == str[x]) || ('>' == str[x])) + y += 3; + else if (('&' == str[x]) || ('\'' == str[x])) + y += 4; + else if ('"' == str[x]) + y += 5; + } + + if (0 < y) { + rstr = (char *)PR_Malloc(x + y + 1); + } else { + rstr = PL_strdup(str); + } + l = x; /* length of str */ + + if (NULL == rstr) { + if (admutil_i18nResource) { + char buf[BUFSIZ]; + rpt_err(MEMORY_ERROR, + NULL, + (char*)res_getstring(admutil_i18nResource, + DBT_formPost_PostStdinErr, + admutil_acceptLang, buf, sizeof(buf), + NULL), NULL); + } else { + rpt_err(MEMORY_ERROR, + NULL, + "Could not allocate enough memory to read in the POST parameters.", + NULL); + } + return NULL; + } + + for (x = 0, y = 0; x < l; x++, y++) { + if (('%' == str[x]) && (x < (l - 2))) { + ++x; + digit = (str[x] >= 'A' ? + ((str[x] & 0xdf) - 'A') + 10 : (str[x] - '0')); + digit *= 16; + + ++x; + digit += (str[x] >= 'A' ? + ((str[x] & 0xdf) - 'A') + 10 : (str[x] - '0')); + + rstr[y] = digit; + } else if (str[x] == '+') { + rstr[y] = ' '; + } else if ('<' == str[x]) { + memcpy(&rstr[y], "<", 4); + y += 3; + } else if ('<' == str[x]) { + memcpy(&rstr[y], ">", 4); + y += 3; + } else if ('&' == str[x]) { + memcpy(&rstr[y], "&", 5); + y += 4; + } else if ('"' == str[x]) { + memcpy(&rstr[y], """, 6); + y += 5; + } else if ('\'' == str[x]) { + memcpy(&rstr[y], "'", 5); + y += 4; + } else { + rstr[y] = str[x]; + } + } + rstr[y] = '\0'; + return rstr; +} + PR_IMPLEMENT(void) post_begin(FILE *in) { @@ -201,49 +291,22 @@ string_to_vec(char *in) return(ans); } - if (!(ans[x]=PL_strdup(tmp))) { - if (admutil_i18nResource) { - rpt_err(MEMORY_ERROR, - NULL, - (char*)res_getstring(admutil_i18nResource, - DBT_formPost_PostStdinErr, - admutil_acceptLang, buf, sizeof(buf), NULL), - NULL); - } - else { - rpt_err(MEMORY_ERROR, - NULL, - "Could not allocate enough memory to read in the POST parameters.", - NULL); - } - return ans; - } - - form_unescape(ans[x++]); + if (!(ans[x++] = form_unescape_url_escape_html(tmp))) { + /* could not allocate enough memory */ + PR_Free(in); + return ans; + } while((tmp = strtok(NULL, "&"))) { - if (!strchr(tmp, '=')) { - PR_Free(in); - return ans; - } - if (!(ans[x] = PL_strdup(tmp))) { - if (admutil_i18nResource) { - rpt_err(MEMORY_ERROR, - NULL, - (char*)res_getstring(admutil_i18nResource, - DBT_formPost_PostStdinErr, - admutil_acceptLang, buf, sizeof(buf), NULL), - NULL); - } - else { - rpt_err(MEMORY_ERROR, - NULL, - "Could not allocate enough memory to read in the POST parameters.", - NULL); - } + if (!strchr(tmp, '=')) { + PR_Free(in); + return ans; + } + if (!(ans[x++] = form_unescape_url_escape_html(tmp))) { + /* could not allocate enough memory */ + PR_Free(in); return ans; } - form_unescape(ans[x++]); } PR_Free(in);