-
Notifications
You must be signed in to change notification settings - Fork 215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Prevent a webpage document element to be detected as the Extension API object #153
Conversation
…on API object when running in content scripts
The following two DOM elements ensure that the polyfill doesn't detect the | ||
globals defined for these DOM element ids as the Extensions API objects. | ||
--> | ||
<div id="browser"></div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add another <div id="browser"></div>
to demonstrate the issue that I mentioned above.
@tophf have you deleted Rob comment by mistake? Follows @Rob--W deleted comment for reference In src/browser-polyfill.js: > @@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-if (typeof browser === "undefined") {
+if (typeof browser === "undefined" || browser instanceof window.Node) { Change to: if (typeof browser !== "object" || browser && Object.getPrototypeOf(browser) !== Object.prototype) {` or (if you prefer shorter code or don't want to rely on Object.getPrototypeOf): if (typeof browser === "undefined" || browser && browser.__proto__ !== Object.prototype) { or (if you don't want to rely on Object): if (typeof browser === "undefined" || browser && browser.__proto__ !== ({}).__proto__) { Why? Well:
See also https://www.w3.org/TR/html5/browsers.html#named-access-on-the-window-object |
I don't have any rights in this repo so I couldn't have deleted anyone else's comments directly. I guess github created a "thread" for my comment and Rob commented in that thread. Then I realized my comment is wrong and deleted it, which made github delete the entire "thread". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Do we already have an integration test that verifies that the polyfill does not overwrite the browser global in Firefox (content scripts and extension/background page)?
We have a unit test (which simulates the behaviors in an extension page/background page): webextension-polyfill/test/test-browser-global.js Lines 15 to 27 in 450eee5
And an integration test which tests the behavior in a content script context on Chrome and Firefox: webextension-polyfill/test/fixtures/detect-browser-api-object-in-content-script/content.js Lines 1 to 18 in 450eee5
|
The way that we inject APIs in Firefox are different for extension pages and content scripts, so a test for the background page seems desired.
|
… object when running in content scripts mozilla/webextension-polyfill#153
… object when running in content scripts mozilla/webextension-polyfill#153
… object when running in content scripts mozilla/webextension-polyfill#153
… object when running in content scripts mozilla/webextension-polyfill#153
…and fix wrong assumption in the test related to the content scripts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with very minor nits.
// a small latency time. | ||
browser.runtime.onMessage.addListener(async (msg, sender) => { | ||
if (msg !== "test-api-object-in-background-page") { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why return false;
? If you don't want the handler to respond, jus return void (return;
).
Or make this a non-async function and call sendResponse({ ... });
in the end.
@@ -0,0 +1,2 @@ | |||
// Store a copy of the references to the original API objects. | |||
const originalAPIObjects = {browser, chrome}; // eslint-disable-line no-unused-vars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment that in browsers without a browser
API, this will point to the <div id="browser">
in the page.
return Promise.resolve({ | ||
browserIsDefined: !!browser, | ||
chromeIsDefined: !!chrome, | ||
browserIsUnchanged: browser === originalAPIObjects.browser, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's check window.browser
too?
552cfa0
to
17536d2
Compare
… object when running in content scripts mozilla/webextension-polyfill#153
This PR applies some changes to the webpage used by the integration test suite, to reproduce the same issue that is described in this comment on issue #68 and on https://crbug.com/865881
And the additional check
browser instanceof window.Node
in the polyfill sources, to detect this scenario and prevent the DOM node to be detected as an existing Extension API object (and turn the polyfill into a no-op as when it runs on Firefox where the browser API object is natively available).