Skip to content
This repository has been archived by the owner on Nov 6, 2023. It is now read-only.

Mixed Content lightweight DOM trasversal #10842

Closed
SamuelePilleri opened this issue Jul 1, 2017 · 9 comments
Closed

Mixed Content lightweight DOM trasversal #10842

SamuelePilleri opened this issue Jul 1, 2017 · 9 comments
Labels

Comments

@SamuelePilleri
Copy link

This is kind of related to #2017 though not exactly the same.

When creating a rule, we can client-side rewrite page url, switching to https, but this potentially leads to MCB errors with URLs hardcoded in the document (related).

Most of them can be fixed with very simple JavaScript and CSS selectors, making the site usable out of the box:

document.querySelectorAll('*[href^="http://' + document.location.host + '" i]')
.forEach(function(value)
{
        value.href = value.href.replace(/^http/i, "https");
});

document.querySelectorAll('*[src^="http://' + document.location.host + '" i]')
.forEach(function(value)
{
        value.src = value.src.replace(/^http/i, "https");
});

This wouldn't generate any error because we are assuming that, if the current host (exact domain + port) works with HTTPS, then all resources served by the current host work with HTTPS.

Please note that *[src^="http://www.example.com" i] is a CSS4 selector (it takes advantage of case-insensitive attribute), but I've tested it on Firefox latest (54.0.1 on Windows, not sure when they introduced it) and it works, while in Chromium it is available since version 49 (see); I do not have Opera to test.

I don't know if this is possible under current HTTPS Everywhere design, but I think it would be a nice feature to have, either default or optional via a tag-rule in the XML rule specification:

<ruleset name="Example.com">
        <target host="www.example.com" />

        <rule from="^http:" to="https:" />

        <rewrite from='*[src^="http://www.example.com" i]' to="https://www.example.com" />
        <rewrite from='*[href^="http://www.example.com" i]' to="https://www.example.com" />
</ruleset>
@ghost
Copy link

ghost commented Jul 2, 2017

I'm not sure if replacing href/src in pages is in scope of HTTPS Everywhere.

@SamuelePilleri
Copy link
Author

SamuelePilleri commented Jul 2, 2017 via email

@ghost
Copy link

ghost commented Jul 2, 2017

@SamuelePilleri This is not possible since the WebExtensions-based extensions cannot disable MCB.

@SamuelePilleri
Copy link
Author

How about modifying the response body before it gets parsed by the browser? I'm don't have any experience in plugin development, but looking at the code HTTPS.handleSecureCookies(req) does something similar with response headers. Thinking about <link>, <script> and <img> that cannot have children as far as I know, this would be a simple regex (I think elements that can have children would require a full XML parse, much more heavy).

Do you think that would be appropriate?

@SamuelePilleri
Copy link
Author

Actually, I think a simple regex like this could make it:

<\w+[^>]+(?:href|src)="(http:\/\/)(([^\/"]+)[^"]*)"

@cschanaj
Copy link
Collaborator

cschanaj commented Jul 3, 2017

Linking #8506

@iki
Copy link

iki commented Aug 3, 2017

#8506 seems to handle this universally, even for resources loaded by js/css

@iki
Copy link

iki commented Aug 3, 2017

oops, upgrade-insecure-requests CSP applies only to site resources, not 3rd part ones, so we need fixing resources in DOM too

@SamuelePilleri
Copy link
Author

I was reading #8506 as pointed out by @iki. The topic is quite interesting from a technical point of view, so I would start focusing on "same host" resources.

Reading through MDN docs I've found default-src which description says:

The HTTP Content-Security-Policy (CSP) default-src directive serves as a fallback for the other CSP fetch directives.

I'm completely new to this and I still have a lot to figure out, but could that be used as a fallback for requests that fail to load with HTTPS? That way, resources on the same domain are guaranteed to work and others might work.

Something like this:

Content-Security-Policy: upgrade-insecure-requests; default-src http: 

I understand it isn't an optimal solution given that HTTPS Everywhere has a huge database that could be used to resolve this problem with higher accurancy, but it's better than nothing.

Anyone knows any other way or is working on something similar?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants