-
Notifications
You must be signed in to change notification settings - Fork 15
Mixed Content and Malformed URLs: Optimole image CDN creates scheme-less URLs, causes HTTPS to HTTP fallback redirects in AJAX/mini-cart #1048
Description
Description
A user reported a significant mixed content/broken image issue on their WooCommerce store (windmeile.com) traced to Optimole's image URL handling in certain AJAX contexts (mini-cart, custom admin-ajax action).
What happens
- Page is served over HTTPS.
- AJAX-loaded mini-cart shows image URLs like:
//{id}.i.optimole.com/...///windmeile.com/wp-content/uploads/...png
(Note: CDN path is protocol-relative double-slash, and the embedded origin is scheme-less triple-slash: ///windmeile.com/) - When loaded, browser requests CDN over HTTPS. Optimole redirects:
302 Found
Location: http://windmeile.com/wp-content/uploads/... - This triggers a browser mixed content error (secure page attempts to load insecure image) and images break in affected areas.
Debug and analysis
- WordPress correctly detects SSL even in AJAX context (is_ssl()=true, HTTPS=on, SERVER_PORT=443, X-Forwarded-Proto=https).
- Input image URLs given to Optimole are already HTTPS (https://windmeile.com/wp-content/uploads/...).
- Problem reproducible by opening the CDN URL directly: the CDN still redirects with Location: http://... (not https).
- The origin windmeile.com does redirect http > https if requested directly, but browser blocks due to mixed content chain start.
Why it happens
- The plugin creates and passes URLs with three leading slashes (///windmeile.com/...) to the CDN. This triple-slash case is not normalized properly and results in a malformed URL. Downstream, the Optimole CDN falls back to Location: http://... for such scheme-less/invalid origins.
- There is also a code bug in Optimole's add_schema() implementation (operator precedence) that leads to 'https:' being returned without '//' in some cases.
Workaround
- I (the reporter) added a filter to post-process generated URLs, rewriting '///windmeile.com/...' as '/https://windmeile.com/...'. This prevents the mixed content, but is not a proper fix. Some unnecessary 302s/caching issues remain (origin fetches, slower mini-cart updates).
Additional technical findings (see below)
Step-by-step reproduction instructions
- Enable Optimole and use a theme/plugin that loads images in AJAX (e.g., mini-cart, custom WooCommerce admin-ajax action, etc.).
- Inspect image URLs inside the AJAX-created mini-cart: they appear as:
//{siteid}.i.optimole.com/...///windmeile.com/wp-content/uploads/....png - Open one in a browser: You get a 302 Location: http://windmeile.com/... and a mixed-content warning.
- Confirm that the source image is already an HTTPS URL and WordPress is on HTTPS (is_ssl()=true, etc.).
- Implement the workaround (filter to rewrite ///windmeile.com/ to /https://windmeile.com/) and notice that only THEN does Optimole reliably redirect to HTTPS, eliminating mixed content, but there are still unnecessary 302s (CDN cache/can't serve optimized/caching).
Key is to test with admin-ajax, AJAX-loaded markup, or custom entry points, not only normal frontend pages.
Screenshots, screen recording, code snippet or Help Scout ticket
- Affected CDN URL: //…i.optimole.com/...///windmeile.com/wp-content/uploads/...
- Browser request over HTTPS → Optimole CDN responds 302 Location: http://windmeile.com/...
- Mini-cart images break with mixed content warning
- See detailed technical root cause below
Relevant code issues (Plugin):
- inc/traits/normalizer.php (add_schema): operator precedence bug – prepends only 'https:', NOT 'https://'
- inc/url_replacer.php (build_url): mishandles triple-slash URLs (///host/path), resulting in malformed URLs (https:///host/path), improperly embedded in CDN URLs.
- Optimole CDN backend: fallback logic sets Location: http://... when given scheme-less/malformed origin.
Related code:
https://github.com/Codeinwp/optimole-wp/blob/master/inc/traits/normalizer.php#L366-L376
https://github.com/Codeinwp/optimole-wp/blob/master/inc/url_replacer.php#L156-L158
Original user report (windmeile.com): provided detailed debugging, confirmed WP SSL detection works, not a hosting misconfig.
Proposed Fixes
- Fix add_schema (operator precedence): use (is_ssl() ? 'https:' : 'http:') . $url; instead of is_ssl() ? 'https:' : 'http:' . $url;
- Normalize triple-slash ///host/path URLs in build_url to https://host/path before CDN embedding.
- Optionally, CDN fallback logic for location redirects should default to HTTPS when the incoming CDN request is HTTPS.
If extra details or code context is needed, I'm happy to provide a PR or samples.
Environment info
Not my site. A user reported this to me. Site: windmeile.com, hosted on standard WooCommerce/WordPress stack, confirmed issue is Optimole plugin + CDN regardless of hosting. I (reporter) am a developer/maintainer relaying this user feedback.
Is the issue you are reporting a regression
No