Research Article

Broadcast, Not Stolen: How Passwords and Customer Records Reach Third Parties by Default

Passwords and personal data don’t have to be stolen to end up somewhere they shouldn’t. When an application writes them into a URL or a page title, ordinary analytics, monitoring, and fraud tools collect them by default. A Klaviyo sign-up form with no method attribute sent our test password to 31 third-party hostnames – the same omission we measured on 7,874 websites with credential- or PII-bearing forms across the top 100,000 websites

Research Article

MELURNA tracks how sensitive information moves through web applications and into third-party systems. During recent research, we reviewed a Klaviyo sign-up session that we had recorded using our own test account and credentials.

We found that Klaviyo’s sign-up form (klaviyo.com/sign-up) did not specify a method attribute. In our browser session, we discovered our test password, email, company name, telephone number, and website address were placed into the page URL. That credential-bearing URL was then transmitted to 31 third-party hostnames. Four of those hostnames returned the test-password value in their responses, confirming that they received and processed it.

Deeper testing of our own Klaviyo account revealed a separate data flow. During our CRM activity, simply viewing or creating a customer profile placed that customer’s name, email address, and profile identifier into the page URL and document title. Third-party tags then read those values and transmitted them to third-party hostnames associated with Sift Science, Gainsight PX, Google Analytics, Sentry, and Statsig. We observed this across three test profiles.

Executive summary

  • We identified two separate data-flow weaknesses during controlled testing of Klaviyo using our own test account, credentials, and test customer profiles.
  • During our user-initiated Klaviyo account registration on klaviyo.com/sign-up, a sign-up form without an explicit method form attribute, serialized our registration data into the URL and transmitted our test password, email address, phone number, company name, and website to 31 third-party hostnames. Four of the third-party hostnames returned our password value in their responses, confirming that those endpoints received and processed it.
  • In our measurement of the broader prevalence, we analyzed the top 100,000 websites and identified 7,874 credential- or PII-bearing forms without an explicit method attribute. Missing method alone does not prove a live leak, but it creates a native GET fallback that can serialize sensitive fields into the URL when JavaScript does not intercept submission.
  • Klaviyo’s /login form contained the same structural omission, however we were able to reproduce URL serialization only after intentionally interrupting the page’s JavaScript. We therefore assess the practical exposure risk of the /login variant as lower than /sign-up.
  • In a third Klaviyo finding, simply viewing or creating our test Klaviyo contact profiles caused names, email addresses, or profile identifiers to be transmitted to services associated with Sift Science (hexagon-analytics.com), Gainsight PX, Google Analytics, Sentry, or Statsig.
  • Together, the findings show a broader cyber and privacy data-supply-chain risk: when passwords or personal information enter URLs or page titles, legitimate telemetry tools can carry that information beyond the application that originally collected it.
  • MELURNA responsibly disclosed the findings to Klaviyo. Klaviyo investigated the reports and remediated the affected behavior before publication.
  • Organizations can reduce this class of risk by explicitly configuring forms to use a POST method, preventing secrets and personal information from entering URLs and page titles, and sanitizing data before telemetry tools collect it.

Why Klaviyo matters

Klaviyo’s scale makes it an important case study. If you shop online, there’s a chance your personal data – including your name and email address – sits on Klaviyo. The company says its B2C customer relationship management platform processes 8 billion profiles. As of July 18, 2026, BuiltWith reported that 635,022 websites were using Klaviyo. A July 2026 BuiltWith.com query for websites using Klaviyo returned domains across categories including online retailers, sexual-health services, GLP-1 providers, suicide-prevention nonprofits, firearms retailers, adult and LGBTQ+ brands, and children’s gaming and learning platforms.

How we tested

We conducted the research via a Klaviyo test account we created ourselves, using our own data and our own credentials, on our own device. We browsed the product and recorded the network traffic of our own session using Burp Suite, a widely used web security tool that we configured only to passively observe traffic. We did not modify any request. We did not access, attempt to access, or retain any other user’s data. We did not test against any account other than our own.

We first captured the sign-up session on September 18, 2025 as part of broader research into third-party data flows. We identified the credential exposure during a review and disclosed it to Klaviyo after confirming the evidence. We conducted the customer-profile testing in July 2026, again within our own account and using test contact profiles we created ourselves.

The report proceeds in two parts. Part I examines the missing-method form pattern through the Klaviyo sign-up and login findings, then places that pattern in the context of our broader web analysis. Part II examines the separate customer-profile telemetry finding.

Part I: Methodless forms and credential transmission

Finding 1: A credential exposure to 31 third-party hostnames on the Klaviyo /sign-up page

How it started

In fall 2025, while researching how user data flows through web products and into third-party systems, we recorded a browser session in which we created our own Klaviyo account through klaviyo.com/sign-up. When we later analyzed that session, we found our test password, email address, phone number, company name, and company website in traffic associated with 31 third-party hostnames, including services operated by Spotify, HubSpot, 6sense, LinkedIn, Heap Analytics, and Meta. Four third-party hostnames returned our test-password value in their response bodies, confirming that those endpoints received and processed it.

The root cause: a form with no method attribute

During our captured session, Klaviyo’s sign-up page rendered a credential-bearing form declared like this:

<form action="#" id="form--signup">

The form contained named fields including email, password1, company, company_website, and phone.

Two important details. First, there was no method attribute. In HTML, a form with no method attribute defaults to GET. Second, the action is #, which resolves to the current page.

The form is intended to be handled by JavaScript, which validates the input and sends it to Klaviyo in the body of an HTTP POST request. That is the safe path, and in normal operation it is the path that runs. The problem is the fallback. If the browser ever performs a native submission of this form, before or instead of the JavaScript handler, it uses the defaults: an HTTP GET to the current page, with every named field serialized into the URL query string. A GET submission of a login or sign-up form places the password in the URL.

In our session, that is exactly what we observed. The credential values appeared in a top-level navigation to the sign-up page, of the following shape (values redacted):

GET /sign-up?email=<redacted>&password1=<redacted>&company=<redacted>&company_website=<redacted>&phone=<redacted>... HTTP/2
Host: www.klaviyo.com
Referer: https://www.klaviyo.com/sign-up
Redacted request evidence showing the Klaviyo sign-up credential transmission

Figure 1. Burp Suite filtered for our unique test-password value, which has been redacted. The credential-bearing signup URL appeared in the request to dx.mountain.com and was also embedded in the endpoint’s response. The test email, password, company name, website, phone number, URLs, and other identifying values have also been redacted.

This was a real user submission (not a scanner)

A native GET submission of a JavaScript-driven form only happens when the submit handler does not intercept the submit event. There are three ways that can occur: JavaScript is disabled, the form is submitted before the page’s JavaScript has hydrated (a race), or a script error prevents the handler from attaching. We examined our capture against all three, because the distinction between an exotic edge case and a genuine user flow is the heart of this finding.

JavaScript was enabled and running. The session executed extensive JavaScript throughout. Google Tag Manager, GA4, the Meta Pixel, Heap, ContentSquare, reCAPTCHA, and Sentry all ran. This was not a scripting-disabled environment.

A pre-hydration race does not explain this submission. The sign-up page loaded at 08:15:33 GMT, and its JavaScript bundles downloaded within roughly two seconds. The native GET submission did not occur until 08:22:31 GMT, about seven minutes later. A submission arriving seven minutes after the scripts loaded did not beat the JavaScript.

There was no script error. Sentry error monitoring was active and reporting for the entire session. Across every Sentry event we captured, we observed no exception events or error-level events. A JavaScript error that prevented the submit handler from attaching would ordinarily surface in Sentry. None did.

What the capture does show is a genuine, user-initiated submission on a fully loaded page. The native GET request carried Sec-Fetch-User: ?1, the browser signal for a user-activated action, along with Sec-Fetch-Mode: navigate and Sec-Fetch-Dest: document, the signals of a top-level document navigation. These are the fingerprints of a person clicking, not of a crawler issuing bare requests. The request occurred on a standard Chrome profile with no ad blockers or content blockers, and Burp Suite was used only to observe.

We can also characterize why the JavaScript handler was not in control for this form. In our capture, the page’s core JavaScript loaded, but the sign-up route’s page data was never requested before the submission. It was first fetched only after the native GET had already occurred. In other words, the form was present and natively submittable before the route that would have wired up its handler was ready. That is the fallback firing in a real session, not a contrived test.

Where the credentials went

Because the credential values were in the page URL, that URL was available to the many third-party scripts the sign-up page loaded, through ordinary web mechanisms: the Referer header sent with subsequent requests, analytics payloads, and pixel URLs.

We filtered our captured traffic for the unique test password we had chosen and found it associated with 36 distinct hostnames, 31 of which appear to be third-party hostnames other than Klaviyo. We want to draw a careful line here between transmission and confirmed receipt. For most of these hostnames, what we observed is that the credential-bearing URL was transmitted toward them. For several, we observed the password reflected back inside the third party’s own response body. A value that appears in a response body was received and processed by that party, not merely sent in its direction. Those directly confirmed recipients are marked with an asterisk below.

The recipients, grouped by category, included:

  • Advertising platforms: Facebook, Google (*googleads.g.doubleclick.net, *www.googleadservices.com, *11549644.fls.doubleclick.net), LinkedIn, The Trade Desk, Bing, Pinterest, Spotify, Twitter/X, HubSpot, MNTN (*dx.mountain.com), TVSquared
  • Analytics tools: ContentSquare, Heap Analytics, Hexagon Analytics, G2
  • Marketing and intent data: 6sense, Demandbase, Intentsify, Qualified (via WebSocket)
  • Customer data platform: Optimizely/Zaius
  • Error monitoring: Sentry
  • CDN edge: Netlify

* marks hostnames that reflected the password in a response body, which is our strongest evidence of receipt. See Figure 1.

In one case, the credential arrived at a third party inside the Referer header rather than the query string, which is the same class of leak by a different channel.

One further detail is worth noting for accuracy. Where we observed the password in a Google advertising response body, it appeared double URL-encoded. A password containing characters such as @, !, and # is encoded once when placed in a URL and again when that URL is itself carried as a parameter, so a raw value like Example@1234Word! becomes Example%401234Word%21 after one pass and Example%25401234Word%2521 after two. We mention this only to be transparent about how the value appeared in the evidence.

Transport encryption and third-party exposure

It is fair to note that this traffic travels over TLS. TLS is important, and it does protect the data from a passive network eavesdropper sitting between the browser and each server.

TLS does not, however, address the concern here. The concern is not an eavesdropper on the wire. It is that the credential was delivered, over those encrypted connections, to third parties who were never supposed to receive it, and in several cases we watched those third parties echo it back in their responses. Encryption in transit does not prevent Google, Meta, LinkedIn, and the other recipients from receiving, processing, or logging a credential that was placed in a URL and sent to them. Once a password reaches a third party’s servers and enters its logs or telemetry, the protection of the transport layer has already done its job and ended.

How long the form was in this state

To understand the exposure window without touching Klaviyo’s systems, we used Common Crawl, an independent public web archive. Common Crawl periodically captures the raw HTML that a server returned, so its stored records let us observe the actual form markup Klaviyo served on specific historical dates. Everything below is an inference from those public archives, and we would welcome Klaviyo’s confirmation from its own deployment history.

Common Crawl’s stored records show the single-screen sign-up form, with no method attribute and action=”#”, present on sampled dates from February 26, 2024 through at least November 10, 2025. Anyone can retrieve the exact archived record we reviewed:

curl -s -H "Range: bytes=830141671-830173002" 
"https://data.commoncrawl.org/crawl-data/CC-MAIN-2024-10/segments/1707947474663.47/warc/CC-MAIN-20240226194006-20240226224006-00185.warc.gz" 
| gzip -dc

The output is a single-screen sign-up form with no method attribute, an action of #, a password field named password1, and a submit-capable control, with no multi-step components.

Two boundaries are worth stating, because they set the limits of what the public record can and cannot prove:

  • The earliest observable date is a lower bound, not a start date. February 26, 2024 is simply the earliest date on which we can directly observe the vulnerable form in Common Crawl. Common Crawl holds Klaviyo homepage snapshots back to 2019, so the February 2024 date is not a limit of coverage. For the /sign-up path, the earliest captures are from 2020, and they show a different, non-vulnerable form that specified method=”POST” and posted to /ajax/register. A native submission of that 2020 form would have placed credentials in the request body, not the URL. The vulnerable configuration was therefore introduced during a later rebuild. Common Crawl did not capture /sign-up between 2021 and 2023, so the exact date the vulnerable form was introduced, sometime between 2020 and February 2024, cannot be determined from the public record.
  • The form later changed in a way that resolves the exposure. Our review indicates the form changed to a multi-step format sometime between November 10 and December 16, 2025. In that stepped form, the advance control is a type=”button” (JavaScript-driven) and there is no type=”submit” control, so there is no native-submission trigger for the browser to fire. Account creation is handled entirely by a background POST /ajax/register request, with the password in the request body. Prior to disclosure, a browser session confirmed the current behavior: no GET /sign-up request carried a query string, no navigation carried any credential, and the password was sent only to first-party Klaviyo endpoints.

We note one caveat about the pre-disclosure fix. Because the method attribute was still absent, the resolution is behavioral rather than structural. It holds as long as the form contains no submit-capable control on a step that includes the password field. Klaviyo has now remediated the form and introduced the method attribute, specifying method="post".

How common are missing-method forms?

The Klaviyo sign-up event demonstrated what can happen when a browser falls back to native form submission. A broader question however: how often do credential- and PII-bearing forms omit the method attribute that makes this fallback possible?

We analyzed the top 100,000 domains using static analysis and headless-browser rendering.

ClassificationTop 100,000
Password form, missing method3,077 (3.08%)
Any missing-method credential or PII form7,874 (7.87%)

These counts measure the prevalence of risky markup, not the prevalence of confirmed leaks. A form without an explicit method defaults to GET, but JavaScript may still intercept the submission and send the data safely in a POST body.

Our analysis measured structural exposure rather than confirmed real-world leakage. Klaviyo’s /login page shows why that distinction matters.

Finding 2: The lower risk Klaviyo /login form variant

After our initial disclosure, we observed that the form on Klaviyo’s /login is also served without a method attribute. The practical risk there is lower, because /login is rendered client-side. If its JavaScript does not run, the form generally does not render at all, so there is usually nothing to submit, and the exposed window is much smaller. It is not necessarily zero, because the native-submit path remains reachable through handler exceptions and edge cases. Consistent with that, we could reproduce URL serialization on /login only by intentionally interrupting JavaScript in the browser console, after which our credentials appeared in the URL through a password= parameter. This differs from /sign-up, which was server-rendered and natively submittable before and independent of hydration, and where the exposure occurred without any intervention on our part. We share this so the pattern is understood, not to overstate the login risk.

Part II: Profile telemetry and customer identity

Finding 3: Klaviyo customer-profile data transmitted to third-parties during ordinary CRM

Klaviyo customers, often retailers and other consumer-facing businesses, use the platform to create and manage profiles of their own customers and prospects. Depending on how the account is configured, those profiles may include names, email addresses, phone numbers, purchase history, browsing activity, marketing interactions, and predicted attributes. The business using Klaviyo decides why and how that information is used, while Klaviyo processes it to provide the platform.

This distinction matters to our findings. Findings 1 and 2 concern the credentials and identity associated with our own Klaviyo account. Finding 3 concerns the personal information contained in the test contact profiles we created inside our test account. In Klaviyo’s own terms this is Customer Data, for which the Klaviyo customer is the controller and Klaviyo is the processor. Klaviyo’s privacy notice states that it processes such Customer Data on behalf and under the instruction of the respective customer, and that the notice itself does not apply to it.

Finding 3’s behavior does not depend on any JavaScript failure or native-submission fallback. It occurs on a fully loaded, fully working page during ordinary use of the product.

What we observed

When a logged-in Klaviyo user creates a contact (Klaviyo CRM → click Audience, then add profile) or opens and browses an existing contact at /profile/, the contact’s identifying data is transmitted to several third-party services. We observed two triggers. Immediately after we added a new profile, the new contact’s data was sent to third parties. Viewing an existing profile and navigating within it, for example to its Campaigns subtab, caused subsequent outbound requests to continue carrying that contact’s data. The exposure recurs on ordinary reads and navigation, not only when a record is created or updated. All test profiles we created produced the same behavior.

Root cause

When the application renders a contact, its single-page front end writes the contact’s identifying data into two page-level surfaces that analytics and monitoring SDKs read automatically on every route change: the document title and the page URL. On the profile overview, the browser tab title becomes the contact’s email address followed by ” | Klaviyo.” On subtabs, it becomes the contact’s first and last name followed by ” | Klaviyo.” The URL carries the profile’s identifier (/profile/). Because page-view tracking, DOM-capture, device-fingerprinting, and performance-tracing SDKs read the document title and URL by default, each navigation to or within a contact profile emits requests carrying that contact’s personal information to the third-parties’ own servers. Several of those requests are plaintext GET requests in which the data sits in the URL query string, so, as with Finding 1, the values also propagate into server, proxy, and CDN access logs and into referrer chains.

This is not a novel failure mode. The same title-and-URL capture channel is what browser extensions exploit. Our founder documented it at scale in the 2019 DataSpii investigation, in which EHR platforms placed patient names in page titles that extensions then collected and disseminated to third parties. Anything an application writes into a page title or URL should be treated as data that can leave the page.

Where the data went

We confirmed the contact’s values directly in the requests sent to the following hosts. The values appeared in the request URL or body, not by inference alone.

  • Sift (hexagon-analytics.com). Receives the contact’s email address, first name, last name, or profile identifier. The domain’s WHOIS registrant is Sift Science, Inc., a fraud- and abuse-prevention provider. The data is sent as a plaintext GET pixel of the form GET /images/485104.gif?…&t=<contact email>%20%7C%20Klaviyo&u=<profile URL>&rf=…, where the t parameter (the browser tab title) decodes to the contact’s email address followed by ” | Klaviyo,” and u is the profile URL. Neither “Sift” nor hexagon-analytics.com appears in Klaviyo’s public cookie notice or on Klaviyo’s published sub-processor list. Fraud and abuse prevention can be a legitimate processor function, and we do not dispute Klaviyo’s use of anti-fraud tooling.
  • Gainsight PX (esp.aptrinsic.com). Receives the contact’s email, first name, last name, or profile identifier, both as URL parameters (pt= for the page title, pa= for the path) and inside full DOM snapshots of the rendered page posted in the request body. The DOM snapshots we observed included both individual profile pages and multi-contact table views, for example the suppressed-profiles list, whose snapshot contained a contact’s profile link. Because this mechanism captures whatever the page renders, any Customer Data displayed on a profile, not only the name in the title, is within scope of that capture.
  • Google Analytics (analytics.google.com and www.google-analytics.com). Receives the contact’s email and profile identifier via the standard GA4 parameters dt (document title, containing the contact’s email followed by ” | Klaviyo”) and dl (document location, the profile URL). Transmitting a plaintext email address to Google Analytics appears inconsistent with Google’s Measurement Protocol and Analytics terms, which prohibit sending personally identifiable information.
  • Sentry (o19233.ingest.sentry.io). Receives the contact’s first name, last name, or profile identifier, carried inside captured performance-trace spans whose descriptions embed the other trackers’ URLs, which themselves contain the page title and profile path, and in transaction context.
  • Statsig (prodregistryv2.org). Receives the profile identifier via a currentPage field in its event payload.
  • Statsig (prodregistryv2.org and featureassets.org). Requests sent to prodregistryv2.org included the contact’s profile identifier. Those same request batches also carried our test Klaviyo account’s company name (the merchant). We did not observe a contact-profile name in the featureassets.org requests.
Redacted Google Analytics request from a Klaviyo test customer profile

Figure 2. Google Analytics request observed while accessing a test customer profile. The request contained a transformed version of the test end-customer email in the em parameter, the profile identifier in dl, and the test end-customer email in dt. Sensitive values have been redacted.

Measured against Klaviyo’s own terms

We compared these transmissions to Klaviyo’s published disclosures. Klaviyo’s sub-processor list names Sentry (Functional Software, Inc.) and Statsig, Inc. It does not name Sift, Gainsight (Aptrinsic), or Google Analytics. Under Klaviyo’s Data Processing Agreement, Klaviyo acts as a processor or sub-processor of Customer Personal Data (Clause 3.1), that data is to be processed only on behalf of and under the instructions of the customer (Clause 4.2), and each sub-processor must be bound by a written agreement imposing data-protection obligations no less protective (Clause 5.2). That same agreement defines Customer Personal Data as data Klaviyo processes on behalf of the customer, and it excludes Account Information such as the account holder’s own credentials, which is the category implicated by our first two findings. Sending a contact’s name and email address to Sift, Gainsight, and Google Analytics, none of which is named as a sub-processor, raises the question of whether those flows are covered by the agreement.

Why this matters

These third-party recipients serve different purposes: product analytics, web analytics, fraud prevention, error monitoring, and experimentation. Some of those purposes can be legitimate. The problem is common to all of them. None of these services needs the contact’s email or name to do its job, yet each receives it, because the application places Customer Data into the page title and URL, which these SDKs capture by default. The contacts have no relationship with any of these vendors. The value that is transmitted is the key. As described earlier, a Klaviyo profile can be tied to that person’s purchase history down to the item, their browsing and search behavior, their location, and Klaviyo’s own predictions about them. The email address and profile identifier are the identifiers that link an outside record back to that profile. Identified contact records now persist in multiple third-party systems, which creates retention and deletion obligations at each recipient, and the mechanism applies to any contact an operator opens or creates. It is not specific to our test data. For the many Klaviyo customers in sensitive categories, the transmitted value is not merely an identity. It can support a sensitive inference about the person behind it.

How this could have been prevented

We include this section for the engineers and product teams who build flows like these, at Klaviyo and elsewhere, because the same two habits would have prevented all three findings:

Give every credential-bearing form an explicit method="post", and do not rely on submission defaults. The sign-up and login findings come from the same omission. A form served without a method attribute defaults to GET, and a native submission then serializes the fields, including the password, into the URL. Setting method=”post” makes the safe behavior structural rather than dependent on JavaScript running at the right moment. With method=”post”, even a native fallback submission places the fields in the request body, not the URL, so a slow or interrupted script can no longer turn a password field into a query-string parameter. Avoiding action=”#” on sensitive forms removes the same-page navigation that carries the values into the address bar. This single attribute would have closed Findings 1 and 2.

Never place personal data or credentials in a page title or a URL. The contact-data finding comes from a different habit. The application writes an end-customer’s name or email address into the browser tab title and the page URL. A page title and a URL are not private surfaces. Most analytics, monitoring, session-replay, and device-fingerprinting scripts read them by default, and so can browser extensions the user may have installed. Keeping identifiers out of those surfaces, for example by using a non-identifying tab title such as “Contact | Klaviyo” and a path that does not embed the value, removes the data from the channel before any third party can collect it.

The browser-extension half of that risk is neither theoretical nor new. In 2019, our founder published DataSpii, an investigation that found eight browser extensions collecting the URLs and page titles of every page their users visited and forwarding that stream to a data broker that resold it. Because some applications embedded sensitive values in those titles and URLs, the collected data included real personal or corporate information. EHR platforms were among those affected as were top cyber-firms that leaked their enterprise customer data. One EHR exposed patient names, physician names, and listed medications, and another exposed patient names, in both cases because the application had placed the patient’s name in the page title where the extensions could read it. The behavior in Finding 3 is the pattern DataSpii documented, reaching a different set of collectors. The defense is the same. Treat the page title and the URL as data that will leave the page, and never put anything sensitive there.

Klaviyo’s response, and our assessment

During disclosure, Klaviyo confirmed that the finding is valid, that it represents a real risk, and that the issue has been addressed. Klaviyo characterized the behavior as occurring only when the expected JavaScript flow does not run, for example under poor connectivity, certain browser extensions, or automated testing tools.

We agree on the root cause, which is not in dispute: a credential-bearing form served without a method attribute defaults to a native GET submission that serializes the fields into the URL. That is the condition Klaviyo has now addressed.

We asked Klaviyo several clarifying questions, including whether it searched historical access and edge logs for credential-bearing sign-up URLs, whether any production registrations were affected, when the method-less form was introduced, and whether it plans to notify potentially affected users. We shared sections of this writeup for factual review, and we invited an on-the-record statement. Klaviyo was informed of our publication timeline for this report and did not object to it.

Disclosure timeline

DateEvent
September 18, 2025MELURNA captured the self-owned Klaviyo sign-up session during broader research.
February 26, 2024 to November 10, 2025Vulnerable single-screen sign-up form observable in Common Crawl (window is a lower bound).
Between November 10 and December 16, 2025Sign-up form changed to a multi-step design, behaviorally resolving the exposure.
June 19, 2026MELURNA disclosed the sign-up finding to Klaviyo’s Privacy and Security team. Klaviyo acknowledged receipt.
July 1, 2026Klaviyo responded, confirmed the finding is valid and addressed, and shared its assessment.
July 8, 2026MELURNA responded with evidence and clarifying questions.
July 12, 2026MELURNA shared the /login form finding.
July 16, 2026MELURNA disclosed Finding 3, the contact-data finding to Klaviyo’s Privacy and Security team.
August 7, 2026Klaviyo confirms our findings have been remediated.
August 10, 2026MELURNA published this report.

Appendix: Evidence tables

Appendix Table A1. Location of our password across the 36 observed hostnames in the September 18, 2025 sign-up capture (35 hostnames in the HTTP capture, plus ws4.qualified.com observed in a client-to-server WebSocket message). For each hostname, the table shows where our password value was observed: in the request URL or query line, request headers (for example, Referer), request body, response headers, or response body, aggregated across all requests to that host. Party: 1P = Klaviyo first-party host, 3P = third-party host. “Yes” indicates the value was present in that location for at least one request; a hyphen indicates it was not observed there.

HostnamePartyReq URLReq HdrsReq BodyResp HdrsResp Body
www.klaviyo.com1PYesYesYes
heapanalytics.com3PYes
googleads.g.doubleclick.net3PYesYesYes
www.googleadservices.com3PYesYes
www.google.com3PYes
www.facebook.com3PYesYes
px.ads.linkedin.com3PYes
b.6sc.co3PYes
analytics.google.com3PYesYes
ad.doubleclick.net3PYesYes
11549644.fls.doubleclick.net3PYesYesYes
api.zaius.com3PYes
insight.adsrvr.org3PYesYes
static.klaviyo.com1PYes
hexagon-analytics.com3PYes
adservice.google.com3PYes
static-app.klaviyo.com1PYes
track.hubspot.com3PYes
o19233.ingest.sentry.io3PYes
dx.mountain.com3PYesYes
t.co3PYes
analytics.twitter.com3PYes
bite.australiarevival.com3PYes
bat.bing.com3PYes
paapi517.d41.co3PYes
api.company-target.com3PYes
pixels.spotify.com3PYes
collector-51975.us.tvsquared.com3PYes
px.mountain.com3PYes
tracking.intentsify.io3PYes
ct.pinterest.com3PYes
68cbbc2dd42d1400087e16af–klaviyo-marketing-site-us.netlify.app1PYes
tracking.g2crowd.com3PYes
k-us1.az.contentsquare.net3PYes
atlas-notifications.services.klaviyo.com1PYes
ws4.qualified.com3PYes*

* ws4.qualified.com was observed in a client-to-server WebSocket message (the record_page_view url field), which carried the full sign-up URL including the password. We record it under Request Body as the closest equivalent. Of the 36 hostnames, 31 are third parties.


Appendix Table A2. End-customer (contact) data across the hosts observed in the July 16 to 17, 2026 profile-viewing capture. For each host, the table shows whether our test contact’s identity (email, first name, last name, or profile identifier) was observed in the request URL or request body, and whether our own operator account identifiers, the test company name and our login email, were also transmitted to the same host. Party: 1P = Klaviyo first-party host, 3P = third-party host. “Yes” indicates the value was present; a hyphen indicates it was not observed there.

HostnamePartyVendorContact Name or EmailLocationMerchant NameMerchant Email
www.klaviyo.com1PKlaviyoYesreq URL, or headers, or body; or resp bodyYesYes
heapanalytics.com3PHeap.ioYes
hexagon-analytics.com3PSiftYesreq URL
esp.aptrinsic.com3PGainsight PXYesreq URL, or req bodyYesYes
o19233.ingest.sentry.io3PSentryYesreq bodyYesYes
prodregistryv2.org3PStatsigProfile ID onlyreq bodyYes
featureassets.org3PStatsigYes
analytics.google.com3PGoogle AnalyticsYesreq URL
www.google-analytics.com3PGoogle AnalyticsYesreq URL

For three of the third-party hosts, Gainsight PX, Sentry, and Statsig, received our operator account identity: the test company name we used, and for Gainsight PX and Sentry our login email. A vendor that receives both the contact’s identity and the operator’s account identity can associate the contact with the specific Klaviyo account that viewed it. Sift (hexagon-analytics.com) and Google Analytics received the contact identity, but the operator company name was not observed in the same requests.