Skip to content

Mixed Content and Malformed URLs: Optimole image CDN creates scheme-less URLs, causes HTTPS to HTTP fallback redirects in AJAX/mini-cart #1048

@kushh23

Description

@kushh23

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

  1. Enable Optimole and use a theme/plugin that loads images in AJAX (e.g., mini-cart, custom WooCommerce admin-ajax action, etc.).
  2. Inspect image URLs inside the AJAX-created mini-cart: they appear as:
    //{siteid}.i.optimole.com/...///windmeile.com/wp-content/uploads/....png
  3. Open one in a browser: You get a 302 Location: http://windmeile.com/... and a mixed-content warning.
  4. Confirm that the source image is already an HTTPS URL and WordPress is on HTTPS (is_ssl()=true, etc.).
  5. 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):

  1. inc/traits/normalizer.php (add_schema): operator precedence bug – prepends only 'https:', NOT 'https://'
  2. inc/url_replacer.php (build_url): mishandles triple-slash URLs (///host/path), resulting in malformed URLs (https:///host/path), improperly embedded in CDN URLs.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis label could be used to identify issues that are caused by a defect in the product.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions