1. 8.9 System state and capabilities
      1. 8.9.1 The Navigator object
        1. 8.9.1.1 Client identification
        2. 8.9.1.2 Language preferences
        3. 8.9.1.3 Custom scheme handlers: the registerProtocolHandler() method
          1. 8.9.1.3.1 Security and privacy
        4. 8.9.1.4 Cookies
        5. 8.9.1.5 Plugins

8.9 System state and capabilities

8.9.1 The Navigator object

Navigator

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Window/navigator

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

The navigator attribute of the Window interface must return an instance of the Navigator interface, which represents the identity and state of the user agent (the client), and allows web pages to register themselves as potential protocol handlers:

[Exposed=Window]
interface Navigator {
  // objects implementing this interface also implement the interfaces given below
};
Navigator includes NavigatorID;
Navigator includes NavigatorLanguage;
Navigator includes NavigatorOnLine;
Navigator includes NavigatorContentUtils;
Navigator includes NavigatorCookies;
Navigator includes NavigatorPlugins;
Navigator includes NavigatorConcurrentHardware;

These interface mixins are defined separately so that WorkerNavigator can re-use parts of the Navigator interface.

8.9.1.1 Client identification
interface mixin NavigatorID {
  readonly attribute DOMString appCodeName; // constant "Mozilla"
  readonly attribute DOMString appName; // constant "Netscape"
  readonly attribute DOMString appVersion;
  readonly attribute DOMString platform;
  readonly attribute DOMString product; // constant "Gecko"
  [Exposed=Window] readonly attribute DOMString productSub;
  readonly attribute DOMString userAgent;
  [Exposed=Window] readonly attribute DOMString vendor;
  [Exposed=Window] readonly attribute DOMString vendorSub; // constant ""
};

In certain cases, despite the best efforts of the entire industry, web browsers have bugs and limitations that web authors are forced to work around.

This section defines a collection of attributes that can be used to determine, from script, the kind of user agent in use, in order to work around these issues.

The user agent has a navigator compatibility mode, which is either Chrome, Gecko, or WebKit.

The navigator compatibility mode constrains the NavigatorID interface to the combinations of attribute values and presence of taintEnabled() and oscpu that are known to be compatible with existing web content.

Client detection should always be limited to detecting known current versions; future versions and unknown versions should always be assumed to be fully compliant.

self . navigator . appCodeName

Returns the string "Mozilla".

self . navigator . appName

Returns the string "Netscape".

self . navigator . appVersion

Returns the version of the browser.

self . navigator . platform

Navigator/platform

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the name of the platform.

self . navigator . product

Returns the string "Gecko".

window . navigator . productSub

Returns either the string "20030107", or the string "20100101".

self . navigator . userAgent

Navigator/userAgent

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

WorkerNavigator/userAgent

Support in all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS5+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android12.1+

Returns the complete `User-Agent` header.

window . navigator . vendor

Navigator/vendor

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera15+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android14+

Returns either the empty string, the string "Apple Computer, Inc.", or the string "Google Inc.".

window . navigator . vendorSub

Returns the empty string.

appCodeName

Must return the string "Mozilla".

appName

Must return the string "Netscape".

appVersion

Must return either the string "4.0" or a string representing the version of the browser in detail, e.g. "1.0 (VMS; en-US) Mellblomenator/9000".

platform

Must return either the empty string or a string representing the platform on which the browser is executing, e.g. "MacIntel", "Win32", "FreeBSD i386", "WebTV OS".

product

Must return the string "Gecko".

productSub

Must return the appropriate string from the following list:

If the navigator compatibility mode is Chrome or WebKit

The string "20030107".

If the navigator compatibility mode is Gecko

The string "20100101".

userAgent

Must return the default `User-Agent` value.

vendor

Must return the appropriate string from the following list:

If the navigator compatibility mode is Chrome

The string "Google Inc.".

If the navigator compatibility mode is Gecko

The empty string.

If the navigator compatibility mode is WebKit

The string "Apple Computer, Inc.".

vendorSub

Must return the empty string.

If the navigator compatibility mode is Gecko, then the user agent must also support the following partial interface:

partial interface mixin NavigatorID {
  [Exposed=Window] boolean taintEnabled(); // constant false
  [Exposed=Window] readonly attribute DOMString oscpu;
};

The taintEnabled() method must return false.

The oscpu attribute's getter must return either the empty string or a string representing the platform on which the browser is executing, e.g. "Windows NT 10.0; Win64; x64", "Linux x86_64".

(This is a tracking vector.) Any information in this API that varies from user to user can be used to profile the user. In fact, if enough such information is available, a user can actually be uniquely identified. For this reason, user agent implementers are strongly urged to include as little information in this API as possible.

8.9.1.2 Language preferences
interface mixin NavigatorLanguage {
  readonly attribute DOMString language;
  readonly attribute FrozenArray<DOMString> languages;
};
self . navigator . language

Navigator/language

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

WorkerNavigator/language

Support in all current engines.

Firefox3.5+Safari10+Chrome4+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android4+Safari iOS10+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android10.1+

Returns a language tag representing the user's preferred language.

self . navigator . languages

Navigator/languages

Support in all current engines.

Firefox32+Safari10.1+Chrome37+
Opera24+Edge79+
Edge (Legacy)16+Internet ExplorerNo
Firefox Android32+Safari iOS10.3+Chrome Android37+WebView Android37+Samsung Internet3.0+Opera Android24+

WorkerNavigator/languages

Support in all current engines.

Firefox32+Safari10.1+Chrome37+
Opera24+Edge79+
Edge (Legacy)16+Internet ExplorerNo
Firefox Android32+Safari iOS10.3+Chrome Android37+WebView Android37+Samsung Internet3.0+Opera Android24+

Returns an array of language tags representing the user's preferred languages, with the most preferred language first.

The most preferred language is the one returned by navigator.language.

A languagechange event is fired at the Window or WorkerGlobalScope object when the user agent's understanding of what the user's preferred languages are changes.

language

Must return a valid BCP 47 language tag representing either a plausible language or the user's most preferred language. [BCP47]

languages

Must return a frozen array of valid BCP 47 language tags representing either one or more plausible languages, or the user's preferred languages, ordered by preference with the most preferred language first. The same object must be returned until the user agent needs to return different values, or values in a different order. [BCP47]

Whenever the user agent needs to make the navigator.languages attribute of a Window or WorkerGlobalScope object global return a new set of language tags, the user agent must queue a global task on the DOM manipulation task source given global to fire an event named languagechange at global, and wait until that task begins to be executed before actually returning a new value.

To determine a plausible language, the user agent should bear in mind the following:

(This is a tracking vector.) To avoid introducing any more fingerprinting vectors, user agents should use the same list for the APIs defined in this function as for the HTTP `Accept-Language` header.

8.9.1.3 Custom scheme handlers: the registerProtocolHandler() method

Navigator/registerProtocolHandler

Firefox2+SafariNoChrome13+
Opera11.6+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android4+Safari iOSNoChrome AndroidNoWebView AndroidNoSamsung InternetNoOpera AndroidNo
interface mixin NavigatorContentUtils {
  [SecureContext] undefined registerProtocolHandler(DOMString scheme, USVString url);
  [SecureContext] undefined unregisterProtocolHandler(DOMString scheme, USVString url);
};
window . navigator . registerProtocolHandler(scheme, url)

Registers a handler for scheme at url. For example, an online telephone messaging service could register itself as a handler of the sms: scheme, so that if the user clicks on such a link, they are given the opportunity to use that web site. [SMS]

The string "%s" in url is used as a placeholder for where to put the URL of the content to be handled.

Throws a "SecurityError" DOMException if the user agent blocks the registration (this might happen if trying to register as a handler for "http", for instance).

Throws a "SyntaxError" DOMException if the "%s" string is missing in url.

window . navigator . unregisterProtocolHandler(scheme, url)

Unregisters the handler given by the arguments.

Throws a "SecurityError" DOMException if the user agent blocks the deregistration (this might happen if with invalid schemes, for instance).

Throws a "SyntaxError" DOMException if the "%s" string is missing in url.

The registerProtocolHandler(scheme, url) method steps are:

  1. Let (normalizedScheme, normalizedURLString) be the result of running normalize protocol handler parameters with scheme, url, and this's relevant settings object.

  2. In parallel: register a handler for normalizedScheme and normalizedURLString. User agents may, within the constraints described, do whatever they like. A user agent could, for instance, prompt the user and offer the user the opportunity to add the site to a shortlist of handlers, or make the handlers their default, or cancel the request. User agents could also silently collect the information, providing it only when relevant to the user.

    User agents should keep track of which sites have registered handlers (even if the user has declined such registrations) so that the user is not repeatedly prompted with the same request.

    When the user agent uses this handler for a URL inputURL:

    1. Assert: inputURL's scheme is normalizedScheme.

    2. Let inputURLString be the serialization of inputURL.

    3. Let encodedURL be the result of running UTF-8 percent-encode on inputURLString using the component percent-encode set.

    4. Let handlerURLString be normalizedURLString.

    5. Replace the first instance of "%s" in handlerURLString with encodedURL.

    6. Let resultURL be the result of parsing handlerURLString.

    7. Navigate an appropriate browsing context to resultURL.

    If the user had visited a site at https://example.com/ that made the following call:

    navigator.registerProtocolHandler('web+soup', 'soup?url=%s')

    ...and then, much later, while visiting https://www.example.net/, clicked on a link such as:

    <a href="web+soup:chicken-kïwi">Download our Chicken Kïwi soup!</a>

    ...then the UA might navigate to the following URL:

    https://example.com/soup?url=web+soup:chicken-k%C3%AFwi

    This site could then do whatever it is that it does with soup (synthesize it and ship it to the user, or whatever).

    This does not define when the handler is used. To some extent, the processing model for navigating across documents defines some cases where it is relevant, but in general user agents may use this information wherever they would otherwise consider handing schemes to native plugins or helper applications.

The unregisterProtocolHandler(scheme, url) method steps are:

  1. Let (normalizedScheme, normalizedURLString) be the result of running normalize protocol handler parameters with scheme, url, and this's relevant settings object.

  2. In parallel: unregister the handler described by normalizedScheme and normalizedURLString.


To normalize protocol handler parameters, given a string scheme, a string url, and an environment settings object environment, run these steps:

  1. Set scheme to scheme, converted to ASCII lowercase.

  2. If scheme is neither a safelisted scheme nor a string starting with "web+" followed by one or more ASCII lower alphas, then throw a "SecurityError" DOMException.

    This means that including a colon in scheme (as in "mailto:") will throw.

    The following schemes are the safelisted schemes:

    This list can be changed. If there are schemes that ought to be added, please send feedback.

  3. If url does not contain "%s", then throw a "SyntaxError" DOMException.

  4. Parse url relative to environment.

  5. If that fails, then throw a "SyntaxError" DOMException.

    This is forcibly the case if the %s placeholder is in the host or port of the URL.

  6. If the resulting URL record's scheme is not "https" or the resulting URL record's origin is not same origin with environment's origin, then throw a "SecurityError" DOMException.

  7. Return (scheme, resulting URL string).

    The resulting URL string will by definition not be a valid URL string as it includes the string "%s" which is not a valid component in a URL.

8.9.1.3.1 Security and privacy

Custom scheme handlers can introduce a number of concerns, in particular privacy concerns.

Hijacking all web usage. User agents should not allow schemes that are key to its normal operation, such as an HTTP(S) scheme, to be rerouted through third-party sites. This would allow a user's activities to be trivially tracked, and would allow user information, even in secure connections, to be collected.

Hijacking defaults. User agents are strongly urged to not automatically change any defaults, as this could lead the user to send data to remote hosts that the user is not expecting. New handlers registering themselves should never automatically cause those sites to be used.

Registration spamming. User agents should consider the possibility that a site will attempt to register a large number of handlers, possibly from multiple domains (e.g., by redirecting through a series of pages each on a different domain, and each registering a handler for web+spam: — analogous practices abusing other web browser features have been used by pornography web sites for many years). User agents should gracefully handle such hostile attempts, protecting the user.

Hostile handler metadata. User agents should protect against typical attacks against strings embedded in their interface, for example ensuring that markup or escape characters in such strings are not executed, that null bytes are properly handled, that over-long strings do not cause crashes or buffer overruns, and so forth.

Leaking private data. Web page authors may reference a custom scheme handler using URL data considered private. They might do so with the expectation that the user's choice of handler points to a page inside the organization, ensuring that sensitive data will not be exposed to third parties. However, a user may have registered a handler pointing to an external site, resulting in a data leak to that third party. Implementors might wish to consider allowing administrators to disable custom handlers on certain subdomains, content types, or schemes.

Leaking credentials. User agents must never send username or password information in the URLs that are escaped and included sent to the handler sites. User agents may even avoid attempting to pass to web-based handlers the URLs of resources that are known to require authentication to access, as such sites would be unable to access the resources in question without prompting the user for credentials themselves (a practice that would require the user to know whether to trust the third-party handler, a decision many users are unable to make or even understand).

Interface interference. User agents should be prepared to handle intentionally long arguments to the methods. For example, if the user interface exposed consists of an "accept" button and a "deny" button, with the "accept" binding containing the name of the handler, it's important that a long name not cause the "deny" button to be pushed off the screen.

8.9.1.4 Cookies
interface mixin NavigatorCookies {
  readonly attribute boolean cookieEnabled;
};
window . navigator . cookieEnabled

Navigator/cookieEnabled

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns false if setting a cookie will be ignored, and true otherwise.

The cookieEnabled attribute must return true if the user agent attempts to handle cookies according to HTTP State Management Mechanism, and false if it ignores cookie change requests. [COOKIES]

8.9.1.5 Plugins
interface mixin NavigatorPlugins {
  [SameObject] readonly attribute PluginArray plugins;
  [SameObject] readonly attribute MimeTypeArray mimeTypes;
  boolean javaEnabled();
};

[Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface PluginArray {
  undefined refresh(optional boolean reload = false);
  readonly attribute unsigned long length;
  getter Plugin? item(unsigned long index);
  getter Plugin? namedItem(DOMString name);
};

[Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface MimeTypeArray {
  readonly attribute unsigned long length;
  getter MimeType? item(unsigned long index);
  getter MimeType? namedItem(DOMString name);
};

[Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface Plugin {
  readonly attribute DOMString name;
  readonly attribute DOMString description;
  readonly attribute DOMString filename;
  readonly attribute unsigned long length;
  getter MimeType? item(unsigned long index);
  getter MimeType? namedItem(DOMString name);
};

[Exposed=Window]
interface MimeType {
  readonly attribute DOMString type;
  readonly attribute DOMString description;
  readonly attribute DOMString suffixes; // comma-separated
  readonly attribute Plugin enabledPlugin;
};
window . navigator . plugins . refresh( [ refresh ] )

Updates the lists of supported plugins and MIME types for this page, and reloads the page if the lists have changed.

window . navigator . plugins . length

Returns the number of plugins, represented by Plugin objects, that the user agent reports.

plugin = window . navigator . plugins . item(index)
window . navigator . plugins[index]

Returns the specified Plugin object.

plugin = window . navigator . plugins . item(name)
window . navigator . plugins[name]

Returns the Plugin object for the plugin with the given name.

window . navigator . mimeTypes . length

Returns the number of MIME types, represented by MimeType objects, supported by the plugins that the user agent reports.

mimeType = window . navigator . mimeTypes . item(index)
window . navigator . mimeTypes[index]

Returns the specified MimeType object.

mimeType = window . navigator . mimeTypes . item(name)
window . navigator . mimeTypes[name]

Returns the MimeType object for the given MIME type.

plugin . name

Returns the plugin's name.

plugin . description

Returns the plugin's description.

plugin . filename

Returns the plugin library's filename, if applicable on the current platform.

plugin . length

Returns the number of MIME types, represented by MimeType objects, supported by the plugin.

mimeType = plugin . item(index)
plugin[index]

Returns the specified MimeType object.

mimeType = plugin . item(name)
plugin[name]

Returns the MimeType object for the given MIME type.

mimeType . type

Returns the MIME type.

mimeType . description

Returns the MIME type's description.

mimeType . suffixes

Returns the MIME type's typical file extensions, in a comma-separated list.

mimeType . enabledPlugin

Returns the Plugin object that implements this MIME type.

window . navigator . javaEnabled()

Returns true if there's a plugin that supports the MIME type "application/x-java-vm".

The navigator.plugins attribute must return a PluginArray object.

The navigator.mimeTypes attribute must return a MimeTypeArray object.


A PluginArray object represents none, some, or all of the plugins supported by the user agent, each of which is represented by a Plugin object. Each of these Plugin objects may be hidden plugins. A hidden plugin can't be enumerated, but can still be inspected by using its name.

The fewer plugins are represented by the PluginArray object, and of those, the more that are hidden, the more the user's privacy will be protected. Each exposed plugin increases the number of bits that can be derived for fingerprinting. Hiding a plugin helps, but unless it is an extremely rare plugin, it is likely that a site attempting to derive the list of plugins can still determine whether the plugin is supported or not by probing for it by name (the names of popular plugins are widely known). Therefore not exposing a plugin at all is preferred. Unfortunately, many legacy sites use this feature to determine, for example, which plugin to use to play video. Not exposing any plugins at all might therefore not be entirely plausible.

The PluginArray objects created by a user agent must not be live. The set of plugins represented by the objects must not change once an object is created, except when it is updated by the refresh() method.

Each plugin represented by a PluginArray can support a number of MIME types. For each such plugin, the user agent must pick one or more of these MIME types to be those that are explicitly supported.

The explicitly supported MIME types of a plugin are those that are exposed through the Plugin and MimeTypeArray interfaces. As with plugins themselves, any variation between users regarding what is exposed allows sites to fingerprint users. User agents are therefore encouraged to expose the same MIME types for all users of a plugin, regardless of the actual types supported... at least, within the constraints imposed by compatibility with legacy content.

(This is a tracking vector.) The supported property indices of a PluginArray object are the numbers from zero to the number of non-hidden plugins represented by the object, if any.

(This is a tracking vector.) The length attribute must return the number of non-hidden plugins represented by the object.

The item() method of a PluginArray object must return null if the argument is not one of the object's supported property indices, and otherwise must return the result of running the following steps, using the method's argument as index:

  1. Let list be the Plugin objects representing the non-hidden plugins represented by the PluginArray object.

  2. Sort list alphabetically by the name of each Plugin.

  3. Return the indexth entry in list.

It is important for privacy that the order of plugins not leak additional information, e.g., the order in which plugins were installed.

(This is a tracking vector.) The supported property names of a PluginArray object are the values of the name attributes of all the Plugin objects represented by the PluginArray object.

The namedItem() method of a PluginArray object must return null if the argument is not one of the object's supported property names, and otherwise must return the Plugin object, of those represented by the PluginArray object, that has a name equal to the method's argument.

The refresh() method of the PluginArray object of a Navigator object, when invoked, must check to see if any plugins have been installed or reconfigured since the user agent created the PluginArray object. If so, and the method's argument is true, then the user agent must act as if the location.reload() method was called instead. Otherwise, the user agent must update the PluginArray object and MimeTypeArray object created for attributes of that Navigator object, and the Plugin and MimeType objects created for those PluginArray and MimeTypeArray objects, using the same Plugin objects for cases where the name is the same, and the same MimeType objects for cases where the type is the same, and creating new objects for cases where there were no matching objects immediately prior to the refresh() call. Old Plugin and MimeType objects must continue to return the same values that they had prior to the update, though naturally now the data is stale and may appear inconsistent (for example, an old MimeType entry might list as its enabledPlugin a Plugin object that no longer lists that MimeType as a supported MimeType).


A MimeTypeArray object represents the MIME types explicitly supported by plugins supported by the user agent, each of which is represented by a MimeType object.

The MimeTypeArray objects created by a user agent must not be live. The set of MIME types represented by the objects must not change once an object is created, except when it is updated by the PluginArray object's refresh() method.

(This is a tracking vector.) The supported property indices of a MimeTypeArray object are the numbers from zero to the number of MIME types explicitly supported by non-hidden plugins represented by the corresponding PluginArray object, if any.

(This is a tracking vector.) The length attribute must return the number of MIME types explicitly supported by non-hidden plugins represented by the corresponding PluginArray object, if any.

The item() method of a MimeTypeArray object must return null if the argument is not one of the object's supported property indices, and otherwise must return the result of running the following steps, using the method's argument as index:

  1. Let list be the MimeType objects representing the MIME types explicitly supported by non-hidden plugins represented by the corresponding PluginArray object, if any.

  2. Sort list alphabetically by the type of each MimeType.

  3. Return the indexth entry in list.

It is important for privacy that the order of MIME types not leak additional information, e.g., the order in which plugins were installed.

(This is a tracking vector.) The supported property names of a MimeTypeArray object are the values of the type attributes of all the MimeType objects represented by the MimeTypeArray object.

The namedItem() method of a MimeTypeArray object must return null if the argument is not one of the object's supported property names, and otherwise must return the MimeType object that has a type equal to the method's argument.


A Plugin object represents a plugin. It has several attributes to provide details about the plugin, and can be enumerated to obtain the list of MIME types that it explicitly supports.

The Plugin objects created by a user agent must not be live. The set of MIME types represented by the objects, and the values of the objects' attributes, must not change once an object is created, except when updated by the PluginArray object's refresh() method.

The reported MIME types for a Plugin object are the MIME types explicitly supported by the corresponding plugin when this object was last created or updated by refresh(), whichever happened most recently.

(This is a tracking vector.) The supported property indices of a Plugin object are the numbers from zero to the number of reported MIME types.

(This is a tracking vector.) The length attribute must return the number of reported MIME types.

The item() method of a Plugin object must return null if the argument is not one of the object's supported property indices, and otherwise must return the result of running the following steps, using the method's argument as index:

  1. Let list be the MimeType objects representing the reported MIME types.

  2. Sort list alphabetically by the type of each MimeType.

  3. Return the indexth entry in list.

It is important for privacy that the order of MIME types not leak additional information, e.g., the order in which plugins were installed.

(This is a tracking vector.) The supported property names of a Plugin object are the values of the type attributes of the MimeType objects representing the reported MIME types.

The namedItem() method of a Plugin object must return null if the argument is not one of the object's supported property names, and otherwise must return the MimeType object that has a type equal to the method's argument.

The name attribute must return the plugin's name.

The description and filename attributes must return implementation-defined (in all likelihood, plugin-defined) strings. In each case, the same string must be returned each time, except that the strings returned may change when the refresh() method updates the object.

(This is a tracking vector.) If the values returned by the description or filename attributes vary between versions of a plugin, they can be used both as a fingerprinting vector and, even more importantly, as a trivial way to determine what security vulnerabilities a plugin (and thus a browser) may have. It is thus highly recommended that the description attribute just return the same value as the name attribute, and that the filename attribute return the empty string.


A MimeType object represents a MIME type that is, or was, explicitly supported by a plugin.

The MimeType objects created by a user agent must not be live. The values of the objects' attributes must not change once an object is created, except when updated by the PluginArray object's refresh() method.

The type attribute must return the valid MIME type string with no parameters describing the MIME type.

The description and suffixes attributes must return implementation-defined (in all likelihood, plugin-defined) strings. In each case, the same string must be returned each time, except that the strings returned may change when the refresh() method updates the object.

(This is a tracking vector.) If the values returned by the description or suffixes attributes vary between versions of a plugin, they can be used both as a fingerprinting vector and, even more importantly, as a trivial way to determine what security vulnerabilities a plugin (and thus a browser) may have. It is thus highly recommended that the description attribute just return the same value as the type attribute, and that the suffixes attribute return the empty string.

Commas in the suffixes attribute are interpreted as separating subsequent filename extensions, as in "htm,html".

The enabledPlugin attribute must return the Plugin object that represents the plugin that explicitly supported the MIME type that this MimeType object represents when this object was last created or updated by refresh(), whichever happened most recently.


(This is a tracking vector.) The navigator.javaEnabled() method must return true if the user agent supports a plugin that supports the MIME type "application/x-java-vm"; otherwise it must return false.