View Issue Details

IDProjectCategoryView StatusLast Update
0002126libmicrohttpdpostprocessorpublic2012-01-31 17:52
Reporterwoof Assigned ToChristian Grothoff  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version0.9.18 
Summary0002126: Per RFC2046, libmicrohttpd needs to handle garbage prior to first multipart boundary
DescriptionRFC2046 includes the following in 5.1.1 NOTE TO IMPLEMENTORS:

There appears to be room for additional information prior to the first boundary delimiter line and following the final boundary delimiter line. These areas should generally be left blank, and implementations must ignore anything that appears before the first boundary delimiter line or after the last one.

If anything precedes the first boundary delimiter, libmicrohttpd rejects the entire post.
Steps To ReproduceSend a multipart post with extra information before the first boundary, such as:

POST /somedata HTTP/1.1

Accept-Encoding: gzip,deflate

Content-Type: multipart/form-data; boundary=xyzzy

Content-Length: 187


Here is some extra data before the first boundary


--xyzzy

Content-Disposition: form-data; name="username"



barney

--xyzzy

Content-Disposition: form-data; name="password"



fife
Additional InformationI've coded a fix for this (see attached patch) that you can use or modify as you see fit.
TagsNo tags attached.
Attached Files
patch (2,764 bytes)   
--- postprocessor.c.orig	2012-01-30 10:05:44.000000000 -0700
+++ postprocessor.c	2012-01-30 10:06:35.000000000 -0700
@@ -39,6 +39,7 @@ enum PP_State
   PP_Error,
   PP_Done,
   PP_Init,
+  PP_NextBoundary,
 
   /* url encoding-states */
   PP_ProcessValue,
@@ -492,7 +493,8 @@ find_boundary (struct MHD_PostProcessor 
     }
   if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen)))
     {
-      pp->state = PP_Error;
+      if (pp->state != PP_Init)
+        pp->state = PP_Error;
       return MHD_NO;            /* expected boundary */
     }
   /* remove boundary from buffer */
@@ -823,6 +825,25 @@ post_process_multipart (struct MHD_PostP
           pp->state = PP_Error;
           return MHD_NO;
         case PP_Init:
+          /**
+           * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
+           * prior to the first multipart boundary:
+           *
+           * > There appears to be room for additional information prior
+           * > to the first boundary delimiter line and following the
+           * > final boundary delimiter line.  These areas should
+           * > generally be left blank, and implementations must ignore
+           * > anything that appears before the first boundary delimiter
+           * > line or after the last one.
+           */
+          if (MHD_NO == find_boundary (pp,
+                                       pp->boundary,
+                                       pp->blen,
+                                       &ioff,
+                                       PP_ProcessEntryHeaders, PP_Done))
+            ++ioff;
+          break;
+        case PP_NextBoundary:
           if (MHD_NO == find_boundary (pp,
                                        pp->boundary,
                                        pp->blen,
@@ -914,7 +935,7 @@ post_process_multipart (struct MHD_PostP
                                        pp->nlen,
                                        &ioff,
                                        PP_Nested_PerformMarking,
-                                       PP_Init /* or PP_Error? */ ))
+                                       PP_NextBoundary /* or PP_Error? */ ))
             {
               if (pp->state == PP_Error)
                 return MHD_NO;
@@ -955,7 +976,7 @@ post_process_multipart (struct MHD_PostP
                                                    pp->nested_boundary,
                                                    pp->nlen,
                                                    PP_Nested_PerformCleanup,
-                                                   PP_Init))
+                                                   PP_NextBoundary))
             {
               if (pp->state == PP_Error)
                 return MHD_NO;
patch (2,764 bytes)   

Activities

Christian Grothoff

2012-01-30 20:04

manager   ~0005406

Fixed in SVN 19546.

Issue History

Date Modified Username Field Change
2012-01-30 18:25 woof New Issue
2012-01-30 18:25 woof File Added: patch
2012-01-30 19:50 Christian Grothoff Assigned To => Christian Grothoff
2012-01-30 19:50 Christian Grothoff Status new => assigned
2012-01-30 20:04 Christian Grothoff Note Added: 0005406
2012-01-30 20:04 Christian Grothoff Status assigned => resolved
2012-01-30 20:04 Christian Grothoff Resolution open => fixed
2012-01-31 17:52 Christian Grothoff Status resolved => closed
2013-05-06 12:53 Christian Grothoff Category postprocessor => libmicrohttpd postprocessor
2024-01-21 13:24 Christian Grothoff Category libmicrohttpd postprocessor => postprocessor