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

Fork Sync: Update from parent repository #231

Merged
merged 56 commits into from
Dec 19, 2023
Merged

Fork Sync: Update from parent repository #231

merged 56 commits into from
Dec 19, 2023

Conversation

brave-builds
Copy link
Collaborator

@brave-builds brave-builds commented Dec 8, 2023

diff --git a/assets/assets.json b/assets/assets.json
index 4d9d2b294..777331426 100644
--- a/assets/assets.json
+++ b/assets/assets.json
@@ -755,9 +755,9 @@
 		"lang": "af fy nl",
 		"contentURL": "https://easydutch-ubo.github.io/EasyDutch/EasyDutch.txt",
 		"cdnURLs": [
-			"https://easydutchcdn.pages.dev/EasyDutch.all.txt",
-			"https://cdn.jsdelivr.net/gh/EasyDutch-uBO/EasyDutchCDN@main/EasyDutch.all.txt",
-			"https://cdn.statically.io/gh/EasyDutch-uBO/EasyDutchCDN/main/EasyDutch.all.txt"
+			"https://easydutch-ubo.github.io/EasyDutch/EasyDutch.all.txt",
+			"https://cdn.jsdelivr.net/gh/EasyDutch-uBO/EasyDutch@gh-pages/EasyDutch.all.txt",
+			"https://cdn.statically.io/gh/EasyDutch-uBO/EasyDutch/gh-pages/EasyDutch.all.txt"
 		],
 		"supportURL": "https://github.com/EasyDutch-uBO/EasyDutch/"
 	},
diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js
index e3bd1eaf4..c198fb501 100644
--- a/assets/resources/scriptlets.js
+++ b/assets/resources/scriptlets.js
@@ -2351,12 +2351,18 @@ function noXhrIf(
     const propNeedles = parsePropertiesToMatch(propsToMatch, 'url');
     const log = propNeedles.size === 0 ? console.log.bind(console) : undefined;
     const warOrigin = scriptletGlobals.get('warOrigin');
+    const headers = {
+        'date': '',
+        'content-type': '',
+        'content-length': '',
+    };
     self.XMLHttpRequest = class extends self.XMLHttpRequest {
         open(method, url, ...args) {
             if ( log !== undefined ) {
                 log(`uBO: xhr.open(${method}, ${url}, ${args.join(', ')})`);
                 return super.open(method, url, ...args);
             }
+            xhrInstances.delete(this);
             if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
                 return super.open(method, url, ...args);
             }
@@ -2364,6 +2370,7 @@ function noXhrIf(
             if ( matchObjectProperties(propNeedles, haystack) ) {
                 xhrInstances.set(this, haystack);
             }
+            haystack.headers = Object.assign({}, headers);
             return super.open(method, url, ...args);
         }
         send(...args) {
@@ -2371,6 +2378,7 @@ function noXhrIf(
             if ( haystack === undefined ) {
                 return super.send(...args);
             }
+            haystack.headers['date'] = (new Date()).toUTCString();
             let promise = Promise.resolve({
                 xhr: this,
                 directive,
@@ -2385,53 +2393,81 @@ function noXhrIf(
                 },
             });
             switch ( this.responseType ) {
-                case 'arraybuffer':
-                    promise = promise.then(details => {
-                        details.props.response.value = new ArrayBuffer(0);
-                        return details;
-                    });
-                    break;
-                case 'blob':
-                    promise = promise.then(details => {
-                        details.props.response.value = new Blob([]);
-                        return details;
-                    });
-                    break;
-                case 'document': {
-                    promise = promise.then(details => {
-                        const parser = new DOMParser();
-                        const doc = parser.parseFromString('', 'text/html');
-                        details.props.response.value = doc;
-                        details.props.responseXML.value = doc;
-                        return details;
-                    });
-                    break;
-                }
-                case 'json':
-                    promise = promise.then(details => {
-                        details.props.response.value = {};
-                        details.props.responseText.value = '{}';
+            case 'arraybuffer':
+                promise = promise.then(details => {
+                    details.props.response.value = new ArrayBuffer(0);
+                    return details;
+                });
+                haystack.headers['content-type'] = 'application/octet-stream';
+                break;
+            case 'blob':
+                promise = promise.then(details => {
+                    details.props.response.value = new Blob([]);
+                    return details;
+                });
+                haystack.headers['content-type'] = 'application/octet-stream';
+                break;
+            case 'document': {
+                promise = promise.then(details => {
+                    const parser = new DOMParser();
+                    const doc = parser.parseFromString('', 'text/html');
+                    details.props.response.value = doc;
+                    details.props.responseXML.value = doc;
+                    return details;
+                });
+                haystack.headers['content-type'] = 'text/html';
+                break;
+            }
+            case 'json':
+                promise = promise.then(details => {
+                    details.props.response.value = {};
+                    details.props.responseText.value = '{}';
+                    return details;
+                });
+                haystack.headers['content-type'] = 'application/json';
+                break;
+            default:
+                if ( directive === '' ) { break; }
+                promise = promise.then(details => {
+                    return generateContentFn(details.directive).then(text => {
+                        details.props.response.value = text;
+                        details.props.responseText.value = text;
                         return details;
                     });
-                    break;
-                default:
-                    if ( directive === '' ) { break; }
-                    promise = promise.then(details => {
-                        return generateContentFn(details.directive).then(text => {
-                            details.props.response.value = text;
-                            details.props.responseText.value = text;
-                            return details;
-                        });
-                    });
-                    break;
+                });
+                haystack.headers['content-type'] = 'text/plain';
+                break;
             }
             promise.then(details => {
+                haystack.headers['content-length'] = `${details.props.response.value}`.length;
                 Object.defineProperties(details.xhr, details.props);
                 details.xhr.dispatchEvent(new Event('readystatechange'));
                 details.xhr.dispatchEvent(new Event('load'));
                 details.xhr.dispatchEvent(new Event('loadend'));
             });
         }
+        getResponseHeader(headerName) {
+            const haystack = xhrInstances.get(this);
+            if ( haystack === undefined || this.readyState < this.HEADERS_RECEIVED ) {
+                return super.getResponseHeader(headerName);
+            }
+            const value = haystack.headers[headerName.toLowerCase()];
+            if ( value !== undefined && value !== '' ) { return value; }
+            return null;
+        }
+        getAllResponseHeaders() {
+            const haystack = xhrInstances.get(this);
+            if ( haystack === undefined || this.readyState < this.HEADERS_RECEIVED ) {
+                return super.getAllResponseHeaders();
+            }
+            const out = [];
+            for ( const [ name, value ] of Object.entries(haystack.headers) ) {
+                if ( !value ) { continue; }
+                out.push(`${name}: ${value}`);
+            }
+            if ( out.length !== 0 ) { out.push(''); }
+            return out.join('\r\n');
+        }
     };
 }
 
diff --git a/src/js/redirect-resources.js b/src/js/redirect-resources.js
index e2856f61e..b8577e370 100644
--- a/src/js/redirect-resources.js
+++ b/src/js/redirect-resources.js
@@ -48,9 +48,6 @@ export default new Map([
         alias: '32x32-transparent.png',
         data: 'blob',
     } ],
-    [ 'addthis_widget.js', {
-        alias: 'addthis.com/addthis_widget.js',
-    } ],
     [ 'amazon_ads.js', {
         alias: 'amazon-adsystem.com/aax2/amzn_ads.js',
         data: 'text',
@@ -116,14 +113,6 @@ export default new Map([
     } ],
     [ 'hd-main.js', {
     } ],
-    [ 'ligatus_angular-tag.js', {
-        alias: 'ligatus.com/*/angular-tag.js',
-    } ],
-    [ 'mxpnl_mixpanel.js', {
-    } ],
-    [ 'monkeybroker.js', {
-        alias: 'd3pkae9owd2lcf.cloudfront.net/mb105.js',
-    } ],
     [ 'nobab.js', {
         alias: [ 'bab-defuser.js', 'prevent-bab.js' ],
         data: 'text',

Related issue:
uBlockOrigin/uBlock-issues#3004

Related commit:
gorhill@ee83a43

Use extensions API message ports to establish direct communication
between content script and logger window.
Additionally, lock the inspected page to the item under
the mouse in the dom inspector.
Related commit:
uBlockOrigin/uAssets@20312c2178

To work around incompatibity with `urltransform` in 1.53.0.
With this commit support for `urltransform` is dropped in
favor of `uritransform`. Since `uritransform` won't be parsed
by older versions of uBO, the change in syntax for `urltransform`
between 1.53.0 and 1.54.0 will no longer cause issue.
In Support pane's troubleshooting information, a delta sign will
be added to list update information when the list was last updated
through differential update.
Possibly related issue:
uBlockOrigin/uBlock-issues#2136

Also reported internally, steps to reproduce the issue fixed here:

- Open uBO's dashboard through 3-dot > Add-ons > uBO > Settings
- Bring forth "Filter lists" pane
  We want the tab to be already opened at next launch
- Quit Firefox for Android
- Launch Firefox for Android

Result:

Very long launch time, lists marked as out of date.
bcaller
bcaller previously approved these changes Dec 11, 2023
If the `manual` parameter is assigned a date in the form of
`YYMMDD`, this will tell uBO to update lists from origin sources
when the current time is within the range of the specified date,
otherwise lists will be updated from CDNs. Updating from CDNs
is always strongly recommended since this enables differential
updates.

For the time being, `manual=1` will always cause to update lists
from origin, but this form will be deprecated once next stable
release is widespread. The idea is to not leave behind stale
and obsolete links which would be detrimental to differential
updates should someone click on one of these old links left
behind.
Occurred when element picker was launched from context menu
as a result of clicking on `html` or `body` elements.
@brave brave deleted a comment from github-actions bot Dec 18, 2023
@brave brave deleted a comment from github-actions bot Dec 18, 2023
Copy link

[puLL-Merge] - brave/uBlock@231

Description

The pull request appears to introduce changes to resource and scriptlet files within the uBlock repository. These changes include an update of content delivery URLs for a resource file, a robust extension of functionality within a scriptlet concerning XML HTTP Requests (XHR), and the removal of specific redirect rules from a js file managing redirect resources.

Changes

Changes

assets/assets.json

  • The CDN URLs for "EasyDutch.all.txt" have been updated. It seems like a change of branch or location within the same repository from where the asset is served.

assets/resources/scriptlets.js

  • A headers object was added, setting up a template for common HTTP headers.
  • An issue with XHR instances not being deleted after open has been fixed.
  • In the open method:
    • The headers object is cloned and incorporated into the haystack object, which represents context specific to each XHR instance.
  • In the send method:
    • A date header is set to the current UTC string representation.
    • Switch cases for the types arraybuffer, blob, document, and json have been added where they set the appropriate Content-Type header.
    • content-length is calculated and set in the details object.
    • getResponseHeader and getAllResponseHeaders methods have been overridden to return the values from the haystack headers if available, which allows for the synthetic XHR to behave more like a regular XHR in terms of headers handling.

src/js/redirect-resources.js

  • Removed redirect rules for addthis_widget.js, ligatus_angular-tag.js, mxpnl_mixpanel.js, and monkeybroker.js. It's not mentioned why these rules were removed. It could be due to obsolescence, a change in ad serving domains, or an update in ad blocking strategies.

Security Hotspots

Here are the potential security hotspots introduced by these changes:

  1. Scriptlet Modification (scriptlets.js):

    • The scriptlet changes include managing headers and creating artificial responses for intercepted XHR requests. While this is common in content blockers, care must be taken to ensure that security-related headers aren't incorrectly set or omitted. Moreover, the manipulations should not unintentionally provide avenues for bypassing CSP or other security measures in place on the web page or the browser.
    • Overriding the browser's native XHR methods could also lead to unexpected behavior if not correctly implemented. The script should be audited to ensure that no security gaps have been introduced.
  2. Resource Redirect Removal (redirect-resources.js):

    • The removal of certain redirects needs to be validated against the original purpose of these redirects. If they were intended to mitigate tracking or malicious scripts, their removal must be justified and ensured that it does not decrease user privacy or security.

Please review the potential impacts of these changes in detail, especially considering the security rules in place and the threat model of a content blocker extension like uBlock. Testing should be done to ensure that the changes do not introduce regressions or new vulnerabilities.

@bcaller bcaller merged commit 5d931b4 into master Dec 19, 2023
2 checks passed
@bcaller bcaller deleted the mirror branch December 19, 2023 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants