Seems like we will have to implement some sort allow invalid certs (it makes
me really sad that the system administrators and/or managers of tcl and telefonica seem
slow to understand the risks of allowing MITM for user credentials).

I like Brian Smith's proposal to add some visual indicator when using
a non-secure connection and I also agree that making users type the
fingerprint (on a mobile device) is also a non-solution.
I propose making the user type something like:

'I understand that my password to use $mailprovider cannot be protected by
firefoxOS'

And then allow the 'one click' override. (ditto for non SSL connections).

Also in all these variations we have not discussed what should happen
if the untrusted cert changes, my guess is that we should show some delta
of the two certs (once we have detected we are not behind a captive portal)

Camilo



On 5/28/14, 4:16 PM, David Keeler wrote:
Regarding the current certificate exception mechanism:

* there is only a single certificate store on the device and therefore
that all exceptions are device-wide
This is an implementation detail - it would not be difficult to change
exceptions to per-principal-per-app rather than just per-principal.

* only one exception can exist per domain at a time
In combination with point 3, is this a limitation? Do we want to support
this? If so, again, it wouldn't be that hard.

* the exception is per-domain, not per-port, so if we add an exception
for port 993 (imaps), that would also impact https.
I don't think this is the case. Either way, it shouldn't be the case.
In summary, it would not be difficult to ensure that the certificate
exception service operates on a per-principal-per-app basis, which would
allow for what we want, I believe (e.g. exceptions for
{email-app}/example.com:993 would not affect {browser-app}/example.com:443).

In terms of solving the issue at hand, we have a great opportunity to
not implement the "press this button to MITM yourself" paradigm that
desktop browsers currently use. The much safer option is to ask the user
for the expected certificate fingerprint. If it matches the certificate
the server provided, then the exception can safely be added. The user
will have to obtain that fingerprint out-of-band over a hopefully secure
channel.
I would be wary of implementing a more involved scheme that involves
remote services.

Cheers,
David

On 05/28/2014 03:30 PM, Andrew Sutherland wrote:
tl;dr: We need to figure out how to safely allow for invalid
certificates to be used in the Firefox OS Gaia email app.  We do want
all users to be able to access their email, but not by compromising the
security of all users.  Read on if you work in the security field / care
about certificates / invalid certificates.


== Invalid Certificates in Email Context

Some mail servers out there use self-signed or otherwise invalid SSL
certificates.  Since dreamhost replaced their custom CA with valid
certificates
(http://www.dreamhoststatus.com/2013/05/09/secure-certificate-changes-coming-for-imap-and-pop-on-homiemail-sub4-and-homiemail-sub5-email-clusters-on-may-14th/)
and StartCom started offering free SSL certificates
(https://www.startssl.com/?app=1), the incidence of invalid certificates
has decreased.  However, there are still servers out there with invalid
certificates.  With deeply regrettable irony, a manufacturer of Firefox
OS devices and one of the companies that certifies Firefox OS devices
both run mail servers with invalid certificates and are our existing
examples of the problem.

The Firefox OS email app requires encrypted connections to servers.
Unencrypted connections are only legal in our unit tests or to
localhost.  This decision was made based on a risk profile of devices
where we assume untrusted/less than 100% secure wi-fi is very probable
and the cellular data infrastructure is only slightly more secure
because there's a higher barrier to entry to setting up a fake cell
tower for active attacks.

In general, other email apps allow both unencrypted connections and
adding certificate exceptions with a friendly/dangerous flow.  I can
speak to Thunderbird as an example.  Historically, Thunderbird and its
predecessors allowed certificate exceptions.  Going into Thunderbird
3.0, Firefox overhauled its exception mechanism and for a short time
Thunderbird's process required significantly greater user intent to add
an exception.  (Preferences, Advanced, Certificates, View Certificates,
Servers, Add Exception.)  At this time DreamHost had invalid
certificates, free certificates were not available, invalid certificates
were fairly common, Thunderbird's autoconfig security model already
assumed a reliable network connection, Thunderbird could only run on
desktops/laptops which were more likely to have a secure network, etc.
We relented and Thunderbird ended up where it is now.  Thunderbird
immediately displays the "Add Security Exception" UI; the user only
needs to click "Confirm Security Exception".  (Noting that Thunderbird's
autoconfig process is significantly more multi-step.)


== Certificate Exception Mechanisms in Platform / Firefox OS

Currently, the only UI affordance to add certificate exceptions is
exposed by the browser app/subystem for HTTPS sites.  I assert that this
is a different risk profile and we wouldn't want to follow it blindly
and don't actually want to follow it at all[1].

There are general bugs filed on being able to import a new CA or
certificate at https://bugzil.la/769183 and https://bugzil.la/867899.
Users with adb push access also have the potentially to manually import
certificates from the command line, see
https://groups.google.com/forum/#!msg/mozilla.dev.b2g/B57slgVO3TU/G5TA-PiFI_EJ


It is my understanding that:
* there is only a single certificate store on the device and therefore
that all exceptions are device-wide
* only one exception can exist per domain at a time
* the exception is per-domain, not per-port, so if we add an exception
for port 993 (imaps), that would also impact https.

And it follows from the above points that exceptions added by the email
app/on the behalf of the email app affect and therefore constitute a
risk to all other apps on the device.  This is significant because
creating an email account may result in us wanting to talk to a
different domain than the user's email address because of the
autoconfiguration process and vanity domains, etc.


== The email app situation

In bug https://bugzil.la/874346 the requirement that is coming from
partners is that:
- we need to imminently address the certificate exception problem
- the user needs to be able to add the exception from the account setup
flow.  (As opposed to requiring the user to manually go to the settings
app and add an exception.  At least I think that's the request.)

Taking this as a given, our goal then becomes to allow users to connect
to servers using invalid certificates without compromising the security
of the users who do use servers with valid certificates or of other apps
on the phone.

There are two main problems that we need solutions to address:

1) Helping the user make an informed and safe decision about whether to
add an exception and what exception to add.  I strongly assert that in
order to do this we need to be able to tell the user with some
confidence whether we believe the server actually has an invalid
certificate, whether the user is apparently behind a corporate MITM
proxy, or whether they're under attack.

2) How to add this exception / allow connecting to servers with invalid
certificates in a safe way.  Key goals are to minimize the privileges of
the email app (we would like for it to be privileged, not certified),
and to minimize risk to other apps.  This includes risks from exposing a
dangerous web activity that malicious apps/websites could use.


== Proposed solution for informed, safe decision-making

I propose that we use a certificate-observatory-style mechanism to
corroborate any invalid certificates by attempting the connection from 1
or more trusted servers whose identity can be authenticated using the
existing CA infrastructure.

For example, if the email app contacts sketchy.example.com and finds the
certificate does not validate, I propose that:

*  TCPSocket/XHR with mozSystem return information on the
certificate/chain that we received.

* We contact the trusted server, for example, certchecker.mozilla.org.
We tell it the domain we tried to contact, the IP, the port, the
protocol, initial-TLS versus startTLS, and the certificate we got back.

* The trusted server attempts to initiate the same connection.
** If a connection occurs, the server checks the certificate it gets
back and returns it to the client as well as a characterization of its
understanding of the situation.  The results would be:
*** "yes, the server has an invalid certificate; the one I got back
matches up exactly with what you told me; let the user choose"
*** "it looks like the certificate would be valid if accessed via a
different domain name, suggest using that domain."  (In theory the
client could make this decision on its own, assuming we expose the legal
alternate names, but the server might be able to know more about this.
The Thunderbird ISP Database can help answer these questions too, so
this might not be needed.)
*** "it looks like you are behind a corporate firewall that MITMs you,
you should add the firewall's CA to your device.  Send the user to a
support page to help walk them through these steps if that seems right."
*** "it looks like the user is under attack"
*** "unable to connect to the server, try again later"
*** "trusted server is degraded, failing to saying no"
*** "other, say no"

* If and only if the trusted server returns a result and says it looks
like an invalid certificate, prompt the user to see if they want to
allow this connection.

* If we can't talk to the trusted server or for any other reason, we do
not allow the user to add the exception/allow the connection.

Note that the email app will not contact the trusted server if it gets a
valid certificate when it talks to the mail server and that we require
consensus between the local device and the server.  The intent is to
ensure the trusted server cannot be used as a mechanism to attack
devices that are operating on a "safe" network or talking to servers
with valid certificates.

In the worst-case scenario where an attacker both compromises the
device's network and also compromises (or is able to impersonate) the
trusted server we effectively degrade to a yes/no prompt.  An attacker
with this level of sophistication likely already has the ability to
attack the user's own mail server and forge SSL certificates, so this
may be the scenario in the attack tree where we inherently lose.  No
obvious solutions jumps out at me other than maintaining a network of
trusted servers with diverse implementations and operators where our
device requires consensus among multiple servers and uses pinned
connections for these servers.

In terms of making the server somewhat smart / able to provide guidance,
the rationale is that at this time we are effectively unable to update
the email app once it has shipped.  So addressing snafus requires being
able to fix things on the server.

I would propose that we do log the certificates/domains/etc. that we see
for the following reasons:

* Gather information about domains that are using invalid certificates
so that we can evangelize improving their certificate or
autoconfiguration story.  This will also allow us to potentially update
the ISPDB for these servers.

* Gather information about corporate MITM proxies in use so that we can
proactively update our support documentation for users.  This might
imply letting the server have a canned mapping from domains to support
URLs that we could suggest.

* Gain statistics about the number of apparent attacks on our email
userbase.


== Proposed solution for exceptions / allowing connections

There are a variety of options here, but I think one stands above the
others.  I propose that we make TCPSocket and XHR with mozSystem take a
dictionary that characterizes one or more certificates that should be
accepted as valid regardless of CA validation state. Ideally we could
allow pinning via this mechanism (by forbidding all certificates but
those listed), but that is not essential for this use-case.  Just a nice
side-effect that could help provide tighter security guarantees for
those who want it.

The rationale for this:

* In conjunction with the trusted server we are able to ensure that the
key the trusted server sees is the key the device sees is the key we are
adding an exception for.  Just saying "oh yeah, the certificate is
invalid" and then re-fetching the certificate separately where a
different answer could come back is obviously less secure.

* It avoids having any bad decisions made inside the email app
potentially affect other apps or other websites.

* Apps with these permissions are already capable of initiating
unencrypted connections or directly sending information to third
parties, so letting them bypass existing certificate checks is arguably
bad only in that there's one less pressure on server operators to have
valid certificates.

* It avoids needing to give the email app access to a super-dangerous
addCertException API.

* It avoids creating a potentially dangerous web activity.  I have
trouble figuring out how this could be safely done unless the
super-certified app that services the activity is instead the one that
talks to the trusted server.  Otherwise we need to authenticate the web
activity based on its origin, or require that the trusted server
generates a cryptographic attestation about it having seen the invalid
certificate and then have the app validate the attestation.

* Any solution that requires the user to manually verify a fingerprint
for security seems guaranteed to not provide any security.


== Other options?

There are likely to be other options I have not considered or
erroneously discounted.  I realize this is a long email and my points at
https://bugzil.la/874346 are also long, but I would appreciate that any
replies read both to make sure we're all on the same page in terms of
risks to users from the compromise of their email account.  (Do feel
free to skim/skip places where it's clear I'm reiterating discussion
points.)


== Venue

I have picked dev.platform for discussion because I think this is an
important discussion that's relevant to a lot of areas and definitely
has platform implications that concern more than just B2G.  I think it
is of particular interest to those on the dev.security,
dev.security.policy, dev.b2g, dev.gaia, and dev.webapi and so I will be
sending individual pointers to this thread from those groups.

Thanks,
Andrew

1: Specifically, in the web browser case, security does not matter for
every website.  When the user clicks through the exception-adding
process, they are hopefully aware of the context and should be aware of
any active disclosures they make on the website.  For example, they
hopefully know to not do something like enter their bank credentials
after we warned them that they're probably not at their bank website.
But security arguably matters for all non-throway email accounts.  To
have your email credentials is to be able to read your email,
impersonate you, receive and delete account/password reset emails.  And
compromise of credentials is persistent until they are reset.
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to