JustAppSec
Back to news

Starlet 0.31 misreads chunked encoding, enabling request smuggling

2 min readPublished 03 May 2026Source: oss-security (CPAN Security Group)

TL;DR - Starlet through 0.31 picks Content-Length over Transfer-Encoding: chunked when both headers appear in the same request. RFC 7230 section 3.3.3 says the opposite. Behind a reverse proxy that follows the spec, that disagreement is a request smuggling primitive.

What happened

Starlet is a Perl PSGI/Plack HTTP server for running Perl web applications. CVE-2026-40561 is a header precedence bug classified as CWE-444 (Inconsistent Interpretation of HTTP Requests).

When a request carries both Content-Length and Transfer-Encoding: chunked, Starlet honours Content-Length. RFC 7230 section 3.3.3 is unambiguous: if Transfer-Encoding is present, it takes precedence and Content-Length must be ignored.

That gap is the attack surface. A front-end reverse proxy following the spec parses one request boundary; Starlet parses another. The desync lets an attacker smuggle a partial second request through the proxy - effectively prepending attacker-controlled data to the next legitimate request on the same connection.

ItemDetail
Affected componentStarlet (Perl)
Affected versionsthrough 0.31
Vulnerability classHTTP Request Smuggling (header precedence)
CWECWE-444

This bug class recurs because HTTP parsing is underspecified in practice. Any time an intermediary and a backend implement slightly different rules for ambiguous requests, smuggling becomes possible. Next.js, Gunicorn, and various Java containers have all shipped variants of the same issue.

Who is impacted

  • Services running Starlet at versions through 0.31.
  • Deployments sitting behind a front-end reverse proxy - nginx, HAProxy, Caddy, a CDN edge - where the proxy and Starlet can disagree on request boundaries.
  • Internet-facing endpoints that accept untrusted client traffic through the proxy layer. Internal-only services with no HTTP intermediary have no attack path.

What to do now

  • Apply the fix. The CPAN Security Group advisory is clear:

    "Migrate to Starman 0.4018 or later which has fixed this issue or apply the patch."

  • Inventory your Perl services. Check deployed artifacts and container images for any path still running on Starlet. Version pinning in cpanfile or Makefile.PL is the fastest place to confirm what you're actually running.
  • If you operate a reverse proxy in front of Perl app servers, check whether it can be configured to reject or normalise requests that carry both Content-Length and Transfer-Encoding headers. That removes the attack shape at the edge, independent of backend patching.
  • If you suspect prior exposure, query edge and application logs for requests that include both headers. Look for downstream anomalies consistent with request desync: unexpected 4xx spikes, mismatched request counts, or unusual keep-alive behaviour.

Related


Content is AI-assisted and reviewed by our team, but issues may be missed and best practices evolve rapidly, send corrections to [email protected]. Always consult official documentation and validate key implementation decisions before making design or security choices.

Need help?Get in touch.