Plugins:PluginDirectory/HowPluginDetectionWorks: Difference between revisions

Jump to navigation Jump to search
no edit summary
(Created page with 'Building a service to help keep plugins up to date is hard. __TOC__ == Browser identification == The first step in the process is identifying the user's browser. This consist…')
 
No edit summary
Line 7: Line 7:
of determining values for the following properties:
of determining values for the following properties:


; appID : A unique identifier for the browser application (eg. {ec8030f7-c20a-464f-9b0e-13a3a9e97384}, Safari)
; appID : A unique identifier for the browser application (eg. <code>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</code> for Firefox, <code>Safari</code> for Safari)
; appRelease : The official release version number for the browser (eg. 3.5.8, 4.0.4)
; appRelease : The official release version number for the browser (eg. 3.5.8, 4.0.4)
; appVersion : A more specific indicator of the release build (eg. 20100202, 531.21.10)
; appVersion : A more specific indicator of the release build (eg. 20100202, 531.21.10)
; clientOS : An identifier describing the OS on which the browser runs (eg. Intel Mac OS X 10.6)
; clientOS : An identifier describing the OS on which the browser runs (eg. Windows NT 6.1, Linux i686, Intel Mac OS X 10.6)
; locale : The primary locale / language chosen by the user (eg. en-US, zn-CH)
; chromeLocale : The primary locale / language chosen by the user (eg. en-US, zn-CH)


Although most plugins are compatible with a wide range of values for the above
Although most plugins are compatible with a wide range of values for the above
Line 37: Line 37:
You might notice that this list is missing a few particularly useful details:
You might notice that this list is missing a few particularly useful details:


=== No GUIDs or UUIDs ===
=== No reliable GUIDs or UUIDs ===


There is no unique identifier, such as a GUID or UUID.
There is no reliable unique identifier, such as a GUID or UUID.


This means that we'll need to use a combination of all of these properties
This means that we'll need to use a combination of all of the above properties
to uniquely identify a plugin, any of which has the potential to change between
to uniquely identify a plugin, any of which has the potential to change between
plugin versions.  
plugin versions.  


For example, the plugin for Adobe Flash has gone through many
For example: The Adobe Flash plugin has gone through many changes throughout
changes throughout its lifespan, both through changes in the name of the product
its lifespan, both through changes in the name of the product itself to the
itself to the acquisition of Macromedia by Adobe.
acquisition of Macromedia by Adobe.


=== Version is not directly exposed ===
=== Version is not directly exposed, scraped from name / description ===


A version property is not supplied by most browsers for plugins in
A version property for plugins is not exposed by most browsers in
<code>navigator.plugins</code>.
<code>navigator.plugins</code>.


While most plugins include some expression of a version in the name or
Most plugins include some expression of a version in the name or
description, this version does not always exactly match the '''fully  
description.  But, this version does not always exactly match the  
qualified version''' of the plugin.   
'''fully qualified version number''' of the plugin.  Thus, there can be some
discrepancy or fuzziness in version detection.


For example, use the '''Tools > Add-ons''' menu in Firefox to open the Add-ons dialog
For example, use the '''Tools > Add-ons''' menu in Firefox to open the Add-ons dialog
and view the Plugins tab. If you have "Shockwave Flash" installed, you may see
and view the Plugins tab. If you have "Shockwave Flash" installed, you may see
it reported as version 10.0.45.2.  
it reported as version 10.0.45.2.  However, this version is not usually available via
<code>navigator.plugins</code>. Instead, client-side detection code has to
inspect the name or description - which lists the version as "10.0 r45".
 
So, suppose that there were two releases of Flash - say, versions 10.0.45.2 and
10.0.45.6. Now suppose that they both listed "10.0 r45" as the version in the
description. Since client-side code can't see the real '''fully qualified version number'''
for either plugin, it can't tell a difference between the two. And, if it can't
tell a difference, then there's no way to decide whether an upgrade is advisable.


However, this version is not usually available via
In practice, the Adobe Flash plugin in particular tends to update that version in
<code>navigator.plugins</code>. So, instead, client-side detection code has to
the description between siginificant updates - but not all plugins do. So, plugin
inspect the name or description - which lists the version as "10.0 r45".
version detection can be problematic and imprecise.


And, what's worse: Some plugins don't include a version number at all in either
And, what's worse: Some plugins don't include a version number at all, in either
the name or description. In this case, there's not much we can do besides shrug
the name or description. In this case, there's not much we can do besides shrug
and report the version as undetectable.
and report the version as undetectable.


Firefox 3.6 and above ''does'' offer a separate version property
On the bright side, Firefox 3.6 and above ''does'' offer a version property in
<code>navigator.plugins</code>, which reflects the '''fully qualified version number'''
as seen in the Add-ons dialog. In this case, we can detect plugin versions with
great certainty. Hopefully more browsers follow suit in this, and the plugin
version detection story will get better.
 
== Server-side plugin search ==
 
One of the [[Plugins:PluginDirectory#Goals|goals of the Plugin Directory]] is
to provide a service allowing clients to check whether installed plugins are
up-to-date or in need of an upgrade, by performing a search on directory data.
 
The first thing the service requires are all the details revealed by
[[Plugins:PluginDirectory/HowPluginDetectionWorks#Browser_identification|browser identification]].
This allows the search to be restricted to just those plugins asserting
compatibility with the user's browser.
 
The second thing the service requires are details revealed by the
[[Plugins:PluginDirectory/HowPluginDetectionWorks#Client_plugin_scan|client plugin scan]].
One of the most unique properties of a plugin is the set of MIME types it
claims to handle, so sending that along will further restrict the search
to plugins that likely contain a given installed plugin.
 
(By the way: While it might be useful to send along other details - such as name,
description, or filename - these change more often than the set of MIME types,
and don't actually help narrow down the search enough to be worth the trouble.)
 
=== PFS2 search API ===
 
The above is a plain-language description of [[PFS2#Request_Parameters|the PFS2 search API]].
This is a simple HTTP GET service which responds with a JSON data structure, given
the following URL parameters:
 
; <tt>mimetype</tt> : A space-separated list of mimetypes for a plugin. (Note: space can be encoded as <tt>+</tt> in URLs.)
; <tt>detection</tt> : An identifier for the form of version detection available to the client (eg. 'original' for name/description scraping, 'version_available' for Fx 3.6 and above where a real version is available)
; <tt>clientOS</tt> : The client's OS (eg. <tt>navigator.oscpu</tt>, "Windows NT 5.1", "Intel Mac OS X 10.5")
; <tt>chromeLocale</tt> : The client's locale (eg. <tt>navigator.language</tt>)
; <tt>appID</tt> : The client's app ID (eg. Firefox is "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}")
; <tt>appRelease</tt> : Client app release version (eg. "3.5.3")
; <tt>appVersion</tt> : Client's application build version (eg. "20090824085414")
; <tt>callback</tt> : Function wrapper for JSON output, (see also: [http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ JSONP technique])
 
==== Example PFS2 request / response ====
 
So, suppose you wanted to search for the Flash plugin.  On the
Plugin Directory staging server, you could perform an HTTP GET like the following,
using cURL (line breaks added for clarity):
 
    curl -s 'http://plugins.stage.mozilla.com/en-us/pfs/v2?
        appID=%7Bec8030f7-c20a-464f-9b0e-13a3a9e97384%7D&
        appRelease=3.5.8&
        appVersion=20100202152834&
        clientOS=Intel+Mac+OS+X+10.6&
        chromeLocale=en-US&
        detection=original&
        mimetype=application%2Fx-shockwave-flash+application%2Ffuturesplash'
 
This might result in the following JSON, for example:


    [
        {
            "releases": {
                "others": [],
                "latest": {
                    "app_release": "*",
                    "fetched": "2010-02-18T19:06:27-08:00",
                    "locale": "*",
                    "app_id": "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
                    "detection_type": "original",
                    "guid": "{89977581-9028-4be0-b151-7c4f9bcd3211}",
                    "xpi_location": "http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-mac.xpi",
                    "pfs_id": "adobe-flash-player",
                    "version": "10.0.32.0",
                    "app_version": "*",
                    "status": "latest",
                    "os_name": "mac",
                    "vendor": "Adobe",
                    "detected_version": "10.0.32.0",
                    "name": "Adobe Flash Player",
                    "created": "2010-02-19T08:09:18+00:00",
                    "url": "http://www.adobe.com/go/getflashplayer",
                    "modified": "2010-02-19T08:11:10+00:00",
                    "license_url": "http://www.adobe.com/go/eula_flashplayer"
                }
            },
            "aliases": {
                "regex": [
                    ".*Flash.*"
                ],
                "literal": [
                    "Adobe Flash Player",
                    "Shockwave Flash"
                ]
            }
        }
    ]


== Server-side plugin search ==
A more detailed description of this exchange is available in
[[PFS2#Plugin_release_descriptions|the wiki page on the PFS2 API]].


== Client-side plugin matching ==
== Client-side plugin matching ==
A single search request is made to the PFS2 API for each plugin detected.
Since multiple plugins can claim to handle the same set of MIME times passed
to the search API, multiple plugin results may be returned.
=== Plugin name matching via aliases ===
So, the next step is to look at each of these results and use the "aliases"
data stucture to match against the detected plugin's name.  If the name
matches either one of the literal strings values, or one of the regular
expressions, then that search result is paired up with the detected plugin.
Note that this alias matching system helps account for name changes
between plugin releases - eg. Shockwave Flash to Adobe Flash Player, as
a hypothetical example.
For example: Assume that a plugin named "QuickTime Plug-in" was detected,
which claims to handle the MIME type "video/mpeg". 
In response to a search including a MIME type of "video/mpeg", the search API
might respond with results including the plugins "VLC Multimedia Plug-in" and
"QuickTime Plug-in".  We can use the aliases of the "QuickTime Plug-in" result
to pair it up with our detected plugin, and go from there.
=== Version comparison ===
Once we have a search result paired with a detected installed plugin, we can
perform version comparisons.
For quick access, the latest release of a plugin is pulled out of the general
list of plugin releases known by the directory.  A comparison between this
release and the detected plugin can result in one of the following results:
; current : The installed plugin is the up-to-date with respect to the directory
; newer : The installed plugin appears to be newer than what the directory knows about
; should_disable : The installed plugin matches the latest known version, but that version has a known vulnerability and should be disabled until an update is made available.
; maybe_outdated: Version detection for this plugin is imprecise, and matches both the latest version as well as a version known to be out of date.  Manual inspection is advised.
; maybe_vulnerable : Version detection for this plugin is imprecise, and matches both the latest version as well as a version with a known vulnerability.  Manual inspection is advised.
If the installed plugin doesn't match or exceed the version of the latest known
release, then we know an upgrade is advised.  But, we want to report on the
urgency of the upgrade. 
So, we step through the other known releases, looking
for vulnerable versions.  This will then result in one of the following
status flags:
; outdated : The installed plugin should be upgraded, but is not an immediate danger
; vulnerable : The installed plugin matches a version with a known vulnerability, and should be updated immediately
Confirmed users
920

edits

Navigation menu