Load klaviyo.js over HTTPS instead of protocol-relative URLs
-
Summary
The WordPress/WooCommerce plugin enqueues klaviyo.js using a protocol-relative URL (
//static.klaviyo.com/onsite/js/...) instead of an explicithttps://URL. Please switch these tohttps://.Affected code (plugin version 3.8.2)
inc/kla-analytics.php:86$klaviyo_js_source = '//static.klaviyo.com/onsite/js/' . $this->klaviyo_public_key . '/klaviyo.js';includes/wck-cart-functions.php:211wp_enqueue_script( 'wck_anon_backfill', '//static.klaviyo.com/onsite/js/' . $token . '/klaviyo.js?module=POST_IDENTIFICATION_SYNC', ... );
Why this matters
1. Security
The protocol-relative form inherits the protocol of the requesting page. If a visitor reaches the site over
http://– a typed URL, an old link, a stale bookmark, a redirect that has not kicked in yet -the script is fetched over plaintext HTTP as well. A script injected or modified in transit executes with full privileges in the page context and can take over the entire site (read/modify the DOM, exfiltrate form input, hijack sessions). Because klaviyo.js runs on checkout and product pages, this is a payment- and PII-relevant surface.The notation is a legacy pattern from the era of mixed HTTP/HTTPS hosting and is no longer recommended;
static.klaviyo.comserves HTTPS, so there is no compatibility reason to keep it.2. Security scoring / compliance
MDN HTTP Observatory (https://developer.mozilla.org/en-US/observatory) penalizes this. Every site running the Klaviyo plugin currently receives:
Subresource Integrity -50 points Subresource Integrity (SRI) not implemented, and external scripts are loaded over HTTP or they use protocol-relative URLs via src="//..."Serving the scripts over explicit
https://alone removes this deduction – the “SRI not implemented, but all external scripts are loaded over HTTPS” result is scored as a pass. No SRI hashes are required, which matters because klaviyo.js is served dynamically and its content changes, making static integrity hashes impractical.This affects the security rating of every store using the plugin, and for some merchants these scan results are part of a security review or audit requirement.
Suggested fix
- $klaviyo_js_source = '//static.klaviyo.com/onsite/js/' . $this->klaviyo_public_key . '/klaviyo.js';
+ $klaviyo_js_source = 'https://static.klaviyo.com/onsite/js/' . $this->klaviyo_public_key . '/klaviyo.js';
- wp_enqueue_script( 'wck_anon_backfill', '//static.klaviyo.com/onsite/js/' . $token . '/klaviyo.js?module=POST_IDENTIFICATION_SYNC', ... );
+ wp_enqueue_script( 'wck_anon_backfill', 'https://static.klaviyo.com/onsite/js/' . $token . '/klaviyo.js?module=POST_IDENTIFICATION_SYNC', ... );Please also check any other places that emit Klaviyo asset URLs (onsite forms snippet, tracking snippets in documentation and onboarding, other platform integrations), since the same pattern tends to be copied across them.
Current workaround
We currently rewrite the URLs in the page output via an output buffer in the theme’s functions.php. This works, but it costs performance on every request and has to be maintained per site – a one-line change in the plugin would solve it for all installations.
You must be logged in to reply to this topic.