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;
}