
सुरक्षा सलाह: अनप्रमाणित NULL पॉइंटर डीरेफरेंस सर्वर को क्रैश कर देता है (TinyWeb)
निर्धारित CVE ID: CVE-2026-67184
जब TinyWeb किसी अनुरोध पंक्ति (request line) को पार्स करने में विफल रहता है, तो वह एक त्रुटि लौटाता है लेकिन अनुरोध के URL पॉइंटर को NULL पर सेट छोड़ देता है। कॉलर त्रुटि को अनदेखा करता है और अनुरोध को प्रतिक्रिया निर्माता (response builder) को भेज देता है, जो उस NULL पॉइंटर को डीरेफरेंस करता है और वर्कर को क्रैश कर देता है। कुछ ही गलत प्रारूप वाले (malformed) अनुरोध पूरे सर्वर को डाउन कर देते हैं, और यह पुनर्प्राप्त (recover) नहीं हो पाता।
TnyWeb/0.0.8e48f15d (2018-11-20), जहाँ यह पार्सर और प्रतिक्रिया पथ (response path) पेश किए गए थे, से लेकर a381da2 (2023-11-22, master पर नवीनतम) तक।CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:Nएक अनधिकृत (unauthenticated) दूरस्थ हमलावर जो सर्वर के सुनने वाले (listening) TCP पोर्ट (शिप की गई कॉन्फ़िगरेशन में 9090) तक पहुँच सकता है। किसी क्रेडेंशियल या उपयोगकर्ता इंटरैक्शन की आवश्यकता नहीं है।
HttpParser::execute() URL ऑब्जेक्ट को केवल अनुरोध पंक्ति के सफलतापूर्वक पार्स होने के बाद आवंटित (allocate) करता है। गलत प्रारूप वाला HTTP संस्करण संस्करण जाँच को विफल कर देता है और त्रुटि लेबल पर कूद जाता है, जो आवंटन चलने से पहले -1 लौटाता है:
// src/tiny_http/http_parser.cc:1401 (the "H" of "HTTP" is expected here)
checkOrGoError((ch == 'H')); // false -> goto error
// src/tiny_http/http_parser.cc:1692 (skipped by the goto above)
request->url = new Url;
// src/tiny_http/http_parser.cc:1750-1753
error:
LOG(Debug) << "http request content is invalid\n";
return -1;
HttpRequest को std::make_shared<HttpRequest>() के साथ बनाया जाता है, जो इसे वैल्यू-इनिशियलाइज़ करता है, इसलिए आवंटन छोड़े जाने पर url NULL ही रहता है।
WebProtocol::dataReceived() रिटर्न वैल्यू दर्ज करता है लेकिन फिर भी buildResponse() को कॉल करता है:
// src/tiny_http/http_protocol.cc:57-61
valid = m_nParser.execute(data.c_str(), begin, data.size(), m_pRequest.get());
valid_requ = (valid == -1) ? false : true;
// src/tiny_http/http_protocol.cc:75
m_nResponser.buildResponse(m_pRequest.get(), valid_requ, m_pResponse.get());
buildResponse() को valid_requ == false प्राप्त होता है लेकिन यह इसे कभी जाँचता नहीं है, और NULL URL पॉइंटर को डीरेफरेंस करता है:
// src/tiny_http/http_responser.cc:66
Url* url = req->url; // NULL
// src/tiny_http/http_responser.cc:83
if (url->field_set & (1 << HTTP_UF_PATH)) { // SIGSEGV
वर्कर प्रोसेस इस एक्सेस पर क्रैश हो जाता है। इसे सेवा देने वाली स्थिति (serving state) में पुनः प्रारंभ नहीं किया जाता, इसलिए एक बार वर्कर समाप्त हो जाने पर सर्वर जवाब देना बंद कर देता है।
शिप की गई कॉन्फ़िगरेशन के साथ सर्वर प्रारंभ करें (पोर्ट 9090 पर सुनना)।
पुष्टि करें कि यह एक सामान्य अनुरोध का उत्तर देता है:
curl http://TARGET:9090/
XTTP/1.1 संस्करण जाँच में विफल हो जाता है:printf 'GET / XTTP/1.1\r\n\r\n' | nc TARGET 9090
एक वर्कर से जुड़ा डीबगर NULL डीरेफरेंस पर क्रैश दिखाता है:
#0 HttpBuilder::buildResponse (valid_requ=false) at src/tiny_http/http_responser.cc:83
#1 WebProtocol::dataReceived (data="GET / XTTP/1.1\r\n...") at src/tiny_http/http_protocol.cc:75
एक अनधिकृत हमलावर कुछ छोटे अनुरोधों से सर्वर वर्कर को क्रैश कर सकता है और उन्हें बार-बार भेजकर सेवा को ऑफलाइन रख सकता है। यह एक सेवा से वंचित करने वाला हमला (denial of service) है।
dataReceived() में, जब valid_requ false हो, तो buildResponse() को कॉल करने के बजाय एक त्रुटि प्रतिक्रिया बनाकर लौटें। buildResponse() में, उपयोग करने से पहले req->url को NULL के लिए जाँचें। पार्स के विफल होने से पहले URL ऑब्जेक्ट को आवंटित करना भी इस खामी को बंद कर देगा।