
Detection scripts for Pi-hole FTLDNS RCE (CVE-2026-35517) via newline injection, including Python scanner and Nmap NSE script for version-based vulnerability assessment.
A Remote Code Execution vulnerability in Pi-hole's FTLDNS engine (versions 6.0 through 6.5) allows an authenticated attacker to inject arbitrary dnsmasq configuration directives by embedding newline characters (\n) into the dns.upstreams API parameter. Since dnsmasq supports directives that execute shell commands, this newline injection directly translates to full command execution on the host system.
This isn't just a single bug, it's a class of injection that affects five different configuration parameters, all patched together in FTL v6.6.
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-35517 |
| Vendor | Pi-hole Project |
| Product | FTLDNS (pihole-FTL) |
| Affected Versions | 6.0 to < 6.6 |
| CVSS v3.1 | 8.8 (High) |
| CWE | CWE-93 — Improper Neutralization of CRLF Sequences |
| Attack Vector | Network |
| Authentication | Required (Pi-hole admin/API access) |
| User Interaction | None |
| Published | April 7, 2026 |
| Patched In | FTL v6.6 (released April 3, 2026) |
| Discovered By | T0X1Cx |
| Related Advisories | GHSA-23w8-7333-p9fj, GHSA-wxhv-w77q-6qwp, GHSA-28g5-gg88-wh5m, GHSA-fqv2-qhfh-ghcj, GHSA-vfmq-jrx3-wv3c |
Pi-hole is one of the most widely deployed DNS sinkholes in the world. It sits on your network, handles DNS queries, and blocks ads and trackers at the DNS level before they ever reach your browser. It's used everywhere from single Raspberry Pi setups in apartments to enterprise deployments protecting thousands of devices.
FTLDNS (Faster Than Light DNS) is Pi-hole's core engine. It's a custom fork/wrapper around dnsmasq, the well-known DNS and DHCP server. FTLDNS handles:
Here's the key detail: FTLDNS generates dnsmasq configuration files from user-supplied settings through its API. If you change the upstream DNS server in the Pi-hole admin panel, FTLDNS writes that value into a dnsmasq configuration file and restarts the service. That write path is where the vulnerability lives.
+------------------+ +------------------+ +------------------+
| Admin Panel | API/Web | FTLDNS Engine | Config Write | dnsmasq |
| (Web UI) | ---------> | (pihole-FTL) | ------------> | (DNS/DHCP) |
+------------------+ +------------------+ +------------------+
| |
Reads settings, Reads config,
writes to config serves DNS/DHCP
files on disk to network
When an admin changes the upstream DNS servers through the Pi-hole web UI or API, the flow is:
The dns.upstreams parameter is intended to accept DNS server addresses like 8.8.8.8 or 1.1.1.1. FTLDNS writes these into the dnsmasq config as server= directives:
# Normal input: "8.8.8.8"
# Generates:
server=8.8.8.8
The problem: FTLDNS does not sanitize newline characters in the input. An attacker can inject \n to break out of the intended server= directive and inject entirely new configuration lines:
# Malicious input: "8.8.8.8\ndhcp-option=6,evil.dns.server"
# Generates:
server=8.8.8.8
dhcp-option=6,evil.dns.server
This alone would be concerning (DNS hijacking via DHCP option injection). But it gets worse.
dnsmasq supports a configuration directive called dhcp-option that can reference external scripts, and more critically, it supports several directives that can execute commands in specific scenarios. The exploitation chain looks like this:
Step 1: Attacker authenticates to Pi-hole
(default creds, weak password, CSRF, compromised session)
Step 2: Attacker sends API request to update dns.upstreams:
POST /api/dns/upstream
{
"upstreams": ["8.8.8.8\n<malicious dnsmasq directive>"]
}
Step 3: FTLDNS writes the value to the dnsmasq config file
without sanitizing the newline
Step 4: The injected dnsmasq directive is parsed as a
legitimate configuration option
Step 5: Depending on the directive injected, the attacker achieves:
- DNS hijacking (redirect all DNS queries)
- DHCP poisoning (push malicious configs to clients)
- Command execution via dnsmasq's scripting capabilities
- File write to arbitrary paths
The key insight is that this isn't about exploiting a dnsmasq vulnerability, dnsmasq is working as designed. The vulnerability is that FTLDNS lets untrusted input bleed into the configuration file, turning a configuration management API into an arbitrary config injection point.
The researcher (T0X1Cx) discovered that the same newline injection pattern affects five different FTLDNS configuration parameters. This is a systemic issue — the code lacked input sanitization across the board:
| Advisory | Parameter | What It Controls |
|---|---|---|
| GHSA-23w8-7333-p9fj | dns.upstreams | Upstream DNS servers |
| GHSA-wxhv-w77q-6qwp | dns.hostRecord | Custom DNS host records |
| GHSA-28g5-gg88-wh5m | dns.cnameRecords | CNAME record mappings |
| GHSA-fqv2-qhfh-ghcj | dhcp.leaseTime | DHCP lease duration |
| GHSA-vfmq-jrx3-wv3c | dhcp.hosts | Static DHCP host assignments |
Each of these parameters writes to dnsmasq configuration files, and each failed to sanitize newline characters. The fix in FTL v6.6 added proper input validation that rejects newline characters (and other control characters) across all configuration parameters.
On the Pi-hole host:
On the network (downstream impact):
Risk amplification factors:
| Version | Status |
|---|---|
| FTLDNS 6.6+ | Patched |
| FTLDNS 6.0 – 6.5 | Vulnerable |
| FTLDNS 5.x and earlier | Not affected (different API architecture) |
To check your version:
pihole -v
# or
pihole-FTL --version
High risk:
Moderate risk:
Lower risk (but still patch):
The Python script detects vulnerable Pi-hole instances through version-based analysis.
How it works:
No injection payloads are sent. The test is entirely read-only and safe.
Usage:
# Install dependencies
pip install -r requirements.txt
# Single target (HTTP, default port 80)
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1
# Custom port
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t pi.hole -p 8080
# HTTPS mode (auto-switches to port 443)
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 10.0.0.1 --https
# Bulk scan from file
python CVE-2026-35517_PiHole_FTLDNS_detector.py -f targets.txt
# JSON output saved to file
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1 --json -o results.json
# Increased timeout
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1 --timeout 20
Options:
| Flag | Description | Default |
|---|---|---|
-t, --target | Target IP or hostname | — |
-f, --file | File with targets, one per line (# comments supported) | — |
-p, --port | Target port | 80 |
--https | Use HTTPS (auto-switches port to 443 if port is 80) | Off |
--timeout | Connection timeout in seconds | 10 |
--json | Output in JSON format | Off |
-o, --output | Save results to a file | — |
Example output:
╔══════════════════════════════════════════════════════════════╗
║ CVE-2026-35517 - Pi-hole FTLDNS RCE Detector ║
║ Newline Injection in dns.upstreams → Command Execution ║
║ CVSS: 8.8 (High) | Affects: FTLDNS 6.0 - 6.5 ║
╚══════════════════════════════════════════════════════════════╝
[*] Scanning 192.168.1.1:80...
Target: 192.168.1.1:80
============================================================
[*] Pi-hole detected
Admin interface: Accessible
API accessible: Yes
FTL version: v6.4
Core version: v6.3
Web version: v6.4
CVE-2026-35517 Assessment:
[VULNERABLE] FTLDNS 6.4 is within the vulnerable range (6.0 - 6.5).
Upgrade to FTL v6.6 or later immediately.
Related Vulnerabilities (also patched in FTL v6.6):
[-] GHSA-wxhv-w77q-6qwp: RCE via dns.hostRecord Newline Injection
[-] GHSA-28g5-gg88-wh5m: RCE via dns.cnameRecords Newline Injection
[-] GHSA-fqv2-qhfh-ghcj: RCE via dhcp.leaseTime Newline Injection
[-] GHSA-vfmq-jrx3-wv3c: RCE via dhcp.hosts Newline Injection
Remediation:
1. Upgrade Pi-hole FTL to version 6.6 or later
2. Run: pihole -up
3. Verify with: pihole -v
4. Review API access controls and authentication settings
5. Check logs for signs of exploitation (unusual DNS config changes)
# Install the NSE script
sudo cp CVE-2026-35517_PiHole_FTLDNS.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# Basic scan
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS <target>
# Scan common Pi-hole ports
nmap -p 80,443,8080,4711 --script CVE-2026-35517_PiHole_FTLDNS <target>
# Subnet scan — find all Pi-hole instances on a network
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS 192.168.1.0/24
# Combined with version detection
nmap -sV -p 80,443 --script CVE-2026-35517_PiHole_FTLDNS <target>
# Scan targets from a file
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS -iL targets.txt
Example Nmap output:
PORT STATE SERVICE
80/tcp open http
| CVE-2026-35517_PiHole_FTLDNS:
| VULNERABLE:
| Pi-hole FTLDNS RCE via Upstream DNS Configuration
| State: VULNERABLE
| IDs: CVE:CVE-2026-35517
| Risk factor: High (CVSS: 8.8)
| Disclosure date: 2026-04-07
| Extra information:
| FTL Version: v6.4
| Core Version: v6.3
| Web Version: v6.4
| Related advisories also fixed in FTL v6.6:
| GHSA-wxhv-w77q-6qwp (dns.hostRecord injection)
| GHSA-28g5-gg88-wh5m (dns.cnameRecords injection)
| GHSA-fqv2-qhfh-ghcj (dhcp.leaseTime injection)
| GHSA-vfmq-jrx3-wv3c (dhcp.hosts injection)
| Remediation: Upgrade to Pi-hole FTL v6.6+ (pihole -up)
| References:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-35517
|_ https://github.com/pi-hole/FTL/security/advisories/GHSA-23w8-7333-p9fj
If you have SSH access to the Pi-hole host:
# Check FTL version
pihole-FTL --version
# Or via the Pi-hole CLI
pihole -v
# Check via API (v6)
curl -s http://pi.hole/api/info/version | python3 -m json.tool
# Check via API (v5)
curl -s http://pi.hole/admin/api.php?versions | python3 -m json.tool
If the FTL version is between 6.0 and 6.5 (inclusive), you are vulnerable.
What to look for:
/etc/dnsmasq.d/ and /etc/pihole/ for unexpected directivesCommands to investigate:
# Check dnsmasq configs for injected lines
grep -r "dhcp-option\|addn-hosts\|conf-file\|log-facility" /etc/dnsmasq.d/
# Check for recent config modifications
find /etc/pihole /etc/dnsmasq.d -mtime -7 -ls
# Review Pi-hole's debug log
pihole -d
# Check running processes for anomalies
ps aux | grep -E "dnsmasq|pihole"
# Review crontab for persistence
crontab -l
cat /etc/crontab
ls -la /etc/cron.d/
Immediate action - upgrade now:
# Update Pi-hole (includes FTL, Web, and Core)
pihole -up
# Verify the update
pihole -v
# FTL version should be >= 6.6
If you can't upgrade immediately:
pihole -a -pPost-patch actions:
Kerem Oruç - Cybersecurity Engineer