[Fedora-directory-commits] adminutil/lib/libadminutil form_post.c, 1.5, 1.6

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Tue May 15 00:53:35 UTC 2007


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);




More information about the Fedora-directory-commits mailing list