Skip to content

Commit 1ff3878

Browse files
committed
Add prevent-canvas scriptlet
Prevent usage of specific or all (default) canvas APIs. Syntax ```text example.com##+js(prevent-canvas [, contextType]) ``` - `contextType`: A specific type of canvas API to prevent (default to all APIs). Can be a string or regex which will be matched against the type used in getContext() call. Prepend with `!` to test for no-match. Examples 1. Prevent `example.com` from accessing all canvas APIs ```adblock example.com##+js(prevent-canvas) ``` 2. Prevent access to any flavor of WebGL API, everywhere ```adblock *##+js(prevent-canvas, /webgl/) ``` 3. Prevent `example.com` from accessing any flavor of canvas API except `2d` ```adblock example.com##+js(prevent-canvas, !2d) ``` References https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
1 parent c20cfd4 commit 1ff3878

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

assets/resources/scriptlets.js

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function safeSelf() {
6868
if ( pattern === '' ) {
6969
return { matchAll: true };
7070
}
71-
const expect = (options.canNegate === true && pattern.startsWith('!') === false);
71+
const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
7272
if ( expect === false ) {
7373
pattern = pattern.slice(1);
7474
}
@@ -3388,6 +3388,70 @@ function setAttr(
33883388
runAt(( ) => { start(); }, 'idle');
33893389
}
33903390

3391+
/*******************************************************************************
3392+
*
3393+
* @scriptlet prevent-canvas
3394+
*
3395+
* @description
3396+
* Prevent usage of specific or all (default) canvas APIs.
3397+
*
3398+
* ### Syntax
3399+
*
3400+
* ```text
3401+
* example.com##+js(prevent-canvas [, contextType])
3402+
* ```
3403+
*
3404+
* - `contextType`: A specific type of canvas API to prevent (default to all
3405+
* APIs). Can be a string or regex which will be matched against the type
3406+
* used in getContext() call. Prepend with `!` to test for no-match.
3407+
*
3408+
* ### Examples
3409+
*
3410+
* 1. Prevent `example.com` from accessing all canvas APIs
3411+
*
3412+
* ```adblock
3413+
* example.com##+js(prevent-canvas)
3414+
* ```
3415+
*
3416+
* 2. Prevent access to any flavor of WebGL API, everywhere
3417+
*
3418+
* ```adblock
3419+
* *##+js(prevent-canvas, /webgl/)
3420+
* ```
3421+
*
3422+
* 3. Prevent `example.com` from accessing any flavor of canvas API except `2d`
3423+
*
3424+
* ```adblock
3425+
* example.com##+js(prevent-canvas, !2d)
3426+
* ```
3427+
*
3428+
* ### References
3429+
*
3430+
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
3431+
*
3432+
* */
3433+
3434+
builtinScriptlets.push({
3435+
name: 'prevent-canvas.js',
3436+
fn: preventCanvas,
3437+
dependencies: [
3438+
'safe-self.fn',
3439+
],
3440+
});
3441+
function preventCanvas(
3442+
contextType = ''
3443+
) {
3444+
const safe = safeSelf();
3445+
const pattern = safe.initPattern(contextType, { canNegate: true });
3446+
const proto = globalThis.HTMLCanvasElement.prototype;
3447+
proto.getContext = new Proxy(proto.getContext, {
3448+
apply(target, thisArg, args) {
3449+
if ( safe.testPattern(pattern, args[0]) ) { return null; }
3450+
return Reflect.apply(target, thisArg, args);
3451+
}
3452+
});
3453+
}
3454+
33913455

33923456
/*******************************************************************************
33933457
*

0 commit comments

Comments
 (0)