简体   繁体   中英

How can I detect if Chrome thinks the current page is a secure origin?

As of Chrome 50, Google have removed the ability for Chrome to do a Geolocation lookup unless the page hosted on a secure origin.

See https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features

I am building a widget that will be embedded on websites that I do not control, and my widget has some geolocation features. I want to hide geolocation-related UI in my widget if the user is using Chrome and the origin is not considered secure.

How can I detect non-secure origins?

Update

My initial idea was to do something like this:

const geolocationPermitted = () => {
  return (!window.chrome) || window.location.protocol == 'https:';
}

But this test fails When developing locally, since I serve the site from localhost over plain http . This is considered secure by Chrome though, and the function above return false.

I have found that Chrome and Firefox do expose this as a property:

https://developer.mozilla.org/en-US/docs/Web/API/Window/isSecureContext

The window.isSecureContext read-only property indicates whether a context is capable of using features that require secure contexts.

My current test is:

browserHasLocation = () => {
    return navigator.geolocation && (!window.chrome || window.isSecureContext);
}

Chrome will have a built in way to check for this, as one can't just check for the origin of the page, because the page could be on https but inside an iframe that is hosted from an unsecure context etc.

A strong signal that it was a non-secure content issue is to look for the string "Only secure origins are allowed" in the error message.

navigator.geolocation.getCurrentPosition(function(success) {
      // Origin IS secure
}, function(failure) {
    if(failure.message.indexOf("Only secure origins are allowed") == 0) {
      // Origin is NOT secure
    }
  };
});

This will work on older browsers, as they won't throw an error for an unsecure origin

Information gotten from the Chrome Web Updates page


Another way would be to check the protocol, but as noted above, this is not always reliable, for instance when using iframes etc.

if ( window.location.protocol == 'https:' ) {
    // SSL enabled
}

According to Google the following are generally considered "secure".

  • https://
  • wss://
  • file://
  • chrome-extension://
  • http://localhost
  • http://127.0.0.*
  • *::1.128

So if one is developing on localhost, a check for that would be needed as well, and if using websockets, one would have to check for wss etc.

Adding to that, the list may not be complete, there could be several other scenarios where the origin is considered secure, that would require additional checks, which is why the first method of using the error callback on getCurrentLocation should be used.

If developing on localhost, and the script should be used on http(s) protocol only, one could check for both

if (window.location.protocol == 'https:' || ["localhost", "127.0.0.1"].indexOf(location.hostname) !== -1) {...

Or simply comment out the check during development

Use isSecureContext , for example, console.log(isSecureContext) .

This is noted by MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM