Repository navigation
Releases
Pi-hole FTL v6.8
Security
This release fixes the following security advisories (credit to the reporters named):
High
- GHSA-2h7g-g549-hf74 (CVSS 7.7): document root could be relocated via a Teleporter import or symlink. Reported by @abdoghazy2015 and @Jgarcg40.
Medium
- GHSA-667h-gpmh-7gxc (CVSS 6.5): contents of local files echoed when parsing a
file://adlist. Reported by @Rakan78. Requires Core v6.5. - GHSA-v53r-4564-3449 (CVSS 6.5, duplicate GHSA-846w-3j3v-2hx8): read-only app sessions could read password hashes and the TOTP secret. Reported by @Pedromdsn and @010011110.
- GHSA-8fc6-q9x4-892v (CVSS 5.9): out-of-bounds write in the API TXT buffer. Reported by @dagadjno.
- GHSA-xj4x-gf2g-r6m7 (CVSS 4.2): EDNS(0) data leaking between clients' queries. Reported by @010011110.
Low
- GHSA-322h-f873-hp54: cross-site requests and DNS rebinding against a passwordless install. Reported by @ChrisLundquist.
- GHSA-mqr7-j2p5-5495 (CVSS 2.7): crash on a malformed POSTed regex array. Reported by @010011110.
- GHSA-v8mj-cqgw-63rj (CVSS 2.2): race when deleting a DHCP lease. Reported by @010011110.
- GHSA-9828-2f2q-2c8v (CVSS 2.2): crash when searching domains during a list reload. Reported by @010011110.
What's Changed
This is a minor release rather than v6.7.2: there are enough visible behaviour changes that a patch version would undersell it. It backports the bug fixes that landed on development since v6.7.1 and updates the embedded dnsmasq (v2.93+30) and SQLite (v3.53.3).
Improvements
- The live log is now stored as a ring buffer instead of moving the whole buffer for every new line, which costs far less CPU per cached answer.
- Internationalised domain names on lists are converted to punycode with libidn2 and block, instead of being rejected as invalid.
- Long-term statistics are grouped before joining the name tables (faster), and two unused in-memory indexes are gone, saving about 22 MB per million queries.
Notable fixes
- Flushing the logs deleted the whole long-term history, not only the last 24 hours, and moved the graph a day into the future.
- Crashes with 257+ alias-clients, with a no-longer-forced
FTLCONF_array, and withdatabase.DBinterval = 0. - Group and list changes not reaching a client until the next reload, stale forced replies, and missing EDE on the first block.
- A file path containing
+(or any other printable ASCII) was reset to its default on start-up. - An open redirect in the
.lpcompatibility redirect, and/ignoringwebserver.serve_all. - Pi-hole's own certificate for a custom
webserver.domainwas never renewed, and a domain longer than 64 characters ended up as an oversized CN. - The empty-DS DNSSEC loop, via dnsmasq, plus its double-free and information disclosure fixes.
- An API session could enable
misc.readOnlythrough a Teleporter archive, andpihole.toml.lockfailed on NFS. - Any LAN client could make FTL add a new PTR record for every spelling of its own address until a restart.
- The CLI password file and
pihole-tmp.dbwere briefly or permanently readable by everyone. - On ARM and RISC-V the MAC address of a new device was never looked up at query time, so its MAC-based groups only applied later.
- Raising
misc.privacylevelat runtime did not cover domains and clients already seen, and anntp.sync.intervalabove about 24.8 days made the NTP client sync back to back. - DNS stalls on list reloads and rate limiting, GC double processing, lost queries at shutdown, and wrong long-term statistics.
- Old queries were never deleted from
pihole-FTL.dbon a host that restarts FTL at least once a day. dhcp-discoverprinted the DNSSL labels of Router Advertisements unescaped.- Clients without a MAC address (e.g. a WireGuard peer) stayed in the default group until the next list reload, because the groups of a new client were resolved before its interface was known.
- The load check counted only the CPUs a container was limited to, while
/proc/loadavgshows the host's load, so the long-term load warning fired spuriously and/api/info/systeminflated the load percentage in LXC/Docker with fewer cores. FTL now counts all present host CPUs. FTLCONF_files_log_ftlwas not used for log lines on early startup.
Behaviour changes to be aware of
- Invalid values found in
pihole.tomlare rejected and reset to the default:database.DBintervalof 0, awebserver.tls.certbelow the webroot, a non-base32webserver.api.totp_secret, relative paths for files FTL writes, and afiles.tmp_dbthat names another file Pi-hole keeps (e.g.pihole-FTL.db). Awebserver.api.maxHistoryabove 86400 is reduced to 86400. A list (e.g.dns.hosts) now loses only its invalid entries instead of being reset as a whole. - With
webserver.serve_all = false,/under a host other thanwebserver.domainnow returns a 404, so a customindex.htmlin the webroot no longer shows up athttp://<ip>/. Behind a proxy that does not stripwebserver.paths.prefix, the prefixed path returns a 404 as well. - A renewed self-signed certificate comes with a new CA, so an imported
tls_ca.crthas to be imported again. - FTL no longer hands a symbolic link (e.g.
pihole-FTL.dborFTL.loglinked to another disk) to thepiholeuser, and warns about it on every start. Such a target has to be owned bypiholealready. - When FTL runs as root it only changes ownership or permissions of regular files directly in
/etc/piholeand/var/log/pihole, and refuses a symbolic link as log file (includingfiles.log.dnsmasq). Started aspihole, a linked log file keeps working. - A blocking timer on an unchanged status now switches to the opposite mode when it expires.
- The host's own interfaces show up in the network table, and shutdown may wait up to 30 seconds for a busy database thread.
- dnsmasq adds the
option4:syntax and DHCPv6 vendor classes. - Changing
ntp.sync.intervalrestarts FTL,ntp.sync.count = 0is rejected, andPOST /api/action/gravityanswers 409 while a run is in progress. - Queries older than
database.maxDBdaysare deleted in the first night after a start, 10000 at a time. A database that kept growing will lose its whole backlog in the first night after the update. - A v5 Teleporter import replaces the upstreams, reverse servers and excluded domains/clients instead of adding to them.
Full Changelog: v6.7.1...v6.8
Pi-hole FTL v6.7.1
Security Fixes
- pi-hole/FTL/security/advisories/GHSA-2794-hrj8-5jg9 - Remote code execution and arbitrary file read via
webserver.advancedOpts(High) reported by keithlinneman - pi-hole/FTL/security/advisories/GHSA-ww5x-xx4x-qvjr - Remote code execution via exec-capable options in
misc.dnsmasq_lines(High) reported by keithlinneman - pi-hole/FTL/security/advisories/GHSA-gx63-h4w6-f46g - Configuration validators can be bypassed via Teleporter import, combined changes and document-root relocation (High)
- pi-hole/FTL/security/advisories/GHSA-7997-2868-rjfg - Stack buffer overflow in the blocked-answer path (Moderate) reported by 010011110
Behavior changes
misc.dnsmasq_linesandwebserver.advancedOptscan no longer be changed through the API or the web interface. They can still be set inpihole.toml, through environment variables and withpihole-FTL --config.- Wrong-method API requests now return 405 with an
Allowheader, andOPTIONSnames only the methods of the endpoint that fits the URI best. - The
CAP_NET_RAWstartup warning is gone, dnsmasq reports it when it actually needs the capability. database.maxDBdaysis an unsigned value now. A negative value kept the queries forever and is migrated to4294967295, which continues to do so.
Fixes of note
pi.holeand the local host name were answered with NODATA until restart once the interface cache went stale (#3050)- An infinite loop in the dnsmasq config test when
debug.configis enabled - Webserver workers spinning at 100% CPU in the mbedTLS debug callback (#3106)
- Async-signal-safety in the real-time signal handler and the TCP worker terminator
- Query indices that went stale while the shared memory lock was released, and a domain lookup that gave up at once when a list change was being committed
- Database connection leaks and counter skew, gravity regex and search-term handling, config write races, API error paths and response correctness
- Memory-safety hardening in the netlink parsers,
get_api_string(),base64_decode_update()and arp-scan
Full Changelog: v6.7...v6.7.1
v6.7
Security Fixes
- pi-hole/FTL/security/advisories/GHSA-q6fm-xwxf-37r5 — WebUI (& API) DoS via lack of rate limiting (High) reported by rrobgill
- pi-hole/FTL/security/advisories/GHSA-w8cr-2cwg-92cg — Session expiration bypass (High) reported by T0X1Cx
- pi-hole/FTL/security/advisories/GHSA-8j7w-m3cr-6q6x — Remote Code Execution via CivetWeb configuration injection (High) reported by SakusenSec
- pi-hole/FTL/security/advisories/GHSA-g7v8-8q8f-hprp — Log injection in the access-log writer chaining to RCE via Lua-server-page evaluation (Moderate)
- pi-hole/FTL/security/advisories/GHSA-r5vh-5q82-jg7q — CRLF injection / HTTP header injection via group name (Low) reported by T0X1Cx
What's Changed
- Performance optimizations and bug fixes by @DL6ER in #2816
- fix: check NULL returns from strdup/calloc in rotate_files() by @jluzzi123 in #2875
- Make error messages more human friendly by @yubiuser in #2878
- Harden API/database races in civetweb and DB threads by @DL6ER in #2881
- Update embedded SQLite3 to v3.53.1 by @DL6ER in #2891
- Fix build on Fedora 44 by @darkexplosiveqwx in #2893
- macvendor: resolve sub-allocated blocks (MA-M/MA-S) via longest-prefix match by @RamSet in #2907
- Update embedded dnsmasq to v2.93 by @DL6ER in #2890
- fix OOB write in FTL_parse_pseudoheaders when optlen is 0 by @rdevshp in #2910
- Update a single text description "PRIVATE KEY" by @DoctorD90 in #2884
- add optional dnsmasq features to cmake by @darkexplosiveqwx in #2874
- Fix building on alpine 3.24 by @yubiuser in #2911
- Bats by @yubiuser in #2872
- Improve crash backtraces for non-reproducible faults by @DL6ER in #2880
- Fix gzip.c inflate_buffer CRC signed left shift undefined behavior by @rdevshp in #2916
- Fix for iCloud Private Relay zones by @DL6ER in #2919
- fix tar parsing by @rdevshp in #2914
- Allow using local
manufs to generate macvendor.db by @darkexplosiveqwx in #2918 - Use custom message for UNIQUE constraint error message by @rdwebdesign in #2879
- Re-resolve client groups event-driven, drop periodic recheck by @DL6ER in #2922
- Guard against invalid gzip data in gzip.c inflate_buffer by @rdevshp in #2915
- Fix BATS test of no ERRORS in FTL.log to allow capturing the output by @yubiuser in #2927
- fix(cli): warn when --config cannot read pihole.toml (#2849) by @DL6ER in #2930
- fix(api-docs): correct three OpenAPI spec issues (#2867) by @DL6ER in #2929
- fix: avoid segfault in dnsmasq-test on unreadable config file by @DL6ER in #2928
- Fix prefix-match bug and improve fallthrough logging in redirect_root_handler by @slmingol in #2933
- Swap misaligned comments for domain-needed and expand-hosts. by @0xpsyduck in #2932
- Code review July 2026 by @DL6ER in #2935
- Pi-hole FTL v6.7 by @PromoFaux in #2936
New Contributors
- @jluzzi123 made their first contribution in #2875
- @RamSet made their first contribution in #2907
- @rdevshp made their first contribution in #2910
- @DoctorD90 made their first contribution in #2884
- @slmingol made their first contribution in #2933
- @0xpsyduck made their first contribution in #2932
Full Changelog: v6.6.2...v6.7
Pi-hole FTL v6.6.2
dnsmasq security update
This release imports six upstream dnsmasq security fixes, covering all publicly disclosed CVEs against the dnsmasq 2.92/2.93 line. Patches are taken verbatim from https://thekelleys.org.uk/dnsmasq/CVE/
CVEs fixed
-
CVE-2026-2291 — Heap OOB write in
struct bigname. The on-heap namebuffer was sized for the wire form of a domain name (MAXDNAME) rather than its escaped internal form (MAXDNAME*2 + 1). A remote peer that can send or answer DNS queries could cause a large out-of-bounds write on the heap. Reported by Andrew S. Fasano. -
CVE-2026-4890 — DNSSEC denial of service via NSEC bitmap parsing.The window-iteration step omitted the 2-byte window header, so a crafted NSEC record with
bitmap_length == 0produced an infinite loop and dnsmasq stopped answering queries. Reachable before RRSIG validation,so no valid signatures are required to trigger it. Reported by Royce M. -
CVE-2026-4891 — DNSSEC crash via crafted RRSIG. A packet declaring an
rdlensmaller than the fixed RRSIG header plus signer's name produced a negative signature length and a subsequent crash. Reported by Royce M. -
CVE-2026-4892 — Privileged buffer overflow in the DHCP helper.When
--dhcp-scriptis configured, hex-encoded DHCPv6 client identifiers (up to 65535 bytes) were written into a 5131-byte buffer in the root-privileged helper. Reported by Royce M. -
CVE-2026-4893 — EDNS Client Subnet validation bypass. With
--add-subnetenabled,process_reply()passed the OPT record length(~23 bytes) tocheck_source()instead of the packet length, causing every internal bounds check to fail and the validation routine to always return success. ECS source validation per RFC 7871 §9.2 was effectively disabled. Reported by Royce M. -
CVE-2026-5172 — Heap OOB read in
extract_addresses(). A mismatched RRrdlenallowedextract_name()to advance past the computed end of the record, underflowing the remaining-bytes calculation and producing a large OOB read with certain crash.Reported by Hugo Martinez Ray.
Upgrade impact
All six fixes are minimal, self-contained changes to the embedded dnsmasq sources. No FTL-side configuration or API changes; users should see no observable behavior change beyond the closed vulnerabilities.
Fix dnsmasq CVE publications by @DL6ER in #2888
This furthermore indirectly fixes #2871 due to pi-hole/docker-base-images#158
Full Changelog: v6.6.1...v6.6.2
v6.6.1
What's Changed
- Add new
GET /api/config/_propertiesendpoint by @DL6ER in #2356 - Fix thread-safety issues causing SIGSEGV under concurrent API load by @DL6ER in #2835
- fix: fix rare race condition for SHM strings in API handlers by @DL6ER in #2833
- Accept punycode domains that libidn2 rejects under IDNA2008 by @DL6ER in #2838
- Improve shutdown diagnostics to identify SIGTERM source by @DL6ER in #2839
- Resolve empty backtraces when addr2line is not installed by @DL6ER in #2831
- Improve thread-safety for concurrent API requests by @DL6ER in #2847
- Don't skip device lookup when resolver.macNames is disabled by @DL6ER in #2846
- Fix linker error when compiling w/o optimization by @aeolio in #2850
- Clarify
dns.blockESNIwording by @darkexplosiveqwx in #2784 - Preserve log file path config when fopen fails by @DL6ER in #2834
Security advisories
- GHSA-6w8x-p785-6pm4
- Fixed with : 88c569a and pi-hole/pi-hole@7ccb8dd
- GHSA-9cqv-839p-gpq2
- Fixed with : 0c46e4e
New Contributors
- @darkexplosiveqwx made their first contribution in #2784
Full Changelog: v6.6...v6.6.1
v6.6
What's Changed
- Fix possible resolver issue on armv5tel by @DL6ER in #2781
- Introduce CMake options for optional dependencies by @aeolio in #2795
- Fix build without mbedtls [v2] by @aeolio in #2796
- Fix overTime data when database.DBimport = false by @DL6ER in #2788
- Fix cross-compilation issues w/ custom toolchain by @aeolio in #2797
- Add new option for controling name resolution via MAC address by @DL6ER in #2790
- Fix obtaining client groups by name by @DL6ER in #2791
- Ensure API sessions are restored before starting the HTTP server by @DL6ER in #2803
- Add form-action 'self' to Content-Security-Policy by @yubiuser in #2804
- Add query_frequency to /padd endpoint by @yubiuser in #2806
- Guard query-count counters against unsigned underflow by @DL6ER in #2815
- Add universal crash backtrace via _Unwind_Backtrace by @DL6ER in #2811
- config: show totp_secret presence in CLI output by @DL6ER in #2813
- Fix client count inflation for rate-limited queries by @DL6ER in #2814
- Fix stack buffer overflow in get_process_name() by @DL6ER in #2821
- Do not restart FTL while
pihole -gis still ongoing by @DL6ER in #2419
Security Advisories
- GHSA-r7g8-3fj7-m5qq - Authorization bypass: CLI API sessions can import Teleporter archives and modify configuration reported by @mzalzahrani
- Remote Code Execution (RCE) via Newline Injection in Multiple Configuration Parameters reported by @T0X1Cx
New Contributors
Full Changelog: v6.5...v6.6
v6.5
What's Changed
- Tweak undocumented wait-for option subtly by @DL6ER in #2707
- update gravity - improve domain validation processing speed by @rrobgill in #2710
- Update embedded SQLite3 to 3.51.1 by @DL6ER in #2731
- Update embedded dnsmasq to 2.92rc1 by @DL6ER in #2730
- Fix documentation - Do not use equal sign with
pihole-FTL --configcommand by @rdwebdesign in #2736 - Add dns.cache.rrtype by @Manakuremati in #2740
- Enhancements to the documentation markdown generator by @PromoFaux in #2741
- Network Overview - obtain MAC and hostname from dhcp.leases by @rrobgill in #2727
- fix: make
get_domainsparameters optional by @tien in #2278 - Escape unprintable characters in invalid host names by @DL6ER in #2601
- Implement better allOf handling in API verifier by @DL6ER in #2745
- Update build containers to Alpine 3.23 by @DL6ER in #2743
- Add option to hide network connection errors by @DL6ER in #2749
- Harden default Content Security Policy (CSP) by @Erasure5959 in #2754
- Fix computation of NTP server's root delay by @DL6ER in #2760
- Teleporter: Fix for custom gravity.db path by @DL6ER in #2758
- Upgrade embedded Lua to 5.5 by @DL6ER in #2626
- Add missing [forwarded] property in GET /api/history/database by @DL6ER in #2750
- Update SQLite3 to 3.51.2 by @DL6ER in #2761
- Low-memory hardware optimizations by @DL6ER in #2757
- Reduce startup delay by @DL6ER in #2725
- home.arpa and internal TLDs may be non-local without revServer by @DL6ER in #2772
New Contributors
- @Erasure5959 made their first contribution in #2754
Full Changelog: v6.4.1...v6.5
v6.4.1
Nothing to see here - accidentally tagged the wrong commit for the big 6.4 release. Content is exactly the same as v6.4
What's Changed
- Fix API specs and example for dns.upstreams in config.yaml by @rdwebdesign in #2696
- gravity update - silently discard unicode BOM if present by @rrobgill in #2702
- Update embedded SQLite to 3.51.0 by @DL6ER in #2704
- Get earliest query timestamp from database by @PromoFaux in #2706
- Increase buffer length for query string by @mwoolweaver in #2709
- Reduce DNS resolver locking during database interaction by @DL6ER in #2700
- Make colour output optional in streaming gravity API call by @PromoFaux in #2718
- api/dhcp/leases Allow for hwaddr > 48 bits by @rrobgill in #2724
- Add rate-limiting for TOTP validation by @DL6ER in #2719
- Implement simple partial matching for regex in /api/search/{domain} by @DL6ER in #2705
- Performance optimizations: string processing, memory management, and compiler flags by @Copilot in #2571
- Fix authentication redirect when webhome is / (fixes #2518) by @averyvigolo in #2610
- Reduce database locking and add timing debug setting by @DL6ER in #2688
New Contributors
- @mwoolweaver made their first contribution in #2709
- @Copilot made their first contribution in #2571
- @averyvigolo made their first contribution in #2610
Full Changelog: v6.3.3...v6.4.1
v6.4
What's Changed
- Fix API specs and example for dns.upstreams in config.yaml by @rdwebdesign in #2696
- gravity update - silently discard unicode BOM if present by @rrobgill in #2702
- Update embedded SQLite to 3.51.0 by @DL6ER in #2704
- Get earliest query timestamp from database by @PromoFaux in #2706
- Increase buffer length for query string by @mwoolweaver in #2709
- Reduce DNS resolver locking during database interaction by @DL6ER in #2700
- Make colour output optional in streaming gravity API call by @PromoFaux in #2718
- api/dhcp/leases Allow for hwaddr > 48 bits by @rrobgill in #2724
- Add rate-limiting for TOTP validation by @DL6ER in #2719
- Implement simple partial matching for regex in /api/search/{domain} by @DL6ER in #2705
- Performance optimizations: string processing, memory management, and compiler flags by @Copilot in #2571
- Fix authentication redirect when webhome is / (fixes #2518) by @averyvigolo in #2610
- Reduce database locking and add timing debug setting by @DL6ER in #2688
New Contributors
- @mwoolweaver made their first contribution in #2709
- @Copilot made their first contribution in #2571
- @averyvigolo made their first contribution in #2610
Full Changelog: v6.3.3...v6.4