[Slightly off topic] One of the reasons I wouldn't use ID's is because the DOM element with that ID is automatically introduced to the global scope. Open up the console and type "up_8630368" and you will see it yields a DOM Element.
Is this true? If I have a element with id="foo", then "foo" will be available as a variable in the global JS context? I tried, but can't reproduce it (Chrome, Windows & Safari, OS X).
OK, sorry about the reply to myself, but it is true indeed.
I was testing with an id which contains a "-" (hyphen). As the hyphen isn't valid for a variable, you can't access it directly or via the window object (with the "dot" notation). However, it is there, and you can access it with the array-like syntax.
Is this part of the spec? Or creative interpretations?
tl;dr: HTML element with id="foo-bar". You can't access it as the variable foo-bar in the global context or window.foo-bar (invalid var name). However, you can access it via window['foo-bar'].
It started as creative interpretations, then got added to every browser except Firefox , then got added to Firefox because too many websites were relying on it. And now it's in the spec, because too many sites are relying on it, so a browser that doesn't do it wouldn't be web-compatible.
That's per spec. Because the global object can be accessed as window (and several other things…), these global "variables" are therefore merely properties on the window object. It's worthwhile to point out that foo["bar"] and foo.bar are entirely equivalent in ES5 — just the former syntax allows more properties to be expressed as it allows an arbitrary string.
I've been told it's unspecified, but IE implemented it. and when when IE was the most popular browser, other browsers replicated the behaviour as some sites were using it in their JS - as a kind of quick shortcut for document.getElementByID. Don't have a reference though.
It's the DOM element to upvote this whole post at the top of the page.
I agree that polluting JavaScript's global space is bad. I wonder if this could be a vector for some attack. Probably not because it would be well known for a long while (but I didn't know about it untile 5 minutes ago, thanks).
Just recently I saw this used to make a script fail at a very specific point. A script running later expected the first one to have run successfully, opening up an attack vector that works even with CSP in place. The full story is here:
https://github.com/ctfs/write-ups/tree/master/hack-lu-ctf-20...
It seems like you'd need to inject malicious Javascript into the page before you could run an attack like this. General XSS attacks would be the larger, encompassing vulnerability.
In my personal experience, yes. I first found out about it when it broke something. I was using fineuploader, since there was only one element which used fileuploader, it was #fineuploader, and since fineuploader wasn't an AMD module, it exported window.fineuploader() which got blatted by the element.
Wow, today I learned. I've seen iffy situations with name attributes in IE before, I had no idea that IDs became globals... I can't wait for it to bite me
Comments
[Slightly off topic] One of the reasons I wouldn't use ID's is because the DOM element with that ID is automatically introduced to the global scope. Open up the console and type "up_8630368" and you will see it yields a DOM Element.
Upvoted with : up_8630835.click()
same to you, in Firefox.
Is this true? If I have a element with id="foo", then "foo" will be available as a variable in the global JS context? I tried, but can't reproduce it (Chrome, Windows & Safari, OS X).
OK, sorry about the reply to myself, but it is true indeed.
I was testing with an id which contains a "-" (hyphen). As the hyphen isn't valid for a variable, you can't access it directly or via the window object (with the "dot" notation). However, it is there, and you can access it with the array-like syntax.
Is this part of the spec? Or creative interpretations?
tl;dr: HTML element with id="foo-bar". You can't access it as the variable foo-bar in the global context or window.foo-bar (invalid var name). However, you can access it via window['foo-bar'].
It started as creative interpretations, then got added to every browser except Firefox , then got added to Firefox because too many websites were relying on it. And now it's in the spec, because too many sites are relying on it, so a browser that doesn't do it wouldn't be web-compatible.
Classic race to the bottom. :(
That's per spec. Because the global object can be accessed as window (and several other things…), these global "variables" are therefore merely properties on the window object. It's worthwhile to point out that foo["bar"] and foo.bar are entirely equivalent in ES5 — just the former syntax allows more properties to be expressed as it allows an arbitrary string.
I've been told it's unspecified, but IE implemented it. and when when IE was the most popular browser, other browsers replicated the behaviour as some sites were using it in their JS - as a kind of quick shortcut for document.getElementByID. Don't have a reference though.
Seems to be true: https://html.spec.whatwg.org/multipage/browsers.html#named-a...
It's the DOM element to upvote this whole post at the top of the page.
I agree that polluting JavaScript's global space is bad. I wonder if this could be a vector for some attack. Probably not because it would be well known for a long while (but I didn't know about it untile 5 minutes ago, thanks).
Just recently I saw this used to make a script fail at a very specific point. A script running later expected the first one to have run successfully, opening up an attack vector that works even with CSP in place. The full story is here: https://github.com/ctfs/write-ups/tree/master/hack-lu-ctf-20...
It seems like you'd need to inject malicious Javascript into the page before you could run an attack like this. General XSS attacks would be the larger, encompassing vulnerability.
It seems malicious HTML could do it, too, if the global element variable replaces some other global object of the same name.
I did not know this before, very interesting.
Despite the easy access as a global variable, using document.getElementById() turns out to still be faster - http://jsperf.com/id-vs-class-vs-tag-selectors/328
I get that being annoying, but is it really that big of a deal?
In my personal experience, yes. I first found out about it when it broke something. I was using fineuploader, since there was only one element which used fileuploader, it was #fineuploader, and since fineuploader wasn't an AMD module, it exported window.fineuploader() which got blatted by the element.
I don't think it is a big deal. It is just slightly arbitrary, in my opinion.
Wow, today I learned. I've seen iffy situations with name attributes in IE before, I had no idea that IDs became globals... I can't wait for it to bite me