WHMCS's addon-module password-type fields are stored plaintext in tbladdonmodules.value — unlike tblservers.password which IS encrypted at rest. Config::get() was blindly calling decrypt() on the raw value and then preferring its output over raw when the two differed. Unfortunately, when decrypt() is fed a plaintext string, it doesn't return empty or unchanged — it returns a short binary-garbage string (observed: 4 bytes of \xEF\xBF\xBD unicode-replacement noise for a 32-char plaintext). That garbage then went into the X-API-Key header, PowerDNS responded 401, and every rDNS read returned an empty zone list, surfacing as "no zone" for every IP in the client UI. Fix: only accept decrypt()'s output when it's printable ASCII. Real API keys are always printable; decrypted ciphertext that looks like binary is a mangled-plaintext signal, so we fall back to raw. Also trim() the chosen value to defeat a second foot-gun — admin UIs can silently append a newline on paste, which would land in the header verbatim and produce the same 401. Diagnosed via direct WHMCS tbladdonmodules inspection on a user's affected install; confirmed the fix end-to-end with a live ping() returning HTTP 200 post-deploy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.1 KiB
9.1 KiB