On Mon, Sep 29, 2014 at 7:59 AM, Nick Kew <[email protected]> wrote:
> On Sun, 2014-09-28 at 23:10 +0200, Rainer Jung wrote:
>
>> IMHO it is a useful approach. Whan I looked at the CGI topic, I noticed
>> that the safest thing is cleaning up in ap_create_environment(), because
>> you can be sure to get every env var in your hands there, not only the
>> ones coming from headers.
>
> The "shellshock" recipe for mod_taint takes a bit of a kitchen-sink
> approach:
>  - The Request headers
>  - The Request fields that haven't always been fully sanitised
>    and that might try to smuggle something: PATH_INFO and
>    QUERY_STRING (r->args).
>  - subprocess_env

mod_taint uses the header_parser hook to untaint the request
headers/fields, but this is too early for subprocess_env.

As Rainer noticed httpd is probably missing a env_parser hook that
could be called by ap_create_environment(), but still that would not
apply to [fs]cgi (which don't use it).

So maybe rather than defining a hook that would work on the whole char
**env, we could have one working on any key/value pair like :

AP_IMPLEMENT_HOOK_RUN_ALL(int, env_parser,
                          (apr_pool_t *p, const char **key, const char
**value), (p, key, value), OK, DECLINED)

This seems quite costly though...

>
> The point being, that comprehensively covers data coming from
> an HTTP request and that might find its way into a subprocess
> environment!  Unless someone embeds a backdoor in some trojan,
> in which case all bets are off ...
>
>>  Unfortunately that's not an extensible part of
>> code (no hook). Furthermore cleaning the env vars only works for CGI,
>> but not e.g. for FCGI, SCGI proxying etc. Sometimes it would be
>> convenient to sanitize data on e.g. a revproxy and not on every internal
>> web server maybe doing CGI. So I'd say mod_taint is a good compromise
>> between the slightly higher safety of directly sanitizing the env vars
>> and compatibility with current hooks.
>
> You're looking at a WAF there.  mod_taint is but one small part of
> the functionality of a WAF, but just happens to be the part that
> sits between untrusted Request data and a subprocess environment!
> Cleaning up headers and QEURY_STRING/PATH_INFO protects a generic
> backend, anything from local CGI to proxy.
>
>> I haven't looked at your updated code yet (only at the old one that
>> didn't easily allow to untaint all headers),
>
> Indeed, it was only after your first email that I looked at it
> and started thinking harder about whether it in fact did the job!
>
>>  but could it be helpful to
>> allow narrowing down which headers and vars to untaint? Like e.g. with a
>> regexp against the header/var name? Something between listing individual
>> headers und untainting all headers? Or is there no real use case for this?
>
> I don't really see a use case.  HTTP rules allow arbitrary
> headers as extensions and CGI rules translate those by
> formula to environment variables, so we always need some
> kind of catch-all.  But I guess there's nothing to stop
> wildcarding being incorporated into the apr_table_do
> that iterates over request_headers and subprocess_env.
>
>> Some headers have a more complex internal structure. Cookies come to
>> mind. There one might want to untaint using a regexp against the cookie
>> values, not the cookie header value.
>
> What matters is the value passed to the subprocess as
> HTTP_COOKIE.  We're sanitising that, but parsing the
> (sanitised) value(s) is none of our business.
>
> --
> Nick Kew
>

Reply via email to