-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Make Location's toString() actually work #2294
Conversation
I mistakenly copied all boilerplate from IDL’s unforgeable interfaces concept (which was only ever used for Location) and thereby turned the fallback behavior into the actual behavior (or an exception arguably, as [[Configurable]] is false). Fixes #2284.
I wrote tests: web-platform-tests/wpt#4623. Also for the non-IDL bits of Location. https://bugzilla.mozilla.org/show_bug.cgi?id=1333045 is the Gecko bug as per the issue. Will file bugs on other browsers once there's some review. |
LGTM, merge at will. Can you remind me why we have a special toJSON/valueOf/toPrimitive? Maybe adding a note to the spec? |
I think the whole unforgeable setup is to avoid scripts getting confused assuming they found a way to get a correct handle on this object. And those scripts include plugins. So mostly a legacy thing? @bzbarsky would be able to confirm and if so, I suppose I could add a note. |
The original restrictions a very long time ago were prompted by Flash using things like "location.href" to determine the origin of the page for use in its own security checks. But at this point people seem to have a general expectation of being able to use the moral equivalent of "String(location)" for some sort of security purposes, as far as I can tell. This requires the valueOf/@@toPrimitive/toString bits. The toJSON bit was perhaps added because people expected similar things from JSON.stringify(location); worth checking the blame on that one... |
It was added in whatwg/webidl@e1ead07, but there's no pointers... Due to the date I was able to find https://www.w3.org/Bugs/Public/show_bug.cgi?id=20008 which leads to https://lists.w3.org/Archives/Public/public-script-coord/2012JulSep/thread.html#msg144. None of those emails mention |
Should we check what browsers implement here for Location specifically, and maybe back out toJSON if it's not? |
@heycam, do you recall what the story was on toJSON on unforgeable interfaces? As for browsers, looks like neither Safari nor Chrome nor WebKit nightly nor Edge implement the spec bits for toJSON. Firefox does implement them. So I guess if we don't figure out specifically what this was defending against we could just remove it from Firefox and the spec. |
@cdumez you want to look at this issue since you implemented this relatively recently in Safari. Any reason you didn't implement |
/cc @zetafunction as I believe he's working on this area in Blink |
@annevk I don't remember working on this recently in WebKit. As far as I can see, Location's idl does not have a serializer so why do we expect it to have a toJSON()? |
I'm going to tentatively assume @heycam added it because he created a generic unforgeable interfaces design while we only needed one for Location. (The same reason the design included toString() handling which is redundant with Location.) |
Updated the test PR too. |
I guess I added it from some kind of completeness point of view (perhaps a plugin might try to JSONify an |
That attack still seems doable; having a stringifier doesn't save us. http://jsbin.com/xonacebobu/edit?html,console If we want to give that strong "any stringification of location will not be hijackable" guarantee, then we should probably keep toJSON. @cdumez: you asked in web-platform-tests/wpt#4623 (comment) why we expect valueOf to be on the instance. The reason for that, and the rest of the weird stuff going on here, is exactly that "any stringification of location will not be hijackable" guarantee. By adding own properties we ensure that when various parts of JS query for them, they get what we control, not what the page author could control by monkey-patching Object.prototype. |
@domenic My question was about what part of the spec mandates this. But never mind, I finally found it (https://html.spec.whatwg.org/multipage/browsers.html#the-location-interface -> To create a Location object... section). |
Yeah, we should probably add a comment in the IDL block too... |
So we keep |
We basically should decide whether we think this "not hijackable" guarantee is a legacy thing for old flash plugins, or something we want all web code to be able to depend on. If it's legacy then we just go for shortest path to interop, which I guess means removing toJSON. If it's still something we believe in then we should keep toJSON. I don't have a strong opinion here. Does anyone? I've personally never heard of a web developer depending on location being un-hijackable, but absence of evidence is not evidence of absence. Regardless, we should:
|
@erights to what extent do you rely on location being "unforgeable"? Would you prefer it to have an immutable |
I cannot seem to reach @erights. I suggest we go with the majority and drop special |
@annevk Sorry. I think it is fine to drop special handling for |
Proposed commit message:
|
@annevk your commits look good, but I wanted to throw in some additional info. I've added a commit doing so. Let me know what you think! |
Bugs filed for href/toString:
For Symbol.toPrimitive:
For toJSON:
For valueOf:
|
I mistakenly copied all boilerplate from IDL’s unforgeable interfaces concept (which was only ever used for Location) and thereby turned the fallback behavior into the actual behavior (or an exception arguably, as [[Configurable]] is false).
Fixes #2284.