Re: [blink-dev] Re: (Pre-)Intent to Deprecate: <keygen> element and application/x-x509-*-cert MIME handling

On Wed, Aug 26, 2015 at 1:36 AM Henry Story <henry.story@gmail.com> wrote:

> On 26 Aug 2015, at 02:21, samuelhorwitz@gmail.com wrote:
>
> One of the main differences between Webcrypto and keygen besides the
> ability to work with the server to create TLS certs is that the only secure
> browser chrome driven system that seems to exist for user security is TLS
> client auth. Webcrypto solves a lot of issues in theory by making private
> keys non-extractable by choice and the API immutable but the weakness that
> still exists in an overarching fashion is the nature of control the server
> has over the executing JS. Ideally, there should be some sort of visual
> component to Webcrypto that allows it to work purely in the interest of the
> user, such that a malicious server is unable to purposefully get ahold of a
> private key whether by using handrolled crypto libs that appear to work as
> intended but arent native and therefore exposing the private key to the
> server invisibly or even just the server setting extractable to true and
> getting the private key invisibly (invisibly assuming the person isn't
> combing their network requests). There needs to be some sort of browser
> chrome driven way for the user to be confident that a malicious server
> simply could not get ahold of their private keys because their private keys
> were generated in browser, unextractably. The only interface that exists
> for anything like this at all is keygen and client cert chrome. I do not
> believe this is an absurd use case given that web crypto is a standard now.
> The key discovery standard which no one has implemented yet may address
> some of these things, I am unsure, but the point still stands that whether
> client auth TLS is a good thing or not, there really should be some sort of
> in browser crypto that truly works in favor of the user even so that a
> malicious server cannot "win" by dictating all facets of the JS execution.
>
>
> I think one can make a slightly stronger point. You speak here of a
> malicious server. What people tend to think of here is a server that has
> been broken into, and root taken. Perhaps code in the Apache or Ngingx
> server has been changed surrpetitiously. The problem is: nothing this
> dramatic needs to have taken place.
>
> With javascript same origin policy and some HTTP upload method like WebDAV
> - even if well secured to only allow a specific set of users to upload
> anything - any javascript uploaded to the origin anywhere can potentially
> get access to those private keys in the browser local storage and then use
> it to impersonate the user. This is not true of uploaded html, css, or any
> other data. Furthermore: since JS is turing complete language, it can be
> near impossible for an advanced programmer to tell if a piece of code
> uploaded is actually doing something malicious.
>

That's not quite how it works. Stray JS files are fine because they don't
execute when you navigate to them. It's stray HTML files that are a problem
because those are executable formats.

(NB: Don't have stray files on your code origin in general. There are
interesting interactions with MIME sniffing, headers to disable it, CSP,
etc. This mail is not thorough web security advice. Please consult your
local web security expert and copy of The Tangled Web.)


> The only way to secure a server then is to not allow any upload anywhere
> of any JS. But then how would one use the JS Crypto libs?
>

No, the way to do this is to separate your code and data. Don't allow
random HTTP upload of executable resources (i.e. HTML) under the origin
that speaks for your code. If you need to host user-uploaded files then you
have a number of options, the simplest of which is to use a different
origin (e.g. github.io, googleusercontent.com). WebDAV is probably not the
best mechanism and accordingly you don't see much use of it.


> If the JS crypto libs had a way to get the user to sign things through the
> chrome and everyone be guaranteed that the JS never had access to the
> private keys, then it would be possible to distinguish who had signed what
> with the private key x of some public key.
>

The origin that owns the key is the one that's allowed to use WebCrypto or
any other JS API on it. That's how platforms with application isolation
work. Each application has their own state and can do what they like with
it.

If there's another application that's not mutually-trusting, that
application MUST live on a different origin. <keygen> does not save you
from that; you're fixating on the keys, but keys are just random state.
Your auth application may have other state too---a cookie here, some
preference there, some user contact information here, a live document with
a password form there---It would be just as unacceptable to leak those as
it would be for keys.

Should the other origin wish to do key operations, which is what I think
you're alluding to with user-uploaded JS, we have cross-origin channels,
such as postMessage. The auth origin is free to interpret postMessage and
friends as it likes.

The browser tells the user what top-level origin is in control, and the
rest is your business. YOU get to decide what "good UI design" means. YOU
get to decide what kinds of operations to allow. Is a signing oracle okay?
Maybe, maybe not. Maybe you want to require that the message signed always
includes the origin's name. Maybe you allow the operation, but only after
user prompt. The auth origin can implement all that and more.

The browser doesn't know any of that. If we try to enforce things at the
level of keys, no "good UI design" will make "hey, is it okay to sign this
hexdump with that key?" usable. You want questions like "hey, is it okay
for Fancy TODO List to read your email?" Only applications know what their
private state means. We can only enforce high-level things: application
isolation, what application is active, don't access the webcam, etc.

David


> This would of course then require some good UI design in the chrome -
> which is unavoidable in the end. But I at least don't believe that this is
> an impossible task. It's just more complex for things that go beyond the
> micro capacities of TLS client certificate authentication.
>
> Henry
>
>
>
> On Tuesday, July 28, 2015 at 3:46:51 PM UTC-4, Ryan Sleevi wrote:
>>
>> Primary eng (and PM) emails
>> rsl...@chromium.org
>>
>> Summary
>> This is an intent to deprecate, with the goal of eventually removing,
>> support for the <keygen> element [1], along with support for special
>> handling for the application/x-x509-user-cert [2].
>>
>> This is a pre-intent, to see if there are any show-stopping use cases or
>> compatibility risks that have hitherto been unconsidered.
>>
>> [1] https://html.spec.whatwg.org/multipage/forms.html#the-keygen-element
>> [2] https://wiki.mozilla.org/CA:Certificate_Download_Specification
>>
>> Motivation
>> History: <keygen> was an early development by Mozilla to explore
>> certificate provisioning. Originally Firefox exclusive, it was adopted by
>> several mobile platforms (notably, Nokia and Blackberry), along with
>> support for the certificate installation mime-types. During the First
>> Browser Wars, Microsoft provided an alternative, via ActiveX, called
>> CertEnroll/XEnroll. When iOS appeared on the scene, <keygen> got a boost,
>> as being the initial way to do certificate provisioning, and along with it
>> brought support into Safari. It was then retro-spec'd into the HTML spec.
>>
>> Issues: There are a number of issues with <keygen> today that make it a
>> very incompatible part of the Web Platform.
>> 1) Microsoft IE (and now Edge) have never supported the <keygen> tag, so
>> its cross-browser applicability is suspect. [3] Microsoft has made it
>> clear, in no uncertain terms, they don't desire to support Keygen [4][5]
>> 2) <keygen> is unique in HTML (Javascript or otherwise) in that by
>> design, it offers a way to persistently modify the users' operating system,
>> by virtue of inserting keys into the keystore that affect all other
>> applications (Safari, Chrome, Firefox when using a smart card) or all other
>> origins (Firefox, iOS, both which use a per-application keystore)
>> 3) <keygen> itself is not implemented consistently across platforms, nor
>> spec'd consistently. For example, Firefox ships with a number of extensions
>> not implemented by any other browser (compare [6] to [7])
>> 4) <keygen> itself is problematically and incompatibly insecure -
>> requiring the use of MD5 in a signing algorithm as part of the SPKAC
>> generated. This can't easily be changed w/o breaking compatibility with UAs.
>> 5) <keygen> just generates keys, and relies on application/x-x509-*-cert
>> to install certificates. This MIME handling, unspecified but implemented by
>> major browsers, represents yet-another-way for a website to make persistent
>> modifications to the user system.
>> 6) Mozilla (then Netscape) quickly realized that <keygen> was inadequate
>> back in the early 2000s, and replaced it with
>> window.crypto.generateCRMFRequest [8], to compete with the
>> CertEnroll/XEnroll flexibility, but recently removed support due to being
>> Firefox only. This highlights that even at the time of introduction,
>> <keygen> was inadequate for purpose.
>>
>> [3]
>> https://connect.microsoft.com/IE/feedback/details/793734/ie11-feature-request-support-for-keygen
>> [4] https://lists.w3.org/Archives/Public/public-html/2009Sep/0153.html
>> [5] https://blog.whatwg.org/this-week-in-html5-episode-35
>> [6] https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen
>> [7] https://html.spec.whatwg.org/multipage/forms.html#the-keygen-element
>> [8]
>> https://developer.mozilla.org/en-US/docs/Archive/Mozilla/JavaScript_crypto/generateCRMFRequest
>>
>> Compatibility Risk
>> While there is no doubt that <keygen> remains used in the wild, both the
>> use counters [9] and Google's own crawler indicate that it's use is
>> extremely minimal. Given that Mozilla implements a version different than
>> the HTML spec, and given that Microsoft has made it clear they have no
>> desire to implement, the compatibility risk is believed to be low in
>> practice.
>>
>> Mozilla is also exploring whether or not to remove support for the
>> application/x-x509-*-cert types [10], but has not yet (to my knowledge)
>> discussed <keygen> support - either aligning with the (much more limited)
>> spec, extending the spec with the Mozilla-specific extensions, or removing
>> support entirely.
>>
>> On the application/x-x509-*-cert support, there is a wide gap of
>> interoperability. Chrome does not support multiple certificates, but
>> Firefox does. Firefox will further reorder certificates that are
>> inconsistent with what was specified, offering a non-standard behaviour.
>> Chrome does not support application/x-x509-ca-cert on Desktop, and on
>> Android, defers to the platform capabilities, which further diverge from
>> Firefox. Both browsers have the underspecified behaviour of requiring the
>> user having a matching key a-priori, except that's not detailed as to how
>> it works. Firefox also handles various mis-encodings (improper DER, DER
>> when it should be base64), which Chrome later implemented, but is not well
>> specified.
>>
>> [9]
>> https://www.chromestatus.com/metrics/feature/popularity#HTMLKeygenElement
>> [10] https://bugzilla.mozilla.org/show_bug.cgi?id=1024871
>>
>> Alternative implementation suggestion for web developers
>> The primary use cases for <keygen>, from our investigations, appear to be
>> tied to one of two use cases:
>> - Enterprise device management, for which on-device management
>> capabilities (Group Policies, MDM profiles, etc) represent a far more
>> appropriate path. That is, you would not expect a web page to be able to
>> configure a VPN or a users proxy, so too should you not expect a webpage to
>> configure a user's system key store.
>> - CA certificate enrollment, for which a variety of alternatives exist
>> (e.g. integrated to the web server, CA specific-tools such as SSLMate or
>> protocols such as Let's Encrypt, etc). Here again, it does not seem
>> reasonable to expect your web browser to configure your native e-mail
>> client (such as for S/MIME)
>>
>> Within the browser space, alternatives exist such as:
>> - Use the device's native management capabilities if an enterprise use
>> case. On Windows, this is Group Policy. On iOS/Android, this is the mobile
>> device management suites. On OS X, this is Enterprise settings. On
>> ChromeOS, there is chrome.enterprise.platformKeys [11] for
>> enterprise-managed extensions.
>> - Use WebCrypto to implement certificate enrollment, then deliver the
>> certificate and (exported) private key in an appropriate format for the
>> platform (such as PKCS#7) and allow the native OS UI to guide users through
>> installation of certificates and keys.
>>
>> On some level, this removal will remove support for arbitrarily adding
>> keys to the users' device-wide store, which is an intentional, by-design
>> behaviour.
>>
>> While a use case exists for provisioning TLS client certificates for
>> authentication, such a use case is inherently user-hostile for usability,
>> and represents an authentication scheme that does not work well for the
>> web. An alternative means for addressing this use case is to employ the
>> work of the FIDO Alliance [12], which has strong positive signals from
>> Microsoft and Google (both in the WG), is already supported via extensions
>> in Chrome [13], with Mozilla evaluating support via similar means [14].
>> This offers a more meaningful way to offer strong, non-phishable
>> authentication, in a manner that is more privacy preserving, offers a
>> better user experience, better standards support, and more robust security
>> capabilities.
>>
>> [11] https://developer.chrome.com/extensions/enterprise_platformKeys
>> [12] https://fidoalliance.org/
>> [12]
>> https://fidoalliance.org/google-launches-security-key-worlds-first-deployment-of-fast-identity-online-universal-second-factor-fido-u2f-authentication/
>> [14] https://bugzilla.mozilla.org/show_bug.cgi?id=1065729
>>
>> Usage information from UseCounter
>> <https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/page/UseCounter.h&sq=package:chromium&type=cs&q=file:UseCounter.h%20Feature&l=39>
>> https://www.chromestatus.com/metrics/feature/popularity#HTMLKeygenElement
>>
>> Based on data seen from Google crawler (unfortunately, not public), the
>> number of sites believed to be affected is comically low.
>>
>> OWP launch tracking bug
>> https://code.google.com/p/chromium/issues/detail?id=514767
>>
>> Entry on the feature dashboard <https://www.chromestatus.com/>
>> https://www.chromestatus.com/metrics/feature/popularity#HTMLKeygenElement
>>
>> Requesting approval to remove too?
>> No
>>
>
> Social Web Architect
> http://bblfish.net/
>
>

Received on Wednesday, 26 August 2015 15:34:57 UTC