From 1a48b6abdd27e168c78edcf04a7a9f6a8e0fdc15 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Tue, 27 Aug 2024 00:49:15 -0400 Subject: [PATCH] Document javascript: URLs (#35599) * Document javascript: URLs * Apply suggestions from code review Co-authored-by: Hamish Willee * Mention address bar --------- Co-authored-by: Hamish Willee --- .../webextensions/api/tabs/create/index.md | 4 +- .../webextensions/api/tabs/update/index.md | 4 +- .../mozilla/firefox/releases/127/index.md | 2 +- .../web/api/speculation_rules_api/index.md | 4 +- .../en-us/web/api/window/postmessage/index.md | 2 +- files/en-us/web/html/element/a/index.md | 12 +- files/en-us/web/html/element/base/index.md | 2 +- .../content-security-policy/sources/index.md | 4 +- .../reference/operators/void/index.md | 2 +- .../web/security/same-origin_policy/index.md | 2 +- files/en-us/web/uri/schemes/index.md | 2 +- .../en-us/web/uri/schemes/javascript/index.md | 142 ++++++++++++++++++ 12 files changed, 164 insertions(+), 18 deletions(-) create mode 100644 files/en-us/web/uri/schemes/javascript/index.md diff --git a/files/en-us/mozilla/add-ons/webextensions/api/tabs/create/index.md b/files/en-us/mozilla/add-ons/webextensions/api/tabs/create/index.md index 7b824d7c70aa6f3..7dfdf0fc710dda9 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/tabs/create/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/tabs/create/index.md @@ -59,8 +59,8 @@ let creating = browser.tabs.create( For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail: - chrome: URLs - - javascript: URLs - - data: URLs + - [javascript: URLs](/en-US/docs/Web/URI/Schemes/javascript) + - [data: URLs](/en-US/docs/Web/URI/Schemes/data) - file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below) - privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`). Non-privileged URLs (e.g., `about:blank`) are allowed. - The New Tab page (`about:newtab`) can be opened if no value for URL is provided. diff --git a/files/en-us/mozilla/add-ons/webextensions/api/tabs/update/index.md b/files/en-us/mozilla/add-ons/webextensions/api/tabs/update/index.md index 95f31ac4bbd50b3..92af3572d4c8dc8 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/tabs/update/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/tabs/update/index.md @@ -65,8 +65,8 @@ let updating = browser.tabs.update( For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail, with {{WebExtAPIRef("runtime.lastError")}} being set to an error message: - chrome: URLs - - javascript: URLs - - data: URLs + - [javascript: URLs](/en-US/docs/Web/URI/Schemes/javascript) + - [data: URLs](/en-US/docs/Web/URI/Schemes/data) - file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below) - privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`, `about:newtab`). Non-privileged URLs (e.g., `about:blank`) are allowed. diff --git a/files/en-us/mozilla/firefox/releases/127/index.md b/files/en-us/mozilla/firefox/releases/127/index.md index f8b16778e09897a..33c8461e92ee11c 100644 --- a/files/en-us/mozilla/firefox/releases/127/index.md +++ b/files/en-us/mozilla/firefox/releases/127/index.md @@ -12,7 +12,7 @@ This article provides information about the changes in Firefox 127 that affect d ### HTML -- `data:` and `javascript:` URLs are now forbidden in the [`href`](/en-US/docs/Web/HTML/Element/base#href) attribute of the `` element ([Firefox bug 1850967](https://bugzil.la/1850967)). +- [`data:`](/en-US/docs/Web/URI/Schemes/data) and [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) URLs are now forbidden in the [`href`](/en-US/docs/Web/HTML/Element/base#href) attribute of the `` element ([Firefox bug 1850967](https://bugzil.la/1850967)). ### CSS diff --git a/files/en-us/web/api/speculation_rules_api/index.md b/files/en-us/web/api/speculation_rules_api/index.md index 33523e6e07c6ae3..0e094bc4f177709 100644 --- a/files/en-us/web/api/speculation_rules_api/index.md +++ b/files/en-us/web/api/speculation_rules_api/index.md @@ -387,8 +387,8 @@ APIs that require the containing document's {{domxref("Document.visibilityState" - Download links, i.e. {{htmlelement("a")}} and {{htmlelement("area")}} elements with the `download` attribute, will have their downloads delayed until prerendering has finished. - No cross-site navigations: Any prerendering document that navigates to a different site will be immediately discarded before a request to that other site is sent. - Restricted URLs: Prerendering documents cannot host non-HTTP(S) top-level URLs. Including the following URL types will cause the prerender to be immediately discarded: - - `javascript:` URLs - - `data:` URLs + - [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript) + - [`data:` URLs](/en-US/docs/Web/URI/Schemes/data) - `blob:` URLs - `about:` URLs, including `about:blank` and `about:srcdoc` - Session storage: {{domxref("Window.sessionStorage")}} can be used, but the behavior is very specific, to avoid breaking sites that expect only one page to access the tab's session storage at a time. A prerendered page therefore starts out with a clone of the tab's session storage state from when it was created. Upon activation, the prerendered page's storage clone is discarded, and the tab's main storage state is used instead. Pages that use session storage can use the {{domxref("Document.prerenderingchange_event", "prerenderingchange")}} event to detect when this storage swap occurs. diff --git a/files/en-us/web/api/window/postmessage/index.md b/files/en-us/web/api/window/postmessage/index.md index b12aba85ba6a30d..9bb6d4e299b30c3 100644 --- a/files/en-us/web/api/window/postmessage/index.md +++ b/files/en-us/web/api/window/postmessage/index.md @@ -177,7 +177,7 @@ The value of the `origin` property of the dispatched event is not affected by th For IDN host names only, the value of the `origin` property is not consistently Unicode or punycode; for greatest compatibility check for both the IDN and punycode values when using this property if you expect messages from IDN sites. This value will eventually be consistently IDN, but for now you should handle both IDN and punycode forms. -The value of the `origin` property when the sending window contains a `javascript:` or `data:` URL is the origin of the script that loaded the URL. +The value of the `origin` property when the sending window contains a [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) or [`data:`](/en-US/docs/Web/URI/Schemes/data) URL is the origin of the script that loaded the URL. ### Using window\.postMessage in extensions {{Non-standard_inline}} diff --git a/files/en-us/web/html/element/a/index.md b/files/en-us/web/html/element/a/index.md index 5742a00ba82ea8d..ee56d24c8b9bac4 100644 --- a/files/en-us/web/html/element/a/index.md +++ b/files/en-us/web/html/element/a/index.md @@ -65,14 +65,18 @@ This element's attributes include the [global attributes](/en-US/docs/Web/HTML/G - : The URL that the hyperlink points to. Links are not restricted to HTTP-based URLs — they can use any URL scheme supported by browsers: - - Sections of a page with document fragments - - Specific text portions with [text fragments](/en-US/docs/Web/URI/Fragment/Text_fragments) - - Pieces of media files with media fragments - Telephone numbers with `tel:` URLs - Email addresses with `mailto:` URLs - SMS text messages with `sms:` URLs + - Executable code with [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript) - While web browsers may not support other URL schemes, websites can with [`registerProtocolHandler()`](/en-US/docs/Web/API/Navigator/registerProtocolHandler) + Moreover other URL features can locate specific parts of the resource, including: + + - Sections of a page with document fragments + - Specific text portions with [text fragments](/en-US/docs/Web/URI/Fragment/Text_fragments) + - Pieces of media files with media fragments + - `hreflang` - : Hints at the human language of the linked URL. No built-in functionality. Allowed values are the same as [the global `lang` attribute](/en-US/docs/Web/HTML/Global_attributes/lang). - `ping` @@ -169,7 +173,7 @@ Assistive software has shortcuts to list all links on a page. However, strong li ### onclick events -Anchor elements are often abused as fake buttons by setting their `href` to `#` or `javascript:void(0)` to prevent the page from refreshing, then listening for their `click` events . +Anchor elements are often abused as fake buttons by setting their `href` to `#` or [`javascript:void(0)`](/en-US/docs/Web/URI/Schemes/javascript) to prevent the page from refreshing, then listening for their `click` events. These bogus `href` values cause unexpected behavior when copying/dragging links, opening links in a new tab/window, bookmarking, or when JavaScript is loading, errors, or is disabled. They also convey incorrect semantics to assistive technologies, like screen readers. diff --git a/files/en-us/web/html/element/base/index.md b/files/en-us/web/html/element/base/index.md index 7c5e058c3c4644a..9abbebe84413fcb 100644 --- a/files/en-us/web/html/element/base/index.md +++ b/files/en-us/web/html/element/base/index.md @@ -22,7 +22,7 @@ This element's attributes include the [global attributes](/en-US/docs/Web/HTML/G - `href` - : The base URL to be used throughout the document for relative URLs. Absolute and relative URLs are allowed. - [`data:`](/en-US/docs/Web/URI/Schemes/data) and `javascript:` URLs are not allowed. + [`data:`](/en-US/docs/Web/URI/Schemes/data) and [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) URLs are not allowed. - `target` - : A **keyword** or **author-defined name** of the default {{Glossary("browsing context")}} to show the results of navigation from {{HTMLElement("a")}}, {{HTMLElement("area")}}, or {{HTMLElement("form")}} elements without explicit `target` attributes. The following keywords have special meanings: diff --git a/files/en-us/web/http/headers/content-security-policy/sources/index.md b/files/en-us/web/http/headers/content-security-policy/sources/index.md index 9b0a3cdddb7d2c0..8debb1d4dfe551f 100644 --- a/files/en-us/web/http/headers/content-security-policy/sources/index.md +++ b/files/en-us/web/http/headers/content-security-policy/sources/index.md @@ -60,9 +60,9 @@ Relevant directives include the {{Glossary("fetch directive", "fetch directives" The single quotes are required. - `'unsafe-hashes'` - : Allows enabling specific inline [event handlers](/en-US/docs/Web/Events/Event_handlers). - If you only need to allow inline event handlers and not inline {{HTMLElement("script")}} elements or `javascript:` URLs, this is a safer method than using the `unsafe-inline` expression. + If you only need to allow inline event handlers and not inline {{HTMLElement("script")}} elements or [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript), this is a safer method than using the `unsafe-inline` expression. - `'unsafe-inline'` - - : Allows the use of inline resources, such as inline {{HTMLElement("script")}} elements, `javascript:` URLs, inline event handlers, and inline {{HTMLElement("style")}} elements. + - : Allows the use of inline resources, such as inline {{HTMLElement("script")}} elements, [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript), inline event handlers, and inline {{HTMLElement("style")}} elements. The single quotes are required. - `'none'` - : Refers to the empty set; that is, no URLs match. diff --git a/files/en-us/web/javascript/reference/operators/void/index.md b/files/en-us/web/javascript/reference/operators/void/index.md index eb026e51fc9205f..f4aca5c92ec66d7 100644 --- a/files/en-us/web/javascript/reference/operators/void/index.md +++ b/files/en-us/web/javascript/reference/operators/void/index.md @@ -76,7 +76,7 @@ This is a bit longer than wrapping the function expression in parentheses, which ### JavaScript URIs -When a browser follows a `javascript:` URI, it evaluates the code in the URI +When a browser follows a [`javascript:` URI](/en-US/docs/Web/URI/Schemes/javascript), it evaluates the code in the URI and then replaces the contents of the page with the returned value, unless the returned value is {{jsxref("undefined")}}. The `void` operator can be used to return `undefined`. For example: diff --git a/files/en-us/web/security/same-origin_policy/index.md b/files/en-us/web/security/same-origin_policy/index.md index e5e929db2014730..5d4d6eb11cb2b37 100644 --- a/files/en-us/web/security/same-origin_policy/index.md +++ b/files/en-us/web/security/same-origin_policy/index.md @@ -26,7 +26,7 @@ The following table gives examples of origin comparisons with the URL `http://st ### Inherited origins -Scripts executed from pages with an `about:blank` or `javascript:` URL inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server. +Scripts executed from pages with an `about:blank` or [`javascript:` URL](/en-US/docs/Web/URI/Schemes/javascript) inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server. For example, `about:blank` is often used as a URL of new, empty popup windows into which the parent script writes content (e.g. via the {{domxref("Window.open()")}} mechanism). If this popup also contains JavaScript, that script would inherit the same origin as the script that created it. diff --git a/files/en-us/web/uri/schemes/index.md b/files/en-us/web/uri/schemes/index.md index 27acedf57e0dbd1..b914f7b5e275f39 100644 --- a/files/en-us/web/uri/schemes/index.md +++ b/files/en-us/web/uri/schemes/index.md @@ -27,7 +27,7 @@ protocol: - : {{Glossary("FTP","File Transfer Protocol")}} - `http` / `https` - : Hyper text transfer protocol (Secure) ({{glossary("HTTP")}}/{{glossary("HTTPS")}}) - - `javascript` + - [`javascript`](/en-US/docs/Web/URI/Schemes/javascript) - : URL-embedded JavaScript code - `mailto` - : Electronic mail address diff --git a/files/en-us/web/uri/schemes/javascript/index.md b/files/en-us/web/uri/schemes/javascript/index.md new file mode 100644 index 000000000000000..310f7150be61f7a --- /dev/null +++ b/files/en-us/web/uri/schemes/javascript/index.md @@ -0,0 +1,142 @@ +--- +title: "javascript: URLs" +slug: Web/URI/Schemes/javascript +page-type: guide +spec-urls: https://html.spec.whatwg.org/multipage/browsing-the-web.html#the-javascript:-url-special-case +--- + +{{QuickLinksWithSubpages("/en-US/docs/Web/URI")}} + +> [!WARNING] +> Using `javascript:` URLs on the web is discouraged as it may lead to execution of arbitrary code, similar to the ramifications of using [`eval()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). It may also reduce {{glossary("accessibility")}} because it deviates from normal link behavior. + +**JavaScript URLs**, URLs prefixed with the `javascript:` scheme, are used as fake navigation targets that execute JavaScript when the browser attempts to navigate. If the URL evaluates to a string, it is treated as HTML and rendered by the browser. + +## Syntax + +JavaScript URLs start with the `javascript:` scheme and are followed by JavaScript code. The code will be parsed as a script. + +```url +javascript: +``` + +In this example, the `href` attribute of an `` element is set to a `javascript:` URL that navigates to a new page with the content "Hello, world!": + +```html example-bad +Click me + +``` + +Note that because `javascript:` URLs do not create history entries, there's no way to go back to the previous page without refreshing. + +### Using `javascript:` URLs as form actions + +In this example, the `action` attribute of a `
` element is set to a `javascript:` URL that alerts a message when submitted: + +```html example-bad + + + +
+``` + +Instead of doing this, consider listening for the form's `submit` event and handling it with JavaScript: + +```html example-good +
+ + +
+ +``` + +### Using `javascript:` URLs as iframe sources + +In this example, the `src` attribute of an ` + +``` + +Instead of doing this, consider setting the `srcdoc` attribute instead: + +```html example-good + + +``` + +### Using `javascript:` URLs with window.location + +In this example, the `window.location` property is set to a `javascript:` URL that navigates to a new page with the content "Hello, world!": + +```js example-bad +window.location = "javascript:'Hello world!'"; +``` + +Instead of doing this, consider using [DOM APIs](/en-US/docs/Web/API/HTML_DOM_API) to modify the page content. For example: + +```js example-good +document.body.textContent = "Hello, world!"; +``` + +## Specifications + +{{Specifications}} + +## See also + +- [URIs](/en-US/docs/Web/URI) +- [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP) +- [IANA list of URI schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml)