Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workbox PWA broken due to integrity hash mismatch #1539

Closed
Birbber opened this issue Oct 29, 2021 · 5 comments
Closed

Workbox PWA broken due to integrity hash mismatch #1539

Birbber opened this issue Oct 29, 2021 · 5 comments

Comments

@Birbber
Copy link

Birbber commented Oct 29, 2021

@thexeos commented on Fri Oct 29 2021

Issue Details

  • AdGuard version:
    • v3.6.4 (32)
  • Filtering mode:
    • Local VPN
  • Device:
    • Galaxy A5 (2017)
  • Operating system and version:
    • Android 8.0.0
  • Root access:
    • No

Description

When Workbox-based PWAs update (assuming their install was not blocked by any of the filters), the list of files to update may contain integrity attributes, corresponding to SRI hashes. If the hash of the received (server) response does not match the stored hash - the file download, and by extension the update process, fails.

I am seeing these two lines added to the response body for index.html from the PWA's domain (after <meta charset=utf-8> tag):

<script type="text/javascript" nonce="4faaa0101c3b4442b4e06e195dd" src="//local.adguard.org?ts=1635450354873&amp;type=content-script&amp;dmn=domain.com&amp;app=com.android.chrome&amp;css=3&amp;js=1&amp;rel=1&amp;rji=1&amp;sbe=0&amp;stealth=1&amp;uag=&amp;trref=aHR0cHM6Ly9kb21haW4uY29tLw=="></script>
<script type="text/javascript" nonce="4faaa0101c3b4442b4e06e195dd" src="//local.adguard.org?ts=1635450354873&amp;name=AdGuard%20Extra&amp;type=user-script"></script>

Generally, you can tell that the request was made by the Service Worker by inspecting the Referrer header in the request, which would typically look like 'https://domain.com/service-worker.js'.

Either way, this seems to be a recent breaking change, as this specific PWA was able to update through the same mechanism for over a year. From user perspective, this is an issue with the PWA and AdGuard would be the last place they'll look when trying to troubleshoot failed "app" updates.

I can provide the domain name of the PWA, if that would make any difference.

@ameshkov
Copy link
Member

@thexeos it'd help a lot if you could provide an example of such a PWA.

@ameshkov
Copy link
Member

@sfionov I suppose we could have issues with SRI in general since AG may also modify other responses content (i.e. $redirect rules and so on). The fast solution would be to simply remove this attribute.

A little bit better solution would be to read that attribute and do the check on our own (it can probably be planned on a later release of CL).

@thexeos
Copy link

thexeos commented Nov 4, 2021

@thexeos it'd help a lot if you could provide an example of such a PWA.

https://beaconx.com (requires login before PWA can be installed)
I emailed you account credentials for testing.

I gave this some thought and the biggest issue here is the asynchronicity of SRI hashes being sent to client and content being loaded. In case of Workbox, the SRI hashes are included in service-worker.js file, while the resources are downloaded some time later, after Service Worker file was parsed and executed. Thus, AdGuard does not have in its possession the content of, for example, index.html and service-worker.js at the same time, and it won't be able to compute new SRI hash after modifying index.html and inject it into service-worker.js so that update can go through.

The format in which hashes are sent is, roughly (service-worker.js):

// workbox code
precacheAndRoute([
    {
        'integrity':'sha384-BubaQZpIBydSuCKS/9CbrgmvnPmxf0V0QMIAQIYVOx+mgVM4PuMfflVIuPj8Q1kL',
        'revision':'47a4e4a808ef26a32c8193a21a962d5f',
        'url':'/index.html'
    },
    {
        'integrity':'sha384-920rHB8nX4WFHKgdjjN7TboxzDRs3iIJ0JYbnjOb22fUeoONRhIG9IHvxgUfKZdz',
        'revision':'87f95b08a473c41f5c7e464403eac1f3',
        'url':'/manifest.json'
    },
    {
        'integrity':'sha384-8MPmbcaDaa3PyrjdhZZia3RGxQFn7CB+6KQNIFt6oG56E28+SeOiuhotLWwKgIKq',
        'revision':null,
        'url':'https://static.beaconx.com/css/app.0cf1188a.css'
    },
    {
        'integrity':'sha384-DITOVQ9GRMKDkvZwAgf3Quo/95Tqc9gTuQICo4TPSkvT+qjlK5dn6b7Hvn9/zC1g',
        'revision':null,
        'url':'https://static.beaconx.com/js/app.b8f62d34.js'
    }
])
// more workbox code

@ameshkov
Copy link
Member

ameshkov commented Nov 7, 2021

A quick solution for beaconx would be to add a filtering rule that disables cosmetic rules injection completely for it, something like this: @@||beaconx.com^$elemhide,jsinject,content (we'd probably need to limit it to some specific PWA rules, though).

We may resort to it after all, but we'd better look for a generic solution first.

@ameshkov
Copy link
Member

ameshkov commented Dec 7, 2021

In the end, I can't see any viable generic solution. Moved my thoughts about it to a different issue: #1562

Regarding beaconx, I've added the exception rule for it to AG Base filter, the issue shouldn't be happening anymore.

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

No branches or pull requests

5 participants