Privacy/Reviews/F1A

From MozillaWiki
Jump to: navigation, search

Document Overview

Feature/Product: Client-Based F1
Projected Feature Freeze Date: 1-Oct-2011
Product Champions: Shane Caraveo
Privacy Champions: Sid Stamm
Security Contact: Curtis Koenig
Document State: [RESOLVED] (18-Oct-2011) complete


Timeline:

Architectural Overview: Done 7-Oct-2011
Recommendation Meeting: Async via email
Wrap-up Meeting: (not necessary)

Architecture

In this section, the product's architecture is described. Any individual components or actors are identified, their "knowledge" or what data they store is identified, and data flow between components and external entities is described.

The main objective of this feature/product is: to enhance the sharing experience of the browser, Firefox, when sharing web sites. F1 streamlines the process of sharing by integrating various share techniques with the browser experience itself.

This release, to be named Firefox Share (alpha), is being thought of as a Labs release of F1 and not ready for prime time releases. Our goal is to get an extension out that we can start getting UX feedback from users and start iterating quickly on features and UX.

The initial release will not be extensible, but we intend to follow up early Q4 with a version that supports extensibility via OpenWebApps services (such as the Status.net addon we have created). While we have not defined Q4 goals yet, it is probable that a beta release for a wider audience, with extensibility, will be in those goals. It is also highly possible that fx-share-addon will merge with the OWA jetpack.

Design Documents: Link to any design or architectural documents here.

The following illustrates how data flows through the F1 Share system. Other mediated activities may be more complex, but for the purpose of this privacy review only the operation of F1 Alpha is documented.

Privacy-F1a-dfd-minimal.png

Other Resources:

dependencies, included with the add-on:

Components

Currently a bunch of code is bundled together as a single add-on. While the architecture of the system is slightly more nuanced, these are the main basic components for the F1 Alpha release:

  • Share Mediator Panel
  • 3rd party webapps
  • Share Mediator Component
  • Share Mediator Panel
    • future ability for general web content to open activity mediators
    • fx-share-addon
      • share mediator based on top of OWA
      • new smtp module for sending emails
  • 3rd party webapp
    • 3 built-in apps for twitter, facebook and gmail
    • future apps loaded from 3rd party sites
  • Share Mediator Component
    • manages mediator panel (UI)
    • manages interaction between mediators and OWA core
    • manages interaction between services and OWA core
    • manages interaction between mediators and services
    • Sole consumer of OWA core (so that functionality is rolled into this component)


Share Mediator Panel

F1 is an implementation of a mediator for the share activity. The Share Mediator Panel is content loaded locally from the addon. APIs (navigator.mozApps.mediator.*) are injected by the mediator class. Communication between the panel and the mediator class are through sdk ports, passing JSON data.

Stored Data:

The mediator panel stores no data (it interacts via Share Mediator Component with 3rd party webapps that do).

Communication with 3rd party webapp components

NOTE: Communication with third party webapps is tunneled through the mediator class. There is no direct conduit between the mediator content and the service content. This information is documented here since the Share Mediator Component simply acts as a proxy between the other two components.

In order to tunnel a call into a service: the Mediator Panel emits a owa.mediator.invoke port message that contains the data necessary to complete the calls below, along with string id's that the service iframe uses to send a response back. To send a response, the service iframe will emit an owa.mediation.success.# or owa.mediation.error.# with the response data.

Each 3rd party webapp that supports the share activity implements the other end of these calls

Direction Message Data Notes
Out: getShareTypeRecipients type of share (e.g. direct, public, group name)
resolveRecipients list of recipients user has entered into TO field
getLogin/getCredentials none
setAuthorization oauth credentials
confirm page data(3) called when the user clicks "send"
logout/clearCredentials none
In: return from getShareTypeRecipients abbreviated contact data for autocompletion support
return from resolveRecipients success/error of recipient validation
return from getLogin user profile profile returned on success
return from confirm (2) success/error of send
return from getParameters parameter information for ui configuration and oauth

Footnotes:

  1. if getLogin returns nothing, the login flow is initiated. If the login type is oauth (defined in the webapp), openwebapps initiates the oauth flow to get the credentials, and passes them to the webapp via the setAuthorization call.
  2. confirm is only called when the user clicks "send" in the chrome based UI.
  3. page information such as URL, opengraph data, Title, select share image (currently the first one found), etc.


Communication with Share Mediator Component

Direction Message Data Notes
In: owa.app.ready origin (scheme/host/port) one call for each 3rd party webapp. received after the webapp has called owa.service.ready
owa.mediation.setup activity object, services list, caller URL data necessary to setup the mediator UI and load webapp iframes
owa.mediation.onLogin authorization credentials if any (e.g. oauth user tokens) response from doLogin
owa.mediation.reconfigure none sent to mediator content to reconfigure (e.g. a share app was installed or removed)
Out: owa.mediation.ready none called by mediator content after load is finished
owa.mediation.sizeToContent width,height request the mediator class to resize the panel to fit the content
owa.mediation.doLogin auth configuration received from service iframe, may contain consumer oauth key/secret requests mediator class to manage logging in for a service
owa.success none sent upon successful send
owa.failure failure message sent upon failure to send

3rd party webapp component

For each installed service that supports a given activity, the mediator content creates an iframe. The mediator class then injects APIs into the service iframe using the addon-sdk worker class.

Currently, F1 does not allow installation of remote services. It installs three services that are contained in the addon, Twitter, Facebook and GMail.

Stored Data:

While a service may store any data it wants in localStorage, these are the data that our implementations store.

What Where
user profile localstorage
users contacts localstorage
users oauth credentials, secrets, etc localstorage (obtained using the Share Mediator Component)

Communication with Share Mediator Panel

Communication with the Share Mediator Panel is tunneled through the Share Mediator Component. There is no direct conduit between the Share Mediator Panel and the 3rd Party Webapp component (even though the mediator content could directly access the service iframe via postmessage, it doesn't). Any call IN will have a response OUT, even if it is an empty response.

Each app that supports the share activity implements these calls, each is registered using the registerHandler API. The built-in apps in Firefox Share have the implemenation.

This mirrors the "Communication with 3rd party webapp components" section of the Share Mediator Panel. See that section for the details of this communication.


Communication with Share Mediator Component

These are all uni-directional calls with the exception of the oauth and sendEmail calls. The implementation of these APIs are in the openwebapps addon (see servicesapi.js).

Direction Message Data Notes
In: service.origin app origin (scheme/host/port)
service.registerHandler none
return from oauth.call results returned by call to oauth endpoint
return from sendEmail.call simple success/failure object
Out: service.ready app origin (scheme/host/port) same as origin in postMessage api
service.registerHandler origin, activity and message all strings used by mediator to call a specific handler (e.g. url, "link.send", "confirm")
oauth.call auth service information, user tokens, url to oauth endpoint, parameters (share data) for oauth call which are sent to oauth endpoints
sendEmail.call user oauth tokens, share data, recipients list

Share Mediator Component

The Share Mediator Component serves two purposes; 1) managing the Share Mediator Panel and mediator APIs, 2) acting as a tunnel between the 3rd party webapps and the rest of the OWA system.

Stored Data:

The mediator class stores no data.


Communication with 3rd Party Oauth Providers

The Share Mediator Component, via the oauthorizer library communicates on behalf of the 3rd party webapp components to obtain oauth tokens. The authentication is performed by the third party site (e.g., facebook.com) in a popup window, which calls back to a special URI that is controlled locally by the Mediator Component.

Direction Message Data Notes
Out: permission request app_id
In: return from permission request oauth token token is stored in 3rd party webapp's localstorage (in browser)


Communication with 3rd Party Email Servers (via SMTP)

To send messages, the Share Mediator Component employs SMTP communication with 3rd party email servers (google mail for starters). The component obtains oauth tokens via the oauth protocol (previous section) and uses those and SMTP to send messages.

Direction Message Data Notes
Out: EHLO hostname ("localhost")
STARTTLS Triggers TLS/secure communication with mail server
AUTH "xoauth" and token Authenticates the user to the SMTP server
MAIL FROM email address
RCPT TO sharing targets
DATA URL, etc Contents of the share message
In: return from various SMTP commands return codes either error or success


Communication with 3rd party webapp components

This mirrors the "Communication with Share Mediator Component" section of the 3rd party webapp component. See that section for the details of this communication.


Communication with Share Mediator Panel

Direction Message Data Notes
Out: owa.app.ready origin sends one call for each service iframe, received after the service iframe has called owa.service.ready
owa.mediation.setup activity object, services list, caller href data necessary to setup the mediator UI and load service iframes
owa.mediation.doLogin authorization credentials if any (e.g. oauth user tokens) response from doLogin
owa.mediation.reconfigure none sent to mediator content to reconfigure (e.g. a share app was installed or removed)
In: owa.mediation.ready none called by mediator content after load is finished
owa.mediation.sizeToContent width,height request the mediator class to resize the panel to fit the content
owa.mediation.onLogin auth configuration received from service iframe, may contain consumer oauth key/secret requests mediator class to manage logging in for a service
owa.success none sent upon successful send
owa.failure failure message sent upon failure to send

User Data Risk Minimization

In this section, the privacy champion will identify areas of user data risk and recommendations for minimizing the risk.

Credentials

There are various credentials employed in this system (oauth tokens) that are used via OWA and the 3rd party webapp components to share information. Additionally, other users of the system could potentially have access to a user's sharing credentials. The OAuth tokens are stored in the apps localStorage.

The Risk is that these credentials might be leaked across third parties or to other users of the system.

Requirement: These credentials are stored by the 3rd party webapp components who use them and only those components (and the browser, extended by the Share Mediator Component) should be able to touch them. Any non-oauth credentials should be stored in the password database (not localstorage) and, when possible, encrypted using the browser's master password.

Resolution:
[RESOLVED] This software only ships with 3rd party webapps that use oauth and store the tokens in localstorage so there is no threat of password leak. When we open F1A to allow users to install additional apps, we will make clear in the documentation how to store different types of credentials properly.

Clearing Private Data

Anything stored persistently should be cleared when the user clears that type of data elsewhere in the browser. For example, when a user clears stored passwords, any passwords that are stored for purposes of sharing should be cleared. The oauth tokens should be removed when the user clears cookies or passwords (since they are related to both).

The Risk is that, while the user may think he is "resetting" credentials stored in his browser, this may not be the case if the 3rd party webapps don't store data in the right place or erase it at the right time.

Requirement: when stored passwords in the browser are cleared, the webapps should delete passwords. Oauth tokens should be deleted when users clear "active logins". Contacts and other account data should be erased when the user clears localstorage.

Recommendation: if a user has not set up Firefox to remember passwords, no passwords should be stored in localstorage by the share add-on or its webapp components (they can be retained in memory, but lost when Firefox is closed).

Resolution:
[RESOLVED] oauth tokens are stored in localStorage and are cleared when users click logout or clear browser's localStorage. Oauth tokens stored by this addon's apps are purged when users clear "active logins".

Browsing History

A subset of the user's browsing history is exposed to third party services. This is done through the core UI and functionality of the product.

The Risk: the user will knowingly provide third parties with insight into what sites they've visited in the past. Browsing history is generally considered to be private, and the disclosure of such data should be calculated. This is a very tiny risk since the whole point of this feature is to share URLs. Nonetheless, the risk is there and unless the user is always at the helm when data sharing happens, it could be leaked without consent.

URLs shortened through a URL shortening service are disclosed to that service. If third-party URL shortening services are used (shorteners not part of the service used for sharing), it must be clear what is happening.

Requirement: The UI must clearly show each URL being shared and with which parties the URL will be shared before it is transmitted. If an additional URL shortening service is used, there must be user intervention before the URL is sent to the service for shortening. (UI can be used to "remember" the user's preference to shorten URLs, but that must be opt-in).

Resolution:
[RESOLVED] UI is clear about with whom users are sharing URLs. Twitter uses its own in-house shortening on the server-side (their end).

Conformity to Private Browsing Mode (If Applicable)

Since sharing is an explicitly user-initiated action (like bookmarking), it can remain available during a private browsing mode.

Recommendation: During a private browsing session, any data automatically obtained (and stored in the webapp components' localstorage) should be retained in volatile memory only. This is data that the user doesn't explicitly ask for, such as automatically synced contacts. New account setup data and other data explicitly "installed" by the user to be stored can be kept (as we do with sync). The data stored in volatile memory during private mode should be "rolled back" or erased when private mode is exited.

Resolution:
[RESOLVED] since the 3rd party webapps use the usual HTML cookies and localstorage, these will be managed by the private browsing service automatically.

Alignment with Privacy Operating Principles

In this section, the privacy champion will identify how the feature lines up with Mozilla's privacy operating principles.

See Also: Privacy/Roadmap_2011#Operating_Principles:

Principle: Transparency / No Surprises

It's pretty clear that this feature is sharing a URL with a third party service, and the UI seems to clearly explain with whom. F1 is Transparent and not really surprising.

Recommendations: none

Principle: Real Choice

This product doesn't retain data not explicitly provided by the users. It's off by default, and does nothing until users authenticate to their services.

Requirement: Provide a way to "forget" or disconnect from a service that has been used for sharing. -mixedpuppy: there is a logout button under the profile picture for each service which clears localstorage (including oauth tokens) for that service.

Principle: Sensible Defaults

This feature is off by default.

Recommendations: none

Principle: Limited Data

The data retained is only that used for sharing (and contact auto-complete). No extra data is retained.

Recommendations: none.

Resolution:
[RESOLVED] there is a logout button in the Share Mediator Panel

Follow-up Tasks and tracking

What Who Bug Details
[DONE] Initial Overview Discussion Sid & Shane Various meetings and iterations. Completed 7-Oct-2011.
[DONE] Discuss Recommendations Sid & Shane Async via email
[DONE] verify data flow with SMTP and Oauth servers Mark Hammond
[DONE] update add-on to purge oauth tokens (via logout() call) when user clears "active logins" via browser's "clear recent history" dialog Shane bug 695259
[DROPPED] disclose URL shortening in Twitter share UI, perhaps "about url shortening" linking to [1] Shane Unnecessary, Twitter uses their own shortener.