'How do I allow the Geolocation API inside an iframe?

I have an iframe tag with the src being another webpage on a different server. I have the ability to modify the headers of both sites. Before I started implementing the Control Security Policy, I was able to click a button inside the iframe and retrieve the GPS coordinates. I believe there is something about the Control Security Policy that is stopping my parent site from running the Geolocation API.

The Parent Site's Code:

<customHeaders>
    <add name="Content-Security-Policy" value="frame-src 'self' https://MyChildSite.com" />
</customHeaders>
<html>
    <iframe src="https://MyChildSite.com" allow="geolocation"></iframe>
</html>

The Child Site's Code:

<customHeaders>
      <add name="Content-Security-Policy" value="frame-src 'self' https://MyParentSite.com" />
      <add name="Feature-Policy" value="geolocation 'self' https://MyParentSite.com" />
</customHeaders>
<html>
    <button onclick="getCoordinates()">Get GPS</button>
    ...list some stuff
</html>

When I click the button on the child site through the parent site, I don't get the response I'd expect from the coordinates. Is there a solution to this?



Solution 1:[1]

,--------------------- parent https://MyParentSite.com ------------------------,
|Content-Security-Policy: frame-src 'self' https://MyChildSite.com             |
|   * aboved CSP do allow <iframe src="https://MyChildSite.com"                |
|                                                                              |
|                                                                              |
|   <iframe src="https://MyChildSite.com" allow="geolocation">                 |
|                                                                              |
|   ,-------------------- nested https://MyChildSite.com --------------------, |
|   |Content-Security-Policy: frame-src 'self' https://MyChildSite.com       | |
|   |  1. aboved CSP do nothing, it will apply to subnested iframes only     | |
|   |                                                                        | |
|   |  2. allow="geolocation" -> allow="geolocation https://MyChildSite.com" | |
|   |     which is EQUAL to:                                                 | |
|   |    Feature-Policy: geolocation https://MyChildSite.com                 | |
|   |                                                                        | |
|   |  Therefore header:                                                     | |
|   |                                                                        | |
|   |Feature-Policy: geolocation 'self' https://MyParentSite.com             | |
|   |  will failed to allow https://MyParentSite.com, iframe can not extend  | |
|   |  permissions, given by parent document, see para 2. above.             | |
|   |  As result within iframe you will have only:                           | |
|   |     Feature-Policy: geolocation https://MyChildSite.com                | |
|   |                                                                        | |
|   |________________________________________________________________________| |
|                                                                              |
|   </iframe>                                                                  |
!______________________________________________________________________________|
  1. Why allow="geolocation" -> allow="geolocation https://MyChildSite.com pls see Directive in the allow= attribute is specified without keys will take origin from src= attribute.

  2. There is some specifics of passing Feature Policy permissions into nested browsing context. Iframe can not delegate himself (or subnested iframes) more permissions tha it granted by parent document.
    If you have a script running within iframe, you can use featurePolicy.getAllowlistForFeature interface to get a list of all allowed origins and to see whats going on.

  3. You issue have nothing to do with Content Security Policy, I think you even do not have any CSP violation in the browser console.

The solution is to explicitly specify allowed origins in the allow= attribute:

<iframe src="https://MyChildSite.com" allow="geolocation 'self' https://MyParentSite.com"></iframe>

Alternatively you can remove allow= attribute (or set allow='*'):

<iframe src="https://MyChildSite.com"></iframe>

and to use Feature-Policy: geolocation 'self' https://MyParentSite.com within iframe to set permissions.

  • Do not forget that geolocation API works in secure context only (means over https: only). You could check window.isSecureContext property to perform appropriate diag.

PS: Could I ask you to add the `feature policy` tag to you question, this will help other peoples in future.

EDIT

allow="*" isn't working anymore but have to mention it as follow allow="geolocation *"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Raphaël Balet