Apache's un-well-known behavior

Date 2005-12-08 13:07:09 | Category: PHP

in englishin japanese
Do you know these files can be parsed as PHP file?

foo.php.en
foo.php.orig.test

This is a normal behavior of apache's mod_mime.c

If a script stores an uploaded file under DocumentRoot and its name will be generated from its original file name, it is danger enough.
(Though I don't know such modules for XOOPS...)

Even if he disallow *.php, attacker can upload *.php.hehehe and exec the file.

The latest version of Protector (2.54) scans multiple dot(.) inside $_FILE[]['name'].
If a doubtful file name is found, Protector will stop XOOPS immediately.

src/modules/standard/mod_mime.c
inside function find_ct(request_rec *r):


    /* Parse filename extensions, which can be in any order */
    while ((ext = ap_getword(r->pool, &fn, '.')) && *ext) {
        int found = 0;

        /* Check for Content-Type */
        if ((type = ap_table_get(conf->forced_types, ext))
            || (type = ap_table_get(hash_buckets[hash(*ext)], ext))) {
            r->content_type = type;
            found = 1;
        }

        /* Add charset to Content-Type */
        if ((type = ap_table_get(conf->charset_types, ext))) {
            charset = type;
            found = 1;
        }

        /* Check for Content-Language */
        if ((type = ap_table_get(conf->language_types, ext))) {
            const char **new;

            r->content_language = type;         /* back compat. only */
            if (!r->content_languages)
                r->content_languages = ap_make_array(r->pool, 2, sizeof(char *));
            new = (const char **) ap_push_array(r->content_languages);
            *new = type;
            found = 1;
        }

        /* Check for Content-Encoding */
        if ((type = ap_table_get(conf->encoding_types, ext))) {
            if (!r->content_encoding)
                r->content_encoding = type;
            else
                r->content_encoding = ap_pstrcat(r->pool, r->content_encoding,
                                              ", ", type, NULL);
            found = 1;
        }

        /* Check for a special handler, but not for proxy request */
        if ((type = ap_table_get(conf->handlers, ext))
            && r->proxyreq == NOT_PROXY) {
            r->handler = type;
            found = 1;
        }

        if (found)
            found_metadata = 1;
        else
            *((const char **) ap_push_array(exception_list)) = ext;
    }




You can read more news at PEAK XOOPS.
http://xoops.peak.ne.jp

The URL for this story is:
http://xoops.peak.ne.jp/md/news/index.php?page=article&storyid=76