Perspectives icon indicating copy to clipboard operation
Perspectives copied to clipboard

also validate certificates for embedded content that goes to a different domain

Open danwent opened this issue 15 years ago • 7 comments

reported by: tz [email protected]

I have a problem since I've disabled most CAs - perspectives will work for actual web pages, but not other content, e.g. on the page www.xyz.com, if there is a different "images.xyz.com" which has images or javascript or whatever but is NOT a page, I get a certificate error which perspectives cannot bypass (unless I manually type in the URL to go to the top - I might get a 404, but the SSL will go through and get perspectives to verify things).

danwent avatar Nov 07 '10 18:11 danwent

The current code hooks into the nsIWebProgressListener interface, which seems to only be called on actions related to contacting the site shown in the URL bar. You can find this code in plugin/chrome/content/notaries.js . Look for the notaryListener attribute of the class. At this level, we get some idea that the page includes insecure content (because the browser.securityUI.state flags have Perspectives.state.STATE_IS_BROKEN set), but I do not believe you have the ability to validate and trust any such connections. Note: STATE_IS_BROKEN seems to be what Firefox uses to set the 'mixed content' error icon in the UI.

It seems we need to be able to find a lower-level interface that is called for each embedded item on the page. An ancient link (https://developer.mozilla.org/en/Firefox_1.5_for_developers) mentions the following:

Certificate prompts can now be overridden on a per-channel basis. This works by setting an interface requestor as an nsIChannel's notificationCallbacks and giving out an interface for nsIBadCertListener.

Other extensions (e.g., firebug) must already do something along these lines. For example, I suspect we'd be able to catch bad certificate by listening on a per-channel basis similar to how firebug listens on a per-channel basis for each embedded request: http://code.google.com/p/fbug/source/browse/branches/firebug1.7/modules/firebug-channel-listener.js .

Sometimes poking through the mozilla source using mxr.mozilla.org is useful here.

In addition to figuring out how to hook into these requests, we would likely have to change certain things about the perspectives UI, since a single page could have multiple certificates, each of which would require a separate key graph, etc. Those changes probably wouldn't be too tough.

danwent avatar Nov 07 '10 18:11 danwent

It is actually worse than that - here at github. They insist on using a dozen subsites - gist.github.com, assetsN.github.com (N=1,2,3 so far), etc. I type https://assets1.github.com and get the error page but perspectives won't automatically bypass it (though clicking on the perspectives icon says it has seen the cert for the last few days). login redirects to gist.github.com, also not automatically overridden. I've manually inserted exceptions for these.

tz1 avatar Nov 07 '10 19:11 tz1

up :)

Tie-fighter avatar May 28 '11 19:05 Tie-fighter

Certificate Patrol works with embedded content. http://patrol.psyced.org/ Maybe their source code gives a good hint at how to do this properly.

Tie-fighter avatar Aug 24 '11 12:08 Tie-fighter

I implemented a first draft for embedded content support. You can find the fork here: https://github.com/lambdor/Perspectives/tree/embedded_content

Most important question: _How do you restart a single request for embedded content or just delay it long enough until the Perspectives servers have been queried?_ see MDN Setting_HTTP_request_headers, MDN nsIHttpChannel and MDN nsIChannel.

Usage: In about:config you have to set security.ssl.enable_ocsp_stapling to false, otherwise embedded content may silently fail with "sec_error_ocsp_invalid_signing_cert" (see https://bugzilla.mozilla.org/show_bug.cgi?id=971750). The embedded contents are checked on page load and their security exceptions are overriden but not yet restarted again. Therefore you may have to reload the page to see the successful overrides. To actually see some effect delete all your CA certs: go to Perspectives -> View Certificate Store and delete all Authorities (tedious). Then try https://www.github.com for example which embeds stylesheets from https://assets-cdn.github.com. You should either see an unstyled page (=embedded content is not supported or not yet overriden) or a fully styled page (=success). If the page is unstyled try to reload the page once more.

How it works: To retrieve all embedded content URIs we have to register a httpRequestObserver. This is done in initNotaries(). The observe() code is similar to updateStatus() except that "security_state" is always assumed STATE_IS_SECURE(!). I don't know how to retrieve the actual security_state for embedded content. Calling "subject.QueryInterface(Ci.nsIChannel).securityInfo" always returns null for me? But security_state can only take the values SECURE, BROKEN ("some content was received over an insecure channel") and INSECURE (see https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWebProgressListener). Thus if we probe for HTTPS it should be save to exclude STATE_IS_INSECURE? And if "mixed content" is handled in this very procedure then STATE_IS_BROKEN can also be excluded? Which only leaves STATE_IS_SECURE.

After all the notary queries in observe() are completed process_results_embedded() is called. The embedded-procedure is a very simplified version of process_notary_results() (now named process_results_main()), because we can ignore all the different cases which handle notification updates. Whereas process_results_main() reloads the current tab, process_results_embedded() just silently overrides the security exception for now, but doesn't do any reloading, so you don't see any effect until you reload the page.

Querying for embedded content requires the main page fully loaded which again may depend on the users configuration (existing CA certs, existing security overrides). I outlined those conditions in the following decision table:

condition
certificate exists 0 0 0 0 0 0 1 1 1 1 1 1
is_whitelisted_by_user (main page) 0 0 0 1 1 1 0 0 0 1 1 1
ask before contacting notaries 0 1 1 0 1 1 0 1 1 0 1 1
has_user_permission (main page) - 0 1 - 0 1 - 0 1 - 0 1
result
query main 1 0 1 - - - 1 0 1 - - -
loads page and requests embedded 0 0 0 1 1 1 1 1 1 1 1 1
query embedded - - 1' 1 1" 1'" 1 1" 1'" 1 1" 1'"

') This should happen once the main page has been reloaded again triggered by Perspectives. ") Set to "true" for now until we know how to restart a request. Embedded content should actually respect the user's probing permission of course. Setting this to "false" right now would require two page reloads however. '") Set to "true" for now until we know how to restart a request. Querying has to be held back until the user is giving permission for the main page. Setting this to "false" would require a manual page reload right now.

Doing a full page reload once all embedded content requests are finished doesn't work for pages with dynamic requests (AJAX, adding new header nodes etc.).

Tell me what you think!

ghost avatar Jun 14 '14 13:06 ghost

Related to #20

ghost avatar Jun 14 '14 13:06 ghost

Hi @lambdor , thank you very much for sending the patch! I have some important real life deadlines coming up but I will review this as soon as I can.

I may have to fix #123 before looking at this so the existing extension will continue to function when Firefox releases their next update.

daveschaefer avatar Jun 15 '14 06:06 daveschaefer