Closed Bug 1308920 Opened 8 years ago Closed 8 years ago

postMessage adds unexpected origin attributes to target origin

Categories

(WebExtensions :: General, defect, P1)

50 Branch
defect

Tracking

(firefox49 unaffected, firefox50+ fixed, firefox51 fixed, firefox52 verified)

VERIFIED FIXED
mozilla52
Tracking Status
firefox49 --- unaffected
firefox50 + fixed
firefox51 --- fixed
firefox52 --- verified

People

(Reporter: vic.portnov, Assigned: kmag)

References

Details

(Keywords: addon-compat, regression, Whiteboard: triaged [platform-rel-Symantec])

Attachments

(5 files)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36

Steps to reproduce:

(NOTE: I've tested in Beta 50 and in Nightly 52 - behaviour is the same)

I use postMessage to implement communication between extension (content script) and web page.
The communication should work if the web page is top window and if the web page is inside iframe.

To achieve this, the following alogoritm was implemented:
1. At the beginning content script listens for messages from window and uses window.top as targetWindow and '*' as targetOrigin to post messages back to page
Code:
var targetWindow = window.top;
var targetOrigin = '*';
var sourceWindow = window;

2. Every time when content script receives a message which is considired as valid message, it replaces value of targetWindow by msg.source and targetOrigin by msg.origin to be sure that it communicates with particular window, then forwards msg.data to extension
Code:
sourceWindow.addEventListener('message', function (msg) {
  targetWindow = msg.source;
  targetOrigin = msg.origin;
  // handling of msg.data
}, false);

3. When reply from extension comes, content script sends the reply to page using targetWindow and targetOrigin.
Code:
targetWindow.postMessage(data, targetOrigin);




Actual results:

Error happens:
"Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://my.domain.com’) does not match the recipient window’s origin (‘https://my.domain.com’)."

Although origins are identical (see string above) it says that they does not match!
By the way, the same code works fine in Chrome.

I found that I can work it around if targetOrigin is kept '*' (just targetWindow is replace in step 2).
For now I use this solution but it makes my code less secure.


Expected results:

No error happens and target window gets data which has been sent
Severity: normal → major
Hello Victor, could you please provide a simplified test-case in order for us to test this further? Also feel free to use https://jsfiddle.net/ if the tools provided here are enough for you to give us a sample of the issue you are encountering.
Severity: major → normal
Flags: needinfo?(vic.portnov)
Attached file debugext.zip
Simple extension to test bug with https://jsfiddle.net/aotk2xfy/5/
Hi Emil, sure thing.
I've attached the extension code, you need to unpack it to some folder then go into about:debugging#addons page in Firefox 50 or above and Load Temporary Add-on.
As result you will get "Test Bug 1308920" extension.

Then you need to go to https://jsfiddle.net/aotk2xfy/5/ and run it.
As result you will see something like that in console:
=============
from iframe: posting ping ...
from extension: got ping, sending pong to "https://fiddle.jshell.net" ...
Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://fiddle.jshell.net’) does not match the recipient window’s origin (‘https://fiddle.jshell.net’).
from iframe: posting ping ...
from extension: got ping, sending pong to "*"
from iframe: got MessageEvent { isTrusted: false, data: "pong", origin: "https://jsfiddle.net", 7 more… }
=============
The first is buggy case I'm talking about, the second is just illustration that for '*' it works fine.
You may compare target and recipient origins in error text - they are identical.

Just in case below is code in jsfiddle (so you may restore it if something happened jsfiddle):
=============
window.addEventListener('message', function (msg) {
  console.log('from iframe: got', msg);
});

var postMsg = function () {
  console.log('from iframe: posting ping ...');
  window.top.postMessage('ping', '*');
};

setTimeout(postMsg, 1000);
setTimeout(postMsg, 2000);
=============

Hope this helps.
Flags: needinfo?(vic.portnov)
Component: Untriaged → DOM
Product: Firefox → Core
I'm guessing this should be filed in Web Extensions but I'm happy for it to move back here if I'm incorrect.
Component: DOM → WebExtensions: Untriaged
Product: Core → Toolkit
This works as expected for me in Firefox 51.
2Kris: I'm not sure if it is platform dependent or not.
I tested just on Windows 7 64bit with 32bit versions of Firefox.
Firefox versions were 50 (beta) and 52 (nightly).
I'll add this info about platform I've used since I don't know about others.
OS: Unspecified → Windows 7
Hardware: Unspecified → x86_64
Btw, I tested code I put into test extension from page itslef (just inserted it into browser cosole opened for jsfiddle tab with the test): it works as expected, that's true.
So it does not work for extensions' content-scripts only.
We have this same issue w/ our code trying to upgrade to WebExtensions: https://bugzilla.mozilla.org/show_bug.cgi?id=1309683
OK, I was able to reproduce this with the steps described in bug 1309683.

The problem is that we're copying the addon ID from the caller origin attributes to the principal for the URL specified in the postMessage call[1]. So I think we need to do two things to fix this:

1) Don't copy the add-on ID to the target origin attributes when creating the target principal.

2) When the two origin strings are the same, append the origin attributes string to both[2], so that the error message is at least comprehensible.

bz, you reviewed the patch that added this warning in bug 1139849. Do you agree that the origin attributes should be added to the message when the origin strings are otherwise identical? (Also, can you suggest a reviewer for those changes?)

[1]: http://searchfox.org/mozilla-central/rev/d96317a351af8aa78ab9847e7feed964bbaac7d7/dom/base/nsGlobalWindow.cpp#8369-8373
[2]: http://searchfox.org/mozilla-central/rev/d96317a351af8aa78ab9847e7feed964bbaac7d7/dom/base/PostMessageEvent.cpp#110-127
Assignee: nobody → kmaglione+bmo
Status: UNCONFIRMED → NEW
Component: WebExtensions: Untriaged → WebExtensions: General
Ever confirmed: true
Flags: needinfo?(bzbarsky)
OS: Windows 7 → All
Hardware: x86_64 → All
Summary: postMessage does not work from content scritp if origin is specified and target window is in iframe → postMessage adds unexpected origin attributes to target origin
Version: 50 Branch → unspecified
Sorry for the lag here.

Item #2 from comment 10 sounds good to me, though it may not make much sense to do when you just have two distinct nullprincipals or whatnot (because the origin attributes aren't being your problem in that case anyway).

For item #1, I'm not sure what the right thing to do is.  If you don't copy the add-on ID, won't that break postMessage to iframes within the addon itself?  It seems like we'd want to restrict the "don't copy the add-on ID" case to content scripts within addons or something.

As far as reviewers, maybe billm for the review and ping bholley once you decide on what behavior is being implemented just to make sure he's ok with whatever setup gets decided in the end?
Flags: needinfo?(bzbarsky)
(In reply to Boris Zbarsky [:bz] (still a bit busy) from comment #11)
> Item #2 from comment 10 sounds good to me, though it may not make much sense
> to do when you just have two distinct nullprincipals or whatnot (because the
> origin attributes aren't being your problem in that case anyway).

I think those should always have unique UUID origins anyway, so it probably wouldn't make a difference.

> For item #1, I'm not sure what the right thing to do is.  If you don't copy
> the add-on ID, won't that break postMessage to iframes within the addon
> itself?  It seems like we'd want to restrict the "don't copy the add-on ID"
> case to content scripts within addons or something.

Hm. Well, that basically only works by accident, as it is. Technically an add-on should be able to postMessage to an iframe owned by a different add-on, and a window with web content should be able to postMessage or reply to a window with extension content. Neither of which works now.

I don't really have a solution good solution to that, other than special casing moz-extension: URLs here, or adding a special attribute to their URI objects. We normally just directly add the addonId when we create the principals for channels or sandboxes.
> I think those should always have unique UUID origins anyway

They do, but they stringify to "null", so have identical origin strings.

> Technically an add-on should be able to postMessage to an iframe owned by a different add-on

In that case what we _really_ want is some sort of "compare principals ignoring origin attributes" thing here, no?  Normally things with different origin attributes can't even get hold of each other (is that true?), so this should only affect the addon case...
(In reply to Boris Zbarsky [:bz] (still a bit busy) from comment #13)
> > Technically an add-on should be able to postMessage to an iframe owned by a different add-on
>
> In that case what we _really_ want is some sort of "compare principals
> ignoring origin attributes" thing here, no?

I think that maybe we want "compare principals ignoring addonId", since we
already have IsOriginAttributesEqualIgnoringAddonId?

> Normally things with different origin attributes can't even get hold of each
> other (is that true?), so this should only affect the addon case...

That was my thought, but since we're explicitly copying origin attributes when
we create the principal for this check, I was assuming we were doing it for a
reason. As far as I can see, though, if a site gets hold of a window with
different origin attributes (other than addonId) so it can postMessage to it,
something is already very wrong.
> I think that maybe we want "compare principals ignoring addonId"

Yes, that's fair.

> but since we're explicitly copying origin attributes when we create the
> principal for this check, I was assuming we were doing it for a reason

Yes.  The reason is that otherwise an addon could not postMessage its own iframes with a provided origin, and any window running in a non-default container tab would not be able to postMessage anything at all running in that same tab (still with a provided origin), and in private browsing mode things couldn't postMessage either, etc.
OK. In that case I think I'll go with comparing ignoring the add-on ID and add a diagnostic assert that the origin attributes are the same on failed match, rather than a message.
Note that we have a plan to stop using origin attributes for add-on IDs. This is the second time this has come up in the last two weeks. Maybe it's time to fix that. I'll file a bug with more details later.
Flags: needinfo?(wmccloskey)
Priority: -- → P1
Whiteboard: triaged
Let me know if I can help at all with that.

Either way, this is going to need tests and the assertion that origin attributes match.
Since this regression is seen in FF50 beta now, is the fix momentum likely to affect FF50 plans OR not? 

This issue is bringing up the prospect of my team needing to release an extension update and incur release overhead with that, which is not preferred.
If it's deemed a critical regression, we may be able to get the simpler version of the fix into 50 before release, but it's a long shot at this stage.

[Tracking Requested - why for this release]: This is a regression introduced in Firefox 50 which affects an unknown number of WebExtensions.
Severity: normal → critical
Keywords: regression
Comment on attachment 8806157 [details]
Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal.

https://reviewboard.mozilla.org/r/89658/#review89346

Not super excited about the one-off here, especially given that the addonID OA is going away. I'll defer to Bill about the overall plan, (see comment 17), but if it's the most expedient for now I'm ok with it.

If we do go this route though, I want to enscapsulate it a lot more (and make it less general). That would include:
* Putting this on BasePrincipal instead of nsIPrincipal to avoid exposing it to script.
* Not polluting all the regular signatures with this stuff, and just handling it manually in BasePrincipal::EqualsIgnoringAddonId (possibly along with some orthogonal set of utility functions).
Attachment #8806157 - Flags: review?(bobbyholley) → review-
(In reply to Bobby Holley (:bholley) (busy with Stylo) from comment #23)
> Not super excited about the one-off here, especially given that the addonID
> OA is going away. I'll defer to Bill about the overall plan, (see comment
> 17), but if it's the most expedient for now I'm ok with it.

I'm not happy about it either, but this bug is a regression in 50 and there's
no way the removal of the origin attributes will be upliftable at this point.
It can be removed when the the originId attribute is removed.

> If we do go this route though, I want to enscapsulate it a lot more (and
> make it less general). That would include:
> * Putting this on BasePrincipal instead of nsIPrincipal to avoid exposing it
> to script.

That should be fine.

> * Not polluting all the regular signatures with this stuff, and just
> handling it manually in BasePrincipal::EqualsIgnoringAddonId (possibly along
> with some orthogonal set of utility functions).

I guess we could handle it by cloning the origin attributes, removing the
addonId, creating new principals, and falling back to the regular checks...
But I'm not sure that would simplify anything, and the alternative of manually
checking equality seems a bit hairy.
Comment on attachment 8806158 [details]
Bug 1308920: Part 2 - Support posting messages across windows with different addonId origins.

https://reviewboard.mozilla.org/r/89660/#review89368

::: dom/base/PostMessageEvent.cpp:117
(Diff revision 1)
>        nsresult rv = nsContentUtils::GetUTFOrigin(targetPrin, targetOrigin);
>        NS_ENSURE_SUCCESS(rv, rv);
>        rv = nsContentUtils::GetUTFOrigin(mProvidedPrincipal, providedOrigin);
>        NS_ENSURE_SUCCESS(rv, rv);
>  
> +      MOZ_DIAGNOSTIC_ASSERT(providedOrigin != targetOrigin ||

I'm a little worried about this assertion, but I guess if it fails we'll learn something.
Attachment #8806158 - Flags: review?(wmccloskey) → review+
(In reply to Kris Maglione [:kmag] from comment #24)
> I guess we could handle it by cloning the origin attributes, removing the
> addonId, creating new principals, and falling back to the regular checks...
> But I'm not sure that would simplify anything, and the alternative of
> manually
> checking equality seems a bit hairy.

One approach would be to move the OA check from Subsumes to SubsumesInternal, which would give you an OA-agnostic subsumes method.
Comment on attachment 8806158 [details]
Bug 1308920: Part 2 - Support posting messages across windows with different addonId origins.

https://reviewboard.mozilla.org/r/89660/#review89368

> I'm a little worried about this assertion, but I guess if it fails we'll learn something.

I was initially planning to add the origin attributes string if they didn't match, so the error message made some sort of sense. But after going over it with bz in the bug comments, we came to the conclusion it shouldn't actually ever happen. So, if it does, it would be good to know about it.
(In reply to Bobby Holley (:bholley) (busy with Stylo) from comment #26)
> (In reply to Kris Maglione [:kmag] from comment #24)
> > I guess we could handle it by cloning the origin attributes, removing the
> > addonId, creating new principals, and falling back to the regular checks...
> > But I'm not sure that would simplify anything, and the alternative of
> > manually
> > checking equality seems a bit hairy.
> 
> One approach would be to move the OA check from Subsumes to
> SubsumesInternal, which would give you an OA-agnostic subsumes method.

Hm... The only problem I see with that is that ExpandedPrincipals theoretically need to check the OA of all of their sub-principals. And their SubsumesInternal calls both Subsumes and SubsumesInternal.

But I'll see if I can figure out a way to make it work.
Filed bug 1314361 based on my best recollection of our plan.
Flags: needinfo?(wmccloskey)
Comment on attachment 8806157 [details]
Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal.

https://reviewboard.mozilla.org/r/89658/#review89510

r=me with those fixes. Most important fix is ithe one in nsExpandedPrincipal::Subsumes.

::: caps/BasePrincipal.h:326
(Diff revision 2)
>  
>  protected:
>    virtual ~BasePrincipal();
>  
>    virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
>    virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;

Please add a comment here indicating that this doesn't check OAs.

::: caps/BasePrincipal.cpp:400
(Diff revision 2)
> +  // Expanded principals handle origin attributes for each of their
> +  // sub-principals individually, and system principals are immune to origin
> +  // attributes checks, so only do this check for codebase principals.

Also mention that null principals use pointer equality and so don't need this.

::: caps/BasePrincipal.cpp:432
(Diff revision 2)
>  }
>  
> +bool
> +BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
> +{
> +  MOZ_ASSERT(aOther, "Invalid argument");

Nit: you can drop the string explanation.

::: caps/BasePrincipal.cpp:433
(Diff revision 2)
>  
> +bool
> +BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
> +{
> +  MOZ_ASSERT(aOther, "Invalid argument");
> +  NS_ENSURE_TRUE(aOther, false);

This isn't necessary. We're not called from script so we have a higher confidence in correct API usage.

::: caps/nsPrincipal.cpp:726
(Diff revision 2)
>    if (expanded) {
>      nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
>      expanded->GetWhiteList(&otherList);
>      for (uint32_t i = 0; i < otherList->Length(); ++i){
>        if (!SubsumesInternal((*otherList)[i], aConsideration)) {

This is busted now, right? I think this needs to become Subsumes().
Attachment #8806157 - Flags: review?(bobbyholley) → review+
Comment on attachment 8806157 [details]
Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal.

https://reviewboard.mozilla.org/r/89658/#review89510

> This is busted now, right? I think this needs to become Subsumes().

No. I initially did change it to Subsumes, but SubsumesInternal never checked OAs on expanded principals, and Subsumes still doesn't, so it just adds unnecessary virtual call overhead for the same behavior.
(In reply to Kris Maglione [:kmag] from comment #33)
> Comment on attachment 8806157 [details]
> Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal.
> 
> https://reviewboard.mozilla.org/r/89658/#review89510
> 
> > This is busted now, right? I think this needs to become Subsumes().
> 
> No. I initially did change it to Subsumes, but SubsumesInternal never
> checked OAs on expanded principals, and Subsumes still doesn't, so it just
> adds unnecessary virtual call overhead for the same behavior.

Oh right ok - the actually OA check happens in the Subsumes call below in the case where we have a normal principal. That's fine then.
But maybe add a comment explaining this?
(In reply to Bobby Holley (:bholley) (busy with Stylo) from comment #35)
> But maybe add a comment explaining this?

Yeah.
https://hg.mozilla.org/integration/mozilla-inbound/rev/0475a23b1a526c8338852d4812bdd65027bd8c1f
Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal. r=bholley

https://hg.mozilla.org/integration/mozilla-inbound/rev/36b37ea010f1baacac9513a3554c202f609a6ec9
Bug 1308920: Part 2 - Support posting messages across windows with different addonId origins. r=billm
Comment on attachment 8806158 [details]
Bug 1308920: Part 2 - Support posting messages across windows with different addonId origins.

Approval Request Comment
[Feature/regressing bug #]:

It's unclear which bug regressed this, but it works in Firefox 49 and does not work in 50.

[User impact if declined]:

This breaks an unknown number of WebExtensions, and causes them to fail with a cryptic error message. The simplest workaround, which is to change the target origin to "*", drastically decreases security, and is not something we should encourage while developers wait for a fix.

[Describe test coverage new/current, TreeHerder]:

The relevant features are covered by extensive tests, and this patch adds tests for this particular regression.

[Risks and why]:

Low. The changes are as minimal as possible, and shouldn't have effects to code outside of `window.postMessage`. The changes to `window.postMessage` should be restricted to cases where one side of the exchange is a WebExtension, and which is currently broken.

The one marginal risk is the addition of a diagnostic assert to detect unexpected messaging across windows with different origin attributes, but it does not apply to release or beta populations.

[String/UUID change made/needed]: None
Attachment #8806158 - Flags: approval-mozilla-beta?
Attachment #8806158 - Flags: approval-mozilla-aurora?
Comment on attachment 8806157 [details]
Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal.

Approval Request Comment: See comment 38
Attachment #8806157 - Flags: approval-mozilla-beta?
Attachment #8806157 - Flags: approval-mozilla-aurora?
(In reply to Kris Maglione [:kmag] from comment #38)
> [Feature/regressing bug #]:
> 
> It's unclear which bug regressed this, but it works in Firefox 49 and does
> not work in 50.

Update: This seems to have been regressed by bug 1297687.
Hi Victor, could you please verify this issue is fixed as expected on a latest Nightly build? Thanks!
Flags: needinfo?(vic.portnov)
Comment on attachment 8806158 [details]
Bug 1308920: Part 2 - Support posting messages across windows with different addonId origins.

This is a new regression in 50 which breaks a bunch of webextensions, the workaround isn't safe, let's take this in 50 RC2, Aurora51+
Attachment #8806158 - Flags: approval-mozilla-beta?
Attachment #8806158 - Flags: approval-mozilla-beta+
Attachment #8806158 - Flags: approval-mozilla-aurora?
Attachment #8806158 - Flags: approval-mozilla-aurora+
Attachment #8806157 - Flags: approval-mozilla-beta?
Attachment #8806157 - Flags: approval-mozilla-beta+
Attachment #8806157 - Flags: approval-mozilla-aurora?
Attachment #8806157 - Flags: approval-mozilla-aurora+
Part 1 is hitting a conflict in caps/BasePrincipal.h that I'm not comfortable working around myself. Could we get a rebased patch for beta (and make sure part 2 applies to beta as well?
Flags: needinfo?(kmaglione+bmo)
Flags: needinfo?(kmaglione+bmo)
(In reply to Kris Maglione [:kmag] from comment #42)
> This isn't in a nightly yet, but there are try builds available now:
> 
> win64:
> 
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-win64/firefox-52.0a1.en-US.
> win64.installer.exe
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-win64/firefox-52.0a1.en-US.
> win64.zip
> 
> 
> win32:
> 
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-win32/firefox-52.0a1.en-US.
> win32.installer.exe
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-win32/firefox-52.0a1.en-US.
> win32.zip
> 
> 
> linux64:
> 
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-linux64/firefox-52.0a1.en-US.
> linux-x86_64.tar.bz2
> 
> 
> OS-X:
> 
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-macosx64/firefox-52.0a1.en-US.
> mac.dmg
> 
> 
> linux32:
> 
> https://archive.mozilla.org/pub/firefox/try-builds/maglione.k@gmail.com-
> e2082184caca77cfef95164b626f1418b0f781c9/try-linux/firefox-52.0a1.en-US.
> linux-i686.tar.bz2

Try build for FF52 worked ok - we'd like to test with a FF50 RC2 build too
Flags: needinfo?(matthew_powers)
https://hg.mozilla.org/mozilla-central/rev/0475a23b1a52
https://hg.mozilla.org/mozilla-central/rev/36b37ea010f1
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla52
I've tested with win32 try build using test extension and it works fine for me now.
Thank you for the fix!

May you please let me know when it is going to be merged into FF 50?
Flags: needinfo?(vic.portnov)
I tested our extension with the above link (firefox-52.0a1.en-US.mac.dmg) and things are looking pretty good. I'm also interested in getting this fix in earlier versions of FF (50, etc.)
Reading back through these comments, it looks like people think this worked correctly in FF49? If you look at my bug report (https://bugzilla.mozilla.org/show_bug.cgi?id=1309683) that was marked as a duplicate, the example extension attached there does NOT work in FF49. 

I realize a fix may not get back-ported to older versions, but I want to make sure these two issues are in fact duplicates... Thanks!
Whiteboard: triaged → triaged [platform-rel-Symantec]
(In reply to Victor Portnov from comment #51)
> I've tested with win32 try build using test extension and it works fine for
> me now.
> Thank you for the fix!
> 
> May you please let me know when it is going to be merged into FF 50?

Thanks Victor for the prompt verification! This fix will go-live with 50 release. You may also check 50 RC2 build early next week, it should have the fix.
Status: RESOLVED → VERIFIED
FYI: I've retested on official FF beta (v 50) and it works fine. Thank you for the fix.
Version: unspecified → 50 Branch
Product: Toolkit → WebExtensions
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: