Pi-hole FTL v6.9 and Core v6.6 released

Pi-hole FTL v6.9 and Core v6.6 released

Pi-hole FTL v6.9 and Core v6.6 are now available. The web interface has no release this time and stays at v6.6.1.

This release fixes a number of security advisories in FTL and Core. Thank you to everyone who reported them: @Pedromdsn, @pmagayon, @cerodah, @wyx98765, @gudangkantong and @010011110.

Before updating, please read the changelogs below. Update with pihole -up. If you want a safety net, take a backup of your configuration first with Teleporter (Settings -> Teleporter in the web interface, or pihole-FTL --teleporter).

The Docker image is tagged 2026.11.0.

Security fixes

High

  • FTL + Core: command execution through files.gravity (GHSA-pj9m-9623-2g75 / GHSA-cq9w-mv93-mxh7, CVSS 7.2): FTL v6.8 accepted a quote in file paths, and both gravity.sh and the Teleporter put files.gravity into SQL unescaped. An admin could use this to run commands as pihole. Core now escapes the path and FTL binds it to a prepared statement. Update both. Reported by @Pedromdsn.
  • Core: the installer still followed symlinks in /etc/pihole (GHSA-wp3p-45h3-2v82, CVSS 7.3): pihole -r and pihole -up wrote install.log, the v6 migration backup and hosts/custom.list as root. The installer now writes into /etc/pihole only as pihole. Found by @cerodah, reported by @pmagayon.
  • Core: root following pihole-controlled paths (GHSA-5w4v-f65m-323f, CVSS 7.3): in the macvendor.db download, pihole checkout and pihole uninstall. Reported by @pmagayon.
  • Core: pihole -d following symlinks (GHSA-jvg9-fm8x-2jqq, CVSS 7.3): the debug script now works in pihole-owned directories as pihole. Found by @wyx98765, reported by @pmagayon.

Medium

  • Core: secrets in the debug log (GHSA-qfq3-88xg-765w, CVSS 5.3): the pihole -d log, and so a tricorder upload, included the password hashes and the TOTP secret. If you have uploaded a debug log, consider changing your password and app password and setting up 2FA again. Reported by @pmagayon.

Low

  • FTL: limited sessions could list and end other sessions (GHSA-x6xh-vxcm-g8rm, CVSS 3.8): app sessions without webserver.api.app_sudo and CLI sessions could see every session, including the admin’s address and user agent. Reported by @gudangkantong.
  • FTL: webserver.acl IPv4 entries ignored on dual-stack ports (GHSA-87wp-wm3p-8cxm, CVSS 3.7): with a port such as +80, deny entries let IPv4 clients through and allow entries refused them. Reported by @010011110.
  • FTL: a CLI password change could be undone (GHSA-cg4p-5r3r-m54p, CVSS 3.1): an API config write at the same time as pihole setpassword kept the old password and its sessions valid. Reported by @010011110.
  • FTL: maximum-privacy queries reaching the database (GHSA-fj2f-pgf2-j888, CVSS 2.2): queries recorded at misc.privacylevel 3 could be stored once the level was lowered. Reported by @010011110.
  • FTL: two crashes needing a valid session (GHSA-9mh9-95wj-4w4q, GHSA-9hh4-j8jf-6c96, CVSS 2.2 each): reading the metrics during a hosts reload, and a v5 Teleporter import while the API read the config. Reported by @010011110.

FTL v6.9

This release backports the fixes that landed on development since v6.8 and updates the embedded dnsmasq (v2.93+42), SQLite (v3.54.1) and the bundled TRE regex engine. The work towards v7 is not included. The TRE update changes how some stored regex filters match, so this is a minor release rather than v6.8.1.

Improvements

  • Regex matching is faster.
  • gravity.db is only reopened when it changed on disk. This was most of FTL’s CPU time while idle.
  • Partial domain searches also find ABP-style list entries.
  • With DNSSEC, dnsmasq keeps extra TCP slots for its own validation queries, so validation still works when clients use up the TCP connection limit.
  • Control characters in logged configuration values are escaped.
  • Bash completion for pihole-FTL --config -t and -q, and .diskused works in pihole-FTL sqlite3.

Notable fixes

  • Several memory safety fixes via dnsmasq: a heap out-of-bounds read in DNSSEC validation, a heap out-of-bounds write in blockdata_read(), a DNS name buffer overflow and an off-by-one in the DHCPv6 FQDN option.
  • DNSSEC SERVFAIL for deeper wildcard answers, and lost pipelined TCP answers.
  • Two config changes through the API at the same time could lose one of them.
  • The webserver could spin at 100% CPU and stop accepting connections.
  • A crashed thread could leave FTL hanging instead of exiting.
  • /api/info/system reported the host’s load inside containers.
  • FTLCONF_ variables were ignored when FTL started without pihole.toml.
  • Without a password, a link to the dashboard from another site was answered with 403.
  • misc.hide_dnsmasq_warn and misc.hide_connection_error did not hide the warnings from FTL.log.
  • pihole -g started from the web interface stopped when the browser stopped reading.
  • Queries of DNS type 0 stored by FTL v5 were skipped on import.

Behaviour changes to be aware of

  • Regex filters: {,n} and {,} now mean {0,n} and {0,}. More than three nested approximate-matching groups, and a back-reference inside an unbounded repetition, are rejected.
  • webserver.acl: IPv4 entries now match IPv4 clients on every port, and [::]/0 no longer admits IPv4 clients.
  • App sessions without webserver.api.app_sudo and CLI sessions can no longer list or end other sessions.
  • dns.cnameRecords entries with invalid names, or a TTL that does not fit into an int, are rejected.
  • A request with more than 64 headers is refused.
  • /api/info/system answers with an error instead of zeros when the load averages cannot be read, and DELETE /api/dhcp/leases/{ip} answers 503 instead of 400 when the resolver did not get to it in time.

Core v6.6

  • Pi-hole no longer needs sudo: it drops from root to pihole with setpriv.
  • The installer, pihole checkout, pihole uninstall and pihole -d no longer write into pihole-owned directories as root.
  • The debug log leaves out password hashes and the TOTP secret.
  • Pi-hole’s logs are rotated by the system’s daily logrotate. The nightly forced run is gone, because it collided with the system’s run and rotated the logs twice.
  • pihole flush quiet is quiet again, and pihole flush once finishes its status line.
  • pihole updatechecker no longer writes null hashes to /etc/pihole/versions when run from /root.
  • A warning when a local repository is not marked as safe for git, instead of pihole -v showing N/A.
  • Quad9’s unfiltered upstream is marked as validating DNSSEC.

New contributors: welcome and thank you to @baseman70 and @TooAngel for their first contributions!