An attacker sending a malformed HTTP POST request over LAN to a TP-Link Smart camera device can trigger the vulnerability described here.

This report describes a heap buffer overflow, which leads to remote code execution.

The vulnerability we are disclosing in this advisory affected a wide range of TP-Link devices, including TAPO Smart Cameras. A TP-Link Security Advisory released in April 2026 contains this vulnerability as CVE-2026-34118.

Vulnerability Details

In the HTTP Server implementation of TAPO devices, the http_recv_block function (within the main binary) is used to retrieve HTTP packets from the network into memory. It accepts a pointer to a buffer and the size of said buffer as parameters, and copies the HTTP content into this buffer. This function is called on multiple occasions in the HTTP parser subsystem.

int http_recv_block(httpd_context* context, void* buf, size_t buflen) {
  int err;
  
  if (context->is_https == 1) {
    // ...
    while (err = tpssl_read(context->ssl_handle, buf, buflen), err < 1) {
      // Error handling
    }
  } else {
    err = recv(context->sockfd, buf, buflen, 0);
    // Error handling
  }
  
  return err;
}

One case is in http_read_content. This function is responsible for handling the first bytes of the content. Because the HTTP protocol dictates that the headers are in a line-by-line format, the full length of the headers cannot be known in advance. Thus, due to the required buffering, this part of the parser might have read into the content, and this case must be handled appropriately.

The content is originally stored in the context->main_buffer (NOTE: the symbol names are not public, so these labels might differ from the names present in the original source) of 0x1000 bytes, and the region between context->buffered_data_start and context->buffered_data_end are the bytes that were already received, but not yet parsed.

Also, the expected content length is already communicated in HTTP, so the application must process exactly content_len bytes. If this main_buffer is too small to contain both the headers and the content, a new buffer is allocated (content_buf/content_buffer). Both main_buffer and content_buf size are defined by a pointer to the end of the buffer (main_buffer_end/content_buffer_end).

content_len = context->content_len;
if (content_len == 0) {
  context->content_parse_err = 1;
  return 0;
}
        /* Check if we fit inside the rest of the bytes */
begin = context->buffered_data_start;
context->content_parse_err = 0;
if (content_len < (int)context->main_buffer_end - (int)begin) { // [1]
new_currptr = context->buffered_data_end;
  // ...
  // (set context fields)
}
else {
        /* Allocate new memory, because we do not fit into the range
           buffered_data_start ... end of the buffer */
  begin = (char *)malloc(content_len + 1); // [2]
  new_currptr = begin + ...;
  // ...
  // (set context fields)
}
remaining_to_read = begin + (content_len - (int)new_currptr);
if ((int)remaining_to_read > 0) {
  bytes_read = http_recv_block(context,new_currptr,0x1000); // [3]
  ...
}

As we can see in a function that might be called http_read_content, which is used for receiving the content (body) part of HTTP requests, if the length of the HTTP packet (as per the Content-Length header field) is larger than the buffer stored in the context, it will be reallocated with the needed size. However, the following http_recv_block() call will always put 0x1000 as the size to be received. This is an issue if the length of the unused bytes in the buffer is less than 0x1000 bytes and more bytes are sent by the other party, i.e. the Content-Length field is set to something smaller, which is not prevented by the code.

Even if the reallocation does not happen, we can trigger the vulnerability by sending two separate packets. The first packet fills the buffer (which by default has a size of 0x1000) up to an offset, then the second packet will be placed after that offset. If the second offset is larger than the remaining size, the heap buffer can be overflown.

Affected Devices

  • verified: TAPO C520WS
  • potentially: TP-Link smart devices using the TAPO architecture

Timeline

  • 2025.12.12. Vulnerability reported to TP-Link PSIRT by email.
  • 2026.02.04. TP-Link acknowledges the report and asks for extended PoC.
  • 2026.02.11. TASZK responds with sending extended copy-paste PoCs and highlights that sufficient reproduction information was already contained in the original submission.
  • 2026.03.04. TP-Link confirms vulnerability and asks for time extension. TP-Link also provides erroneous analysis for several other reported vulnerabilities.
  • 2026.03.04. TASZK provides update explaining the errors in TP-Link’s assessment regarding other reported vulnerabilities, describing which CVE assignment and advisory detail assessments are incorrect.
  • 2026.03.05. TP-Link again asks for a 3 week extension, does not confirm any TASZK analysis.
  • 2026.03.06. TASZK confirms that a 3 week extension will be granted for vulnerabilities where a CVE assignment and/or Advisory correction will happen.
  • 2026.03.20. TP-Link communicates that this vulnerability (along with some reported at the time) have been fixed and wishes TASZK to provide a black box analysis of a new firmware image. TP-Link does not confirm which submitted vulnerabilities will receive a CVE and/or Advisory correction but ask for another arbitrary extension for only 1 vulnerability.
  • 2026.03.23. TASZK confirms that the 3 week extension will be granted if the list of vulnerabilities that are receiving a CVE and/or Advisory correction will be shared, otherwise no other extension will be granted.
  • 2026.03.26-04.01. TP-Link attempts to get in touch via several non-official channels, including an attempt to show up at our offices in person uninvited. TP-Link requests additional delay for different vulnerabilities.
  • 2026.04.02. End date of original 90 day + 3 week embargo. TASZK highlights that the PSIRT keeps sending plaintext emails with sensitive vulnerability information, points out that non-PSIRT channels are considered out-of-bounds for coordinated disclosure and confirms that embargo windows will not be extended further. TASZK volunteers a 24h notice to TP-Link for advisory release.
  • 2026.04.02. TP-Link releases advisory for the vulnerability: https://www.tp-link.com/us/support/faq/5047/
  • 2026.04.06. TASZK communicates notice of release to TP-Link.
  • 2026.04.28. Advisory released.