~/blog/what-the-register-publishesPOSTED
by Shady Nathan Tawfik · October 19, 2026 · 12 min

The Register Is the Perimeter: What Public Certificates and Dashboards Publish

A German machine-software manufacturer asked for a web audit and got a lesson in publishing: certificate transparency named 68 customer brands across 194 tenant hostnames, the primary domain had no DMARC policy, the WordPress API reflected any origin with credentials, and a public Power BI report showed live service KPIs. Includes the lab results for the POST surfaces that only looked open.

Interactive[blog-2.0]

TL;DR: A manufacturer with a clean-looking web presence was publishing far more than it intended. Public certificate logs named 68 customer brands across 194 tenant hostnames, 40 of which still resolved. The primary domain had no DMARC policy at all, so its name could be used in forged supplier mail. The WordPress REST API reflected any origin with credentials, the staff directory was readable without a login, two customer demo hosts had no usable TLS trust, and the product portal's config exposed 40+ endpoints plus a public Power BI report with live service KPIs. The lab then showed which POST surfaces were actually dangerous — and which only looked that way.

The scenario

A German machine-software manufacturer asked me to look at its public web estate. Not one website: a corporate WordPress site, a product portal on a separate hub domain, a service-hub family, customer demo tenants under the main domain, a developer estate, and a public Confluence. The brief was simple: find what an attacker sees before they touch a login.

That last part matters. Most audits start at the front door — login pages, forms, application logic. This one started at the public register: certificate transparency. Everything below was collected without authentication, without exploitation, and without sending a single request to the customer tenants.

I removed all identifying information. The target is described by sector and technology class. Customer names, employee names, hostnames and credentials do not appear in this article.

The pattern

Certificate transparency is a customer list

Every TLS certificate is logged publicly. That is the point of CT: you can verify which certificates exist for a domain. The side effect is that hostnames become a public inventory — and in a multi-tenant business, hostnames are customer names.

The estate contained 340 CT entries for the main domain. Grouping them by tenant family produced:

  • 194 tenant hostnames
  • 68 distinct customer brands
  • 40 hosts that still resolve today
  • production, demo and QA families that are trivially distinguishable by name

The same logs also named the delivery toolchain — GitLab, Harbor, Nexus, SonarQube, ReportPortal, Testrail — and the environments around them. A competitor, a fraudster or a supplier can read this without touching the company. There is no alert for reading a public register.

A hidden login does not hide the staff

The WordPress login was hidden well: wp-login.php and /wp-admin/ redirected to a 404 page, XML-RPC returned 403, uploads were not listable. That is better than most.

Then I asked the REST API for the user list. It returned 12 accounts with names, and the administrator's profile description contained a real name. Two more paths — oEmbed and the ?author=1 redirect — returned the same directory. The login was hidden; the workforce was not.

CORS with credentials turns the API into a cross-site surface

The REST API reflected any Origin back in Access-Control-Allow-Origin while sending Access-Control-Allow-Credentials: true. It did the same for Origin: null, which covers sandboxed iframes and local files, and it was reachable both via /wp-json/ and the ?rest_route= alias.

WordPress nonces limit the practical blast radius, so I did not rate this as remote code execution. But the configuration is wrong in a way that multiplies every other problem: any website a logged-in employee visits can issue credentialed requests to the company's own API.

Mail trust was split, and one half was missing

The primary domain published no DMARC record — NXDOMAIN on two public resolvers. The secondary domain published p=none, reported to a third party, and its SPF authorised a shared agency host plus two server IPs. For a supplier into industrial customers, that is the realistic money path: a forged invoice or bank-detail change from the real domain, with no policy telling the recipient to distrust it.

TLS trust broke exactly where customers look

Two customer-facing demo hosts had no usable TLS:

  • one presented a self-signed CA from 2007 using SHA-1, with a 20-year leaf certificate;
  • the other served a certificate for an unrelated external domain, producing ERR_CERT_COMMON_NAME_INVALID;
  • both answered on plain HTTP with nginx/1.28.3 and PHP/8.5.5 in the headers.

Browsers show a full-page warning. Some users click through. Others fall back to HTTP. Both behaviours are trained on pages that look like the product.

The product portal published its own map

The portal's CSP allowed 'unsafe-eval', trusted whole wildcard subdomain families, loaded a jsDelivr path without SRI and set child-src *. The policy also named 42 customer and partner domains — a second customer list, this time in a response header.

Its public config.js added 40+ internal and customer-facing endpoints, feature flags for unreleased products, an Azure Function lookup, a Novu app id and a publish-to-web Power BI URL. Rendered in a browser, without login, the report showed service-case volume, reaction and resolution times, failure priorities and the connected/unconnected fleet split.

The least glamorous findings were the useful ones

A public Confluence sandbox held 142 pages, including a work log with 165 revisions, internal migration to-dos and draft links. The WordPress media API exposed 538 items and 32 documents, including an unattached 2024 participant list as an XLSX. A hosting panel (Froxlor) answered on a public host, and three login apps (tpm, smtpgui, transfer.it) set session cookies without Secure, HttpOnly or SameSite — one of them also sent an invalid X-Frame-Options: ALLOW-FROM and a malformed Referrer-Policy.

None of that is an exploit. All of it is material for one.

TL;DR: A manufacturer asked for a web audit and got a lesson in publishing: certificate transparency named 68 customer brands across 194 tenant hostnames, the primary domain had no DMARC policy, the WordPress API reflected any origin with credentials, and a public Power BI report showed live service KPIs. The lab then proved which POST surfaces were actually open — and which only looked open.

Findings

The full set: 24 findings — 2 high, 14 medium, 6 low, 2 info. No exploitable 2026 CVE matched the observed versions.

SeverityFindingWhy it matters
HIGHCustomer list in certificate transparency — 68 brands, 194 tenant hosts, 40 resolving, plus the delivery mapCommercial intelligence and targeting material without a single request to the target
HIGHNo DMARC on the primary domain — .de only p=none, SPF authorises a shared agency hostForged invoices and bank-detail changes stay deliverable under the real name
MEDIUMCORS with credentials on /wp-json/ and ?rest_route= — any origin, including nullAny visited site can issue credentialed API requests from a logged-in browser
MEDIUMStaff enumeration — 12 accounts via REST, oEmbed and ?author=1, admin real name in the descriptionSpear phishing and credential stuffing start with a real name
MEDIUMCustomer demo hosts with broken TLS — 2007 SHA-1 self-signed CA, 20-year leaf; foreign certificate; HTTP fallbackBrowser warnings at the exact place customers expect a product
MEDIUMPortal CSP — unsafe-eval, wildcard subdomains, jsDelivr without SRI, child-src *, no frame-ancestorsA script injection anywhere in the portal runs at full effect
MEDIUM42 customer/partner domains in the CSPA second customer list in a public response header
MEDIUMPublic config.js — 40+ endpoints, feature flags, Azure lookup, Novu idThe full product and integration map, cacheable for a year
MEDIUMPublic Power BI report — service-case KPIs, priorities, fleet splitOperational performance data visible to competitors and customers
MEDIUMGrafana 13.1.0 public — /metrics 768 KB without auth, /login without XFO/CSP, patch lagMetrics reveal rhythms; the version selects the exploit
MEDIUMWordPress hardening gaps — no HSTS, no CSP, no Permissions-Policy; version leaks; 516 REST routesNo second line of defence, and the version map is free
MEDIUMConfluence sandbox public — 142 pages, work log, migration to-dosInternal process and release cadence become readable
MEDIUMParticipant list XLSX via the open media APIPersonal data for targeted social engineering
MEDIUMFroxlor hosting panel public + three login apps with missing cookie flagsCredential stuffing target; one hit means hosting, mail or files
MEDIUMJitsi build 8206 (2022/23) vs 11248 (2026), no token authAn old edge on a meeting service is a perfect phishing pretext
MEDIUMSonarQube 26.1.0 vs 26.10.0Nine monthly releases behind, version public
LOWDev/infra metadata — Nexus 3.96.3-01, registry proxy catalogue, Harbor systeminfoExact versions for exploit selection; no private repositories exposed
LOWHygiene bundle — no security.txt, no CAA, HSTS preload claim not listed, Fluent Forms one patch behindSmall gaps that compound
LOWDev storage in production — privacy policy and BIMI logo on a dev account; dev host in the CSPIf the dev account is retired or compromised, production legal assets change
LOWSynapse 1.161/1.162 vs 1.163.0, public admin version endpointVersion leak plus an admin endpoint without auth
LOWAuth0 legacy grants — implicit and password enabled; login page itself hardenedLarger attack surface; the login page is a genuine plus
LOWAzure lookup function — constant organisation id for every addressNo user enumeration observed; write path untested
INFODetection vacuum — no WAF/rate limit across 171 requests; later a silent TCP blackholeDetection is network-level and silent, not application-level
INFOPublic demo apps and a test page — no data, extra surfaceHygiene and attack surface
Public CT logsCustomer listDelivery mapOpen REST APIStaff listTargeted phishingNo DMARCSpoofed supplier mailInvoice fraudLookalike subdomainsEdge patch lagExploit selection

The lab: which POST surfaces were actually open

This is where the audit changed shape. The live WordPress origin started silently dropping my egress after roughly 200 read-only requests — no 429, no 403, just TCP timeouts while an independent fetch from another network returned 200. That is a detection control, and it meant the POST surfaces could not be tested against production.

So I rebuilt the stack in an isolated lab: WordPress 7.1.3, Novamira 1.9.2, SEOPress 10.3, Fluent Forms 6.2.16, MCP Adapter 0.7.1. Then I tested every endpoint that looked dangerous.

SurfaceLab resultVerdict
Novamira POST /upload401 missing token; 401 forged signature; 200 only with a valid HMAC tokenToken-gated — no anonymous upload
Novamira POST /admin-access401 without one-time token and nonceNo anonymous admin access
SEOPress MCP POST /register201 with client id and secretOpen dynamic client registration, by design
SEOPress MCP POST /token401 without a registered clientNo anonymous token
SEOPress MCP authorizePKCE S256 required; explicit consent screen showing client, redirect URI and accountNo auto-approve; residual consent-phishing risk
Fluent Forms submit200 and an entry created without a nonceSpam surface — no upload fields on the target form
MCP Adapter / Abilities401Correctly closed
Power BIsingle-page report; no hidden pagesThe one page is the exposure
Azure lookupconstant organisation id for every addressNot user enumeration

The lesson is not "the plugins are unsafe". It is that a public route is not the same thing as an open route. Two of the scariest-looking endpoints were token- and consent-gated; one boring form endpoint accepted anonymous writes. You cannot tell which is which from the route list.

What I got wrong

Three claims did not survive verification, and I removed them:

  1. A certificate "mismatch" on the whiteboard host. The CN differed, but the SAN included the host. Browser and curl accepted it. CN is not the check; SAN is.
  2. A JWT in the portal config. It was the public jwt.io demo token, not a credential.
  3. A public Docker registry catalogue. It was a pull-through cache of public upstream images — no private repositories.
  4. The Azure lookup function. It returned the same organisation id for every address, so it was not user enumeration. The write path remained untested.

Four false positives removed before disclosure. That is the job: the finding you do not publish is as important as the one you do.

What the defender should take away

  • Treat CT as a publication channel. Customer names in hostnames are convenient and permanent. Opaque tenant identifiers or wildcard certificates remove the list; monitoring CT tells you what you have already published.
  • Publish DMARC and enforce it. A primary domain with no policy is a spoofing surface with your name on it.
  • CORS is a policy, not a default. Reflect only the origins you own, never with credentials, and test both route shapes.
  • A hidden login is not a hidden directory. Lock the users endpoint, oEmbed and author redirects, or accept that the staff list is public.
  • Dashboards are data. A publish-to-web link in a config is a data release; render it before you ship it.
  • Pin what you load. unsafe-eval, wildcard subdomains and unversioned CDN paths turn every other bug into a bigger one.
  • Test the POST surfaces in a lab. A route list tells you what exists, not what is protected.

Closing

The most valuable data in this audit was not behind a login. It was in a public register, a public config and a public dashboard — three places nobody thinks of as "the perimeter".

The login page was fine. The register was not.

Once an attacker gains access, they can perform the following actions:

Harvest the customer list from public certificate logs: 68 brands, 194 tenant hosts, 40 live. No request to the target, no alert, no trace.
Send forged invoices or bank-change requests from the primary domain — it has no DMARC policy at all, so nothing tells the recipient to distrust them.
Read the public Power BI report for support volume, reaction/resolution times, failure priorities and the connected/unconnected fleet split.
Download the 2024 participant list (XLSX) through the open media API — personal data for targeted social engineering against industry decision-makers.
Use the reflected CORS origin and the 12-account staff list to probe the WordPress API from any visited website and to build credible phishing.
Exploit the patch lag on the edge: Grafana 13.1.0, Jitsi build 8206, SonarQube 26.1, Synapse 1.161/1.162 — each with public version disclosure.
Try credential stuffing against the exposed hosting panel and the three login apps with missing cookie flags — one hit means hosting, mail or file access.

All identifiers removed. No customer systems were accessed, no credentials were used, and no exploitation was performed. The lab mirror is isolated and synthetic.

Shady Nathan Tawfik

Founder & Cyber IT Security Engineer in Bielefeld. Offensive security, audits and full-stack builds. More at

For educational purposes only. Every reproducible command targets my own lab environment (localhost), never a live system. © 2026