Apacheのあまり知られていない仕様

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

in englishin japanese
私自身、最近知ったのですが、以下の様なファイル名がサーバ上にあった場合、PHPファイルとして実行されます。

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

これはApacheのmod_mime.cの「正しい仕様」なのですが、この仕様を知らなかったが故にできてしまっているファイルアップロード脆弱性もあり得ます。

もし、アップロードされてDocumentRoot下に置かれるファイル名が、自動連番などでなく、元のファイル名を活かした形のものとなった場合、ファイル名最後の.phpだけを禁止しても、意味がなくなります。

XOOPSにそういうモジュールがあるかどうか私は知りませんが、念のため、最新版のProtector (2.54) では、ドット(.)が2つ以上あるファイルをアップロードしようとした場合は、強制終了する仕様にしました。

もし、ファイルアップロードで、真っ白画面になってしまった場合、Protectorの管理画面を見てください。理由が書いてあるはずです。

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