FastCGI-Archives / fcgi2

FastCGI.com fcgi2 Development Kit fork from http://repo.or.cz/fcgi2.git + last snapshot
Other
216 stars 72 forks source link

Malformed requests when using more than 8192 bytes of parameters #13

Open arnecls opened 5 years ago

arnecls commented 5 years ago

The size of the parameter buffer is set fixed to 8KB, see https://github.com/FastCGI-Archives/fcgi2/blob/856ac8362affcc5e1aaafe587db9a56c89fc4c83/cgi-fcgi/cgi-fcgi.c#L814 Using more then ~8KB of parameters will cause malformed requests.

In our case we were sending around 8184 bytes (according to wireshark):

broken

Here is the output of the same request with slightly less data, which is working:

working

We could not really track it down far into the code, but I never saw the stream buffer size being reset somewhere. But as a second parameter set is sent (see wireshark protocol) it could also be an off-by-one error or similar.

arnecls commented 5 years ago

I sadly cannot send you the dumps, as they contain sensitive information, but I can look things up if you want to.

The error reported by wireshark is sadly not very informative.

[Malformed Packet: FCGI]
    [Expert Info (Error/Malformed): Malformed Packet (Exception occurred)]
        [Malformed Packet (Exception occurred)]
        [Severity level: Error]
        [Group: Malformed]
mcarbonneaux commented 5 years ago

your welcome to send pull request to fix it.

mcarbonneaux commented 5 years ago

you've tryed to change the 8192 size in FCGX_CreateWriter argument to see if simply this size that had been reached or more complex thing ?

mcarbonneaux commented 5 years ago

you've catched the exit status of the cgi-fcgi binary ?

because in the loop after the createwriter they exit hard if fail to putstr:

 for( ; *envp != NULL; envp++) {
        equalPtr = strchr(*envp, '=');
        if(equalPtr  == NULL) {
            exit(1000);
        }
        valueLen = strlen(equalPtr + 1);
        FCGIUtil_BuildNameValueHeader(
                equalPtr - *envp,
                valueLen,
                &headerBuff[0],
                &headerLen);
        if(FCGX_PutStr((char *) &headerBuff[0], headerLen, paramsStream) < 0
                || FCGX_PutStr(*envp, equalPtr - *envp, paramsStream) < 0
                || FCGX_PutStr(equalPtr + 1, valueLen, paramsStream) < 0) {
            exit(FCGX_GetError(paramsStream));
        }
    }