Author: nhosoi
Update of /cvs/dirsec/adminutil/lib/libadminutil
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26162/lib/libadminutil
Modified Files:
form_post.c
Log Message:
Resolves: #186280
Summary: Close potential security vulnerabilities in CGI code (Comment #30,#31)
Description: Added the code to escape html characters
Index: form_post.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/form_post.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- form_post.c 8 May 2007 19:13:25 -0000 1.5
+++ form_post.c 15 May 2007 00:53:33 -0000 1.6
@@ -86,6 +86,96 @@
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 @@
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);