Iframe not displaying https content due to target server's content policy

I would like to have a card, using an iframe to display a map, say google maps. So I’ve set the iframe’s url property to the https address, but the site is refusing to load the page. Any suggestions?

My network is setup in a way that is a bit unusual compared to most. Instead of having a wired ISP, I use my iPhone’s hotspot as my AP/gateway. I have a router on my LAN that connects to the hotspot using WISP mode, and all my devices (wired/wireless) connect to the internal router.
The main problem this arrangement presents is that I do not have NAT at the gateway, which means I cannot forward ports to my internal servers. This also means I am unable to use dynamic DNS in the usual way. It may be possible to connect everything to an external VPN (I have a hosted VPS which uses Lets Encrypt), but I don’t really want to do that.
My HA is running on a Pi4 without SSL and everything else works fine. I don’t think I can make use of Lets Encrypt on my HA instance because of the NAT issue mentioned above.

1 Like

I believe most browsers complain when displaying http content on an https page and refuse to display https content on an http page.

Note: While this solution may have worked in some browsers when it was written in 2014, it no longer works. Navigating or redirecting to an HTTP URL in an iframe embedded in an HTTPS page is not permitted by modern browsers, even if the frame started out with an HTTPS URL.

from https://newbedev.com/how-to-allow-http-content-within-an-iframe-on-a-https-site

@Prodigyplace : Yes, I’m familiar with this issue, and since the card is being displayed as an element of an http page, I see what you’re saying (although my situation is the opposite of what’s described in that link).

Is there an alternate way, given my network setup? Would a self-signed certificate work here?

There are a few ways to make LetsEncrypt work, and if we had to go down that route - using something like Cloudflare for a domain, and LetsEncrypt in DNS mode, so it never needs to access your internal network is the simplest way in the setup.

However, that doesn’t have anything to do with the problem you are encountering. displaying HTTP content on a HTTPS site is disallowed for reasons of privacy and security, but displaying HTTPS content on a HTTP page is NOT disallowed, because it does not affect the security or privacy of the HTTPS delivered content.

Browsers block loading anything from HTTP on a HTTPS connection, IF the content being loaded has the ability to interact with or change the display of the page. Images and other static content that cannot interact with the page, will still be loaded.

@mobile.andrew.jones : hence my issue (network configuration aside). I am attempting to load HTTPS into a HTTP page, which should not be a problem. Nonetheless, it is an issue.

I know it is possible to block 3rd party iframes from loading content from your site. However, because the guide I’m using to learn about lovelace customisation has a working map page that uses www.windy.com, it is clear that www.windy.com is not blocking iframes. Yet the same code is not working for me (though I can open the map page in another tab of my browser and see the page there).

So this must be something I have mis-configured but I don’t know what.

The YAML snippet for the card is below:

  - title: Weather Map
    panel: true
    cards:
      - type: iframe
        url: https://www.windy.com/-0.462/100.581?temp,0.488,100.630,11,m:cToakpt

When I click the Weather Map panel, the site attempts to load, but gives an error.

It’s a long shot, but try putting quotes around the URL?
You should have a look at the developer tools for your browser, in particular the network tab, to see what URL it shows it is trying to load.

Cheers, I’ll do that.

Quotes did not help.
In browser’s console, I have the following:

    The main 'lit-element' module entrypoint is deprecated. Please update your imports to use the 'lit' package: 'lit' and 'lit/decorators.ts' or import from 'lit-element/lit-element.ts'.
    55704 		@ app.f08a72d3.js:5264
    s		@ app.f08a72d3.js:30632
    53918		@ app.f08a72d3.js:1290
    s		@ app.f08a72d3.js:30632
    (anonymous)	@ app.f08a72d3.js:30632
    (anonymous)	@ app.f08a72d3.js:36741
    (anonymous)	@ app.f08a72d3.js:36741
    --------------------------------------------------------------------------------    
    Refused to frame 'https://www.windy.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self' *.windy.com:*".
    --------------------------------------------------------------------------------
    Blocked autofocusing on a <input> element in a cross-origin subframe.
    --------------------------------------------------------------------------------    
    (index):1370 crbug/1173575, non-JS module files deprecated.
    (anonymous)	@ (index):1370

Not sure what is meant by ‘ancestor’ here.

I’m reading: iframe - Content Security Policy directive: "frame-ancestors 'self' - Stack Overflow about this.

Regardless of what guide you are following - a quick check of windy.com in the developers tools shows this:

content-security-policy: frame-ancestors 'self' *.windy.com:*

In the response headers, suggesting that the site will only display on domains that end in windy.com (eg itself).

Ok.

I tried it on my own HTTPS site, where I have X-Frame-Options set to sameorigin, and I get a similar result, but the error referred to the above option.

Is there any other way of getting this to show in HA? Can I make the panel show in another browser tab instead?

windy offer an API and the trial version is free: https://api.windy.com/ if you used the documentation Windy: Map Forecast API - Tutorials and created a page that worked locally to display what you want inside the www directory, then you could iframe that as /local/my-windy-map.html or something?

1 Like

@mobile.andrew.jones : Thanks. I’ll look into that. Cheers.

I’m going to mark your last comment as the solution, as, after looking at their tutorial, I think this will work.

Only caveat is that the solution will not work for sites that don’t offer this approach.

1 Like

I just quoted where it is EXPECTED to be a problem. I think the Let’s Encrypt certificate idea is the least expensive IF you have the needed knowledge to set it up & maintain it.

I need to change the subject because the problem has to do with the target server’s content policy.
The iframe, irrespective of whether I’m using SSL or not, is able to load HTTPS into a non-HTTPS page, but not the other way around.

In my case, because of my network setup; no NAT at the gateway, Lets Encrypt will not help. I already use Lets Encrypt on my hosted VPS, so I could configure VPN on it which would allow me to connect to it.