JavaScript: Difference between revisions
m mention "Web API" in "How it works", to clarify, yet again, that JS needs Web APIs to perform side-effects |
ES + WebAPI = JS |
||
| Line 9: | Line 9: | ||
|Logo=JavaScript-logo.png}} | |Logo=JavaScript-logo.png}} | ||
'''[[wikipedia:JavaScript|JavaScript]]''' (''' | '''[[wikipedia:JavaScript|JavaScript]]''' '''(JS)''', not to be confused with '''[[wikipedia:ECMAScript|ECMAScript]] (ES)''', is a [[wikipedia:Programming_language|programming language]] and core technology of [[wikipedia:World_Wide_Web|the Web]], alongside [[wikipedia:HTML|HTML]] and [[wikipedia:CSS|CSS]]. It was created by [[wikipedia:Brendan_Eich|Brendan Eich]] in 1995.<ref>https://exploringjs.com/es5/ch04.html</ref> As of 2025, the overwhelming majority of [[wikipedia:Website|websites]] (98.9%) uses JS for [[wikipedia:Client_(computing)|client]]-side [[wikipedia:Web_page|webpage]] behavior.<ref name="deployedstats">{{cite web |title=Usage Statistics of JavaScript as Client-side Programming Language on Websites |url=https://w3techs.com/technologies/details/cp-javascript |access-date=2024-02-27 |website=W3Techs }}</ref> It's even used on the [[wikipedia:Server_(computing)|server]]-side (see [[wikipedia:Node.js|Node.js]]). | ||
For the entirety of this article (unless stated otherwise) the terms "JavaScript" and "JS" will be defined as "ECMAScript with access to [https://developer.mozilla.org/en-US/docs/Web/API Web APIs]" or "ES+WebAPI" for short. | |||
==Consumer-impact summary== | ==Consumer-impact summary== | ||
| Line 15: | Line 17: | ||
*'''Degraded accessibility''': Dynamic and/or active content is well-known to have poor accessibility for users with visual and/or cognitive impairments. While standards such as [[wikipedia:WAI-ARIA|WAI-ARIA]] were created to mitigate this, it's no silver bullet, especially when developers aren't aware of ARIA. | *'''Degraded accessibility''': Dynamic and/or active content is well-known to have poor accessibility for users with visual and/or cognitive impairments. While standards such as [[wikipedia:WAI-ARIA|WAI-ARIA]] were created to mitigate this, it's no silver bullet, especially when developers aren't aware of ARIA. | ||
*'''Lack of transparency''': To optimize network bandwidth, JS code is typically served in [[wikipedia:Minification_(programming)|minified]] form, which makes it harder to understand for humans. This is particularly problematic if the original source is not publicly [[wikipedia:Source-available_software|available]], which is typically the case of [[wikipedia:Proprietary_software|proprietary software]]. | *'''Lack of transparency''': To optimize network bandwidth, JS code is typically served in [[wikipedia:Minification_(programming)|minified]] form, which makes it harder to understand for humans. This is particularly problematic if the original source is not publicly [[wikipedia:Source-available_software|available]], which is typically the case of [[wikipedia:Proprietary_software|proprietary software]]. | ||
*'''Excessive tracking''': JS is much more capable than HTML and CSS '''combined''' to track user behavior | *'''Excessive tracking''': JS is much more capable than HTML and CSS<!-- See "CSS Exfil": https://www.mike-gualtieri.com/posts/stealing-data-with-css-attack-and-defense/ --> '''combined''' to track user behavior.<ref>https://clickclickclick.click/</ref> JS can communicate with almost any server (only limited by [[wikipedia:Cross-origin_resource_sharing|CORS]]) at any time (limited by connection availability), using a plethora of protocols. JS can get hardware information and compute a [[Device fingerprint|fingerprint of the device]], user, or both.<ref>https://privacycheck.sec.lrz.de/</ref><ref>https://abrahamjuliot.github.io/creepjs</ref><ref>https://www.deviceinfo.me/</ref><ref>{{Cite web |title=Learn how identifiable you are on the Internet |url=https://www.amiunique.org/ |access-date=2026-03-19 |website=Am I Unique ?}}</ref> | ||
*'''Market control''': JS | *'''Market control''': JS is built into almost every web-browser and [[wikipedia:User_agent|user-agent]] (UA), including "light-weight" ones (such as [[wikipedia:W3m|w3m]]), incentivizing companies to use it for everything, since "there's no need to worry about compatibility or portability".<ref>{{Cite web |title=Everyone has JavaScript, right? |url=https://www.kryogenix.org/code/browser/everyonehasjs |url-status=live |archive-url=https://web.archive.org/web/20260316024516/https://www.kryogenix.org/code/browser/everyonehasjs.html |archive-date=2026-03-16 |access-date=2026-03-19 |website=Kryogenix Consulting}}</ref><!-- We need another citation here. The current one is relevant, but doesn't cite anyone who assumes JS is portable. Ideally, it should cite an entity using that quote as an excuse to add JS everywhere --> Some people say that JS shouldn't even exist,<ref>https://daringfireball.net/linked/2017/06/22/navistone-form-data</ref><ref>https://daringfireball.net/linked/2017/06/27/web-without-javascript</ref> implying that it should be an [[wikipedia:Browser_extension|extension]] or [[wikipedia:Plug-in_(computing)|plug-in]] the user willingly installs. | ||
*'''Security risks''': It is well-known that JS is poorly-designed,<ref>https://github.com/denysdovhan/wtfjs</ref><ref>https://github.com/brianleroux/wtfjs</ref><ref>https://wiki.theory.org/YourLanguageSucks#JavaScript_sucks_because</ref><ref>https://github.com/Rudxain/ideas/blob/aa9a80252a4b7c9c51f32eda5c716e96220ed96e/software/evar/with_bf.js</ref> even [[wikipedia:Ecma_International|tc39]] acknowledges that{{Citation needed}}. This leads to programmers and even experienced software-devs to accidentally add vulnerabilities to their code. That, and the fact that | *'''Security risks''': It is well-known that JS is poorly-designed,<ref>https://github.com/denysdovhan/wtfjs</ref><ref>https://github.com/brianleroux/wtfjs</ref><ref>https://wiki.theory.org/YourLanguageSucks#JavaScript_sucks_because</ref><ref>https://github.com/Rudxain/ideas/blob/aa9a80252a4b7c9c51f32eda5c716e96220ed96e/software/evar/with_bf.js</ref> even [[wikipedia:Ecma_International|tc39]] acknowledges that{{Citation needed}}. This leads to programmers and even experienced software-devs to accidentally add vulnerabilities to their code. That, and the fact that ES is [[wikipedia:Turing_completeness|Turing-complete]] (both [https://gavinhoward.com/2024/03/what-computers-cannot-do-the-consequences-of-turing-completeness/#mathematical-vs-practical in practice and in theory]) is a recipe for disaster, as it makes [[wikipedia:Debugging|debugging]] and [[wikipedia:Reverse_engineering|reverse-engineering]] impractical in big code-bases. It's worth noting that tooling, such as [[wikipedia:TypeScript|TypeScript]] and [[wikipedia:ESLint|ESLint]], exist to substantially minimize the likelihood of [[wikipedia:Software_bug|bugs]]. | ||
==How it works== | ==How it works== | ||
Whenever a user visits a webpage, an average web-browser will execute the JS code it finds in <code><script></code> [[wikipedia:HTML_element|tags]]. This code | Whenever a user visits a webpage, an average web-browser will execute the JS code it finds in <code><script></code> [[wikipedia:HTML_element|tags]]. This code could do anything from updating part of the [[wikipedia:Document_Object_Model|DOM]]-tree only when the user requests it, to showing a [[wikipedia:Pop-up_ad|popup/popunder]]. | ||
When JS tries to access a "privacy-sensitive" | When JS tries to access a "privacy-sensitive" API (such as the microphone) the browser pauses it until the user has granted access for the first time. This is typically done on a per-domain basis. However, as mentioned earlier, many other APIs don't need to ask permission before fetching data. | ||
It's worth noting that JS has a privileged position, relative to [[wikipedia:WebAssembly|Wasm]], because of its first-class access to Web APIs. | |||
==Why it is a problem== | ==Why it is a problem== | ||
Many webpages (and even entire websites), force the user to keep JS enabled, otherwise they break or deliberately refuse to work. In 2026, considering the advancements in HTML<!-- TO-DO: cite `<portal>`. I remember an entire website that demos/showcases the Portal API, but can't find it. `<portal>` fixed the fundamental problem that SPAs try to solve, with minimal (or zero!) JS --> and CSS technology, there is minimal reason why an average website (excluding real-time simulations and low-latency gaming) would ''ever'' need JS.<ref>{{Cite web |last=Valkhof |first=Kilian |date=2023-12-02 |title=You don't need JavaScript for that |url=https://www.htmhell.dev/adventcalendar/2023/2/ |url-status=live |archive-url=https://web.archive.org/web/20260308161856/https://www.htmhell.dev/adventcalendar/2023/2/ |archive-date=2026-03-08 |access-date=2026-03-19 |website=HTMHell}}</ref> The only valid justifications are: | Many webpages (and even entire websites), force the user to keep JS enabled, otherwise they break or deliberately refuse to work. In 2026, considering the advancements in HTML<!-- TO-DO: cite `<portal>`. I remember an entire website that demos/showcases the Portal API, but can't find it. `<portal>` fixed the fundamental problem that SPAs try to solve, with minimal (or zero!) JS --> and CSS technology, there is minimal reason why an average website (excluding real-time simulations and low-latency gaming) would ''ever'' need JS.<ref>{{Cite web |last=Valkhof |first=Kilian |date=2023-12-02 |title=You don't need JavaScript for that |url=https://www.htmhell.dev/adventcalendar/2023/2/ |url-status=live |archive-url=https://web.archive.org/web/20260308161856/https://www.htmhell.dev/adventcalendar/2023/2/ |archive-date=2026-03-08 |access-date=2026-03-19 |website=HTMHell}}</ref> The only valid justifications are: | ||
| Line 36: | Line 38: | ||
Expanding on the security risks, these are the most common vulnerabilities found in JS code: | Expanding on the security risks, these are the most common vulnerabilities found in JS code: | ||
*[[wikipedia:Cross-site_scripting|XSS]], which [[wikipedia:NoScript|NoScript]] tries to mitigate | *[[wikipedia:Cross-site_scripting|XSS]], which [[wikipedia:NoScript|NoScript]] tries to mitigate | ||
*[[wikipedia:Arbitrary_code_execution|Arbitrary code execution]] and [[wikipedia:Code_injection|code injection]]. Typically caused by <code>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval eval]</code> (part of the | *[[wikipedia:Arbitrary_code_execution|Arbitrary code execution]] and [[wikipedia:Code_injection|code injection]]. Typically caused by <code>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval eval]</code> (part of the ES spec), but there are Web APIs (such as <code>[https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout setTimeout]</code> and <code>[https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval setInterval]</code>) that can be misused as well. | ||
*Remote code execution. This is used by hackers and crackers to build [[wikipedia:Botnet|bot-nets]] for [[wikipedia:Ddos#Distributed_DoS|DDoS]] or [[wikipedia:Cryptocurrency|crypto]]-mining, but it's mostly used for spyware since it can hide more easily. | *Remote code execution. This is used by hackers and crackers to build [[wikipedia:Botnet|bot-nets]] for [[wikipedia:Ddos#Distributed_DoS|DDoS]] or [[wikipedia:Cryptocurrency|crypto]]-mining, but it's mostly used for spyware since it can hide more easily. | ||
Browser-engine developers (such as [[Google]] and [[Mozilla]]) not only feel compelled, but are economically incentivized to optimize JS to its limits. This leads to complex code-bases that are harder to verify for correctness. Browser vendors mitigate this via [[wikipedia:Sandbox_(computer_security)|sandboxing]]. Unfortunately, since modern browsers compile JS to native CPU code (see [[wikipedia:Just-in-time_compilation|JIT]]) to improve performance, this introduces a higher risk of sandbox-escape.<ref>{{Cite web |last=Norman |first=Johnathan |date=2021-08-04 |title=Super Duper Secure Mode |url=https://microsoftedge.github.io/edgevr/posts/Super-Duper-Secure-Mode/ |url-status=live |archive-url=https://web.archive.org/web/20260218110912/https://microsoftedge.github.io/edgevr/posts/Super-Duper-Secure-Mode |archive-date=2026-02-18 |access-date=2026-03-19 |website=Microsoft Browser Vulnerability Research}}</ref> | Browser-engine developers (such as [[Google]] and [[Mozilla]]) not only feel compelled, but are economically incentivized to optimize JS to its limits. This leads to complex code-bases that are harder to verify for correctness. Browser vendors mitigate this via [[wikipedia:Sandbox_(computer_security)|sandboxing]]. Unfortunately, since modern browsers compile JS to native CPU code (see [[wikipedia:Just-in-time_compilation|JIT]]) to improve performance, this introduces a higher risk of sandbox-escape.<ref>{{Cite web |last=Norman |first=Johnathan |date=2021-08-04 |title=Super Duper Secure Mode |url=https://microsoftedge.github.io/edgevr/posts/Super-Duper-Secure-Mode/ |url-status=live |archive-url=https://web.archive.org/web/20260218110912/https://microsoftedge.github.io/edgevr/posts/Super-Duper-Secure-Mode |archive-date=2026-02-18 |access-date=2026-03-19 |website=Microsoft Browser Vulnerability Research}}</ref> | ||
JS not only makes pages "dynamic", the language itself is very dynamic, which is hard to optimize by engines. To put into perspective how much JS can slow down rendering, someone bench-marked a bloated pure-HTML page and a "simple" [[wikipedia:React_(software)|React]] app, the bloated HTML had faster [https://developer.mozilla.org/en-US/docs/Glossary/First_meaningful_paint FMP].<ref>{{Cite web |last=Leatherman |first=Zach |date=2019-09-06 |title=Which has a better First Meaningful Paint time? |url=https://twitter.com/zachleat/status/1169998370041208832 |url-status=live |archive-url=https://web.archive.org/web/20240529104252/https://x.com/zachleat/status/1169998370041208832 |archive-date=2024-05-29 |access-date=2024-05-29 |website=Twitter/X}}</ref> | JS not only makes pages "dynamic", the language itself (ES) is very dynamic, which is hard to optimize by engines. To put into perspective how much JS can slow down rendering, someone bench-marked a bloated pure-HTML page and a "simple" [[wikipedia:React_(software)|React]] app, the bloated HTML had faster [https://developer.mozilla.org/en-US/docs/Glossary/First_meaningful_paint FMP].<ref>{{Cite web |last=Leatherman |first=Zach |date=2019-09-06 |title=Which has a better First Meaningful Paint time? |url=https://twitter.com/zachleat/status/1169998370041208832 |url-status=live |archive-url=https://web.archive.org/web/20240529104252/https://x.com/zachleat/status/1169998370041208832 |archive-date=2024-05-29 |access-date=2024-05-29 |website=Twitter/X}}</ref> | ||
==Incidents== | ==Incidents== | ||