CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-60876

Breaking the Box: Deep Dive into BusyBox wget CRLF Injection

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 15, 2026·7 min read·155 visits

Executive Summary (TL;DR)

BusyBox `wget` (<= 1.37.0) doesn't strip control characters from URLs. If an attacker controls the URL passed to `wget`, they can inject `\r\n` sequences to manipulate the HTTP request headers. This allows for HTTP Request Splitting, potentially poisoning caches or injecting malicious headers like `Authorization` or `X-Forwarded-For`.

BusyBox, the undisputed 'Swiss Army Knife of Embedded Linux,' has a jagged edge in its `wget` implementation. Through version 1.37.0, the utility fails to properly sanitize URL inputs, specifically allowing Carriage Return (CR) and Line Feed (LF) characters to pass through to the raw HTTP request line. This vulnerability, discovered by researcher Takeuchi Yuma, opens the door to HTTP Request Splitting and CRLF Injection. In environments where `wget` processes untrusted URLs—such as webhooks, CI/CD pipelines, or containerized automated tasks—attackers can inject arbitrary HTTP headers, potentially leading to cache poisoning, request smuggling, or internal security control bypasses.

The Hook: The Swiss Army Knife with a Loose Blade

If you have ever touched a router, an IoT toaster, or a minimal Docker container, you have used BusyBox. It is the minimalist's dream: a single binary that masquerades as hundreds of standard Unix utilities. It is efficient, it is everywhere, and it is usually running as root in places you cannot easily patch. One of its most critical applets is wget, a tool used universally to fetch files, health-check services, and download initialization scripts.

The problem with minimalism is that sometimes safety checks are viewed as 'bloat.' In the world of high-level languages like Python or Go, HTTP libraries protect you from yourself. They refuse to put a newline character in a header because they know it violates the protocol. BusyBox, however, is written in C. It talks to the network using raw sockets and optimism. It assumes that if you give it a URL, that URL is a valid string of characters that won't break the HTTP protocol.

CVE-2025-60876 serves as a harsh reminder that the HTTP protocol is, at its core, just text sent over a wire. If you can control that text, you control the conversation. By failing to scrub 'control characters'—specifically the Carriage Return (\r, 0x0D) and Line Feed (\n, 0x0A)—BusyBox wget allows an attacker to break out of the URL path and start writing their own HTTP headers. This isn't a memory corruption bug; it's a logic flaw where the program blindly trusts that a string is just a string, not a command delimiter.

The Flaw: When Text Becomes Syntax

To understand why this is dangerous, you have to look at how a raw HTTP request is constructed. When you run wget http://example.com/file, the program opens a socket to port 80 and sends a formatted string. It looks something like this:

GET /file HTTP/1.1
Host: example.com
User-Agent: Wget
Connection: close
 

The structure relies entirely on newlines (\r\n) to separate the request line from the headers, and the headers from the body. The vulnerability lies in networking/wget.c. The code takes the path component of the URL and sprintfs it directly into that first line. It does not check if the path contains the very characters used to delimit the protocol.

If an attacker provides a URL like http://example.com/file%0d%0aX-Evil: true, and the shell or a calling script decodes that before passing it to wget (or if wget processes a redirect containing it), the resulting raw request sent to the server becomes:

GET /file
X-Evil: true HTTP/1.1
Host: example.com
...

The server parses this. It sees a GET request for /file. Then, crucially, it sees a header named X-Evil with a value of true HTTP/1.1. Wait, that looks broken, doesn't it? The server might ignore the garbage trailing the header, or worse, if the attacker aligns the injection perfectly, they can completely fabricate a second request (Request Splitting) or inject critical headers that the backend application uses for authentication.

The Code: Autopsy of a Socket Writer

Let's look at the smoking gun. In the vulnerable versions of BusyBox, the code responsible for parsing the URL and preparing the request didn't care about the content of the string. It was a simple string manipulation operation. The fix, introduced in response to this CVE, is telling. It adds a dedicated sanitization function.

Here is the essence of the fix introduced in networking/wget.c. The developers had to explicitly teach wget what a 'bad' byte looks like:

static void die_on_bad_http_bytes(const char *s, int reject_space, const char *what)
{
    const unsigned char *p = (const unsigned char*)s;
    while (*p) {
        unsigned char c = *p++;
        // The Blocklist: CR, LF, Control Chars, DEL, and optionally Space
        if (c == '\r' || c == '\n' || c < 0x20 || c == 0x7f || (reject_space && c == ' '))
            bb_error_msg_and_die("bad %s", what);
    }
}

Before this function existed, wget would happily process a URL containing 0x0D (\r) and 0x0A (\n). Now, it iterates through the target.path and target.host byte by byte. If it sees a control character (anything below 0x20), it calls bb_error_msg_and_die.

Notice the reject_space argument? The vulnerability wasn't just CRLF. It was also raw spaces. In HTTP/1.1, the request line is METHOD URI VERSION. If you inject a space into the URI, you can prematurely terminate the URI field and confuse the server into thinking the protocol version comes next. This patch slams the door on both techniques.

The Exploit: Popping the Box

How do we weaponize this? We need a scenario where we control the URL. Imagine a microservice that downloads images based on a user-supplied URL. It runs a command like busybox wget $USER_INPUT -O -. If the application doesn't strictly validate the URL format before shelling out (and let's be honest, they rarely do), we are in business.

We can verify this with a simple Python server that checks for a secret header, X-Secret. If the header is present, it gives us the flag. If not, it gives us a 403.

# The Victim Server Logic
if self.headers.get("X-Secret") == "yes":
    return "Here are the nuclear codes"
else:
    return "Access Denied"

The attack payload looks like this: http://127.0.0.1:9000/funny_cat.jpg HTTP/1.1 X-Secret: yes a:

When wget receives this (assuming the shell passes the raw bytes), it constructs the request. The injection splits the request line. The a: at the end is a classic trick to consume the legitimate HTTP/1.1 that wget automatically appends, turning it into a garbage header a: HTTP/1.1.

The Resulting Wire Traffic:

GET /funny_cat.jpg HTTP/1.1
X-Secret: yes
a: HTTP/1.1
Host: 127.0.0.1:9000
User-Agent: Wget
...

The server sees the X-Secret header, validates it, and hands over the goods. We have successfully bypassed the application logic by manipulating the transport layer.

The Impact: Why Should We Panic?

You might be thinking, 'So I can inject headers, big deal.' But in the modern cloud landscape, headers are identity.

1. SSRF on Steroids: If you can inject headers, you can often bypass internal authentication. Many internal APIs trust requests coming from localhost or specific subnets, relying on headers like X-User-ID or X-Role: Admin. If you can force wget to send those headers, you become the admin.

2. Cache Poisoning: This is the most dangerous vector. If wget is being used to fetch a resource that is then cached (e.g., a reverse proxy or CDN), injecting a split response could poison the cache for everyone. You could force the server to respond with a malicious JavaScript file instead of the expected jQuery library, and that malicious file gets cached and served to every subsequent user.

3. Request Smuggling: By manipulating the Content-Length or Transfer-Encoding headers via injection, you can desynchronize the connection between wget and the server (or a proxy in between). This is advanced territory, but it allows for stealing responses meant for other requests sharing the same TCP connection.

The Fix: How to Stop the Bleeding

The remediation is straightforward but requires a binary update. You cannot configure your way out of this within wget itself.

1. Upgrade BusyBox: The patch was applied in late August 2025. You need a version of BusyBox newer than 1.37.0 (likely 1.37.1 or 1.38.0). If you are on a distro like Alpine or Debian, check specifically for CVE-2025-60876 in the changelogs.

2. Sanitize Inputs Upstream: Do not rely on the tool to be safe. If your application calls wget with user input, validate the URL in your application code first. Use a strict regex. Reject any input containing \r, \n, or raw spaces. If you are passing a URL to a shell command, ensure it is properly quoted, although quoting won't save you if the tool itself (wget) is vulnerable to the content of the string.

3. Switch Tools (If Possible): If you can, use curl (which has had strict protocol validation for years) or native HTTP libraries in your programming language. Using a CLI tool via system() or subprocess calls is historically a recipe for disaster.

Official Patches

BusyBox GitOfficial patch implementation
DebianDebian security tracker entry

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N
EPSS Probability
0.05%
Top 84% most exploited

Affected Systems

BusyBox wget applet (versions <= 1.37.0)Alpine Linux containers (older images)Embedded Linux firmware (OpenWrt, Buildroot based systems using affected BusyBox)CI/CD pipelines using BusyBox for artifact retrieval

Affected Versions Detail

Product
Affected Versions
Fixed Version
BusyBox wget
BusyBox
<= 1.37.0Post-1.37.0 commits
AttributeDetail
CWE IDCWE-113 (CRLF Injection)
Attack VectorNetwork (Input Dependent)
CVSS v3.16.5 (Medium)
ImpactHeader Injection, Request Splitting
EPSS Score0.05%
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1210Exploitation of Remote Services
Lateral Movement
CWE-113
Improper Neutralization of CRLF Sequences in HTTP Headers

The software includes user-supplied data in an HTTP response header without validating that the data does not contain CR and LF characters.

Known Exploits & Detection

Mailing ListInitial report and PoC by Takeuchi Yuma demonstrating X-Secret header injection.

Vulnerability Timeline

Vulnerability reported to BusyBox mailing list
2025-08-23
Patch submitted by Takeuchi Yuma
2025-08-28
CVE-2025-60876 Assigned/Published
2025-11-10

References & Sources

  • [1]BusyBox Mailing List Disclosure

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 5 hours ago•CVE-2026-54347
8.7

CVE-2026-54347: Stored Cross-Site Scripting in Froxlor DNS TXT Record Configuration

A critical stored Cross-Site Scripting (XSS) vulnerability was identified in Froxlor server administration software panel before version 2.3.8. Authenticated customers with DNS editor privileges can inject malicious JavaScript into DNS TXT records. Because the application processes these values via a raw formatting callback without context-aware HTML entity encoding, the payload executes in the security context of administrative users who view the affected domain's DNS zones.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 6 hours ago•CVE-2026-54348
7.2

CVE-2026-54348: Second-Order SQL Injection in Froxlor API Layer

An authenticated administrator with privileges to manage admin accounts (such as change_serversettings) can execute arbitrary SQL commands via a second-order SQL injection vulnerability. The flaw resides in Froxlor's administrative API endpoints, specifically during the handling of IP address mapping parameters which are stored as serialized arrays and later interpolated without sanitization into active database queries. This vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 7 hours ago•CVE-2026-54543
5.4

CVE-2026-54543: DNS Resource Record (RR) Injection in Froxlor DomainZones API

CVE-2026-54543 is a DNS Resource Record (RR) Injection vulnerability in Froxlor, an open-source server administration control panel. Prior to version 2.3.8, the DomainZones.add API command failed to perform strict sanitization and validation on the user-controlled record (label) and type parameters before serializing them into BIND-compatible zone files. An authenticated customer with DNS zone management permissions can inject control characters, breaking out of the original record context to define unauthorized resource records within managed zones.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 7 hours ago•CVE-2026-42533
9.2

CVE-2026-42533: NGINX Map Directive and Regex Matching Pre-Auth Heap Buffer Overflow & Info Leak

CVE-2026-42533 is a critical security vulnerability discovered in NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and related products, referred to as the 'Two-Pass Capture-Clobbering' bug. The flaw is situated within NGINX's internal evaluation engine when handling complex variables, exposing a heap-based buffer overflow and information leak when a configuration chains regular expression-based map directives with numbered capture groups. An unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests to trigger remote code execution or defeat ASLR.

Alon Barad
Alon Barad
7 views•7 min read
•about 8 hours ago•CVE-2026-55593
6.5

CVE-2026-55593: Persistent Administrative Hijacking via Cross-Site Request Forgery in Froxlor Ajax Router

Froxlor prior to version 2.3.8 contains a high-severity architectural flaw where the standalone lib/ajax.php entry point bypasses the centralized request validation in lib/init.php. Unauthenticated remote attackers can leverage Cross-Site Request Forgery (CSRF) to induce authenticated administrators to submit forged requests that modify API key whitelists and expiration dates, potentially yielding persistent, out-of-band administrative control.

Amit Schendel
Amit Schendel
6 views•8 min read
•about 9 hours ago•CVE-2026-62988
9.0

CVE-2026-62988: Multi-Factor Authentication and Credential Bypass in Froxlor API

An insecure data retrieval flaw in the Froxlor server administration panel API allows authenticated remote attackers to retrieve unredacted bcrypt password hashes and Base32-encoded Time-Based One-Time Password (TOTP) seeds. Affected endpoints include several 'get' and 'listing' handlers for customers, administrators, and FTP accounts. Utilizing these leaked parameters, attackers can crack the password hashes offline and concurrently generate valid second-factor authentication codes to completely bypass access controls.

Amit Schendel
Amit Schendel
8 views•6 min read