Skip to content

Commit 60053cb

Browse files
committed
AG-39948 Improve 'prevent-eval-if' — return original value for 'eval.toString()'. #481
Squashed commit of the following: commit ad2685c Merge: 568bdd0 9a97415 Author: Adam Wróblewski <adam@adguard.com> Date: Mon Feb 17 12:02:51 2025 +0100 Merge branch 'master' into fix/AG-39948 commit 568bdd0 Author: Adam Wróblewski <adam@adguard.com> Date: Mon Feb 17 11:56:32 2025 +0100 Fix prevent-bab commit 236d6a4 Author: Adam Wróblewski <adam@adguard.com> Date: Fri Feb 14 19:45:28 2025 +0100 Update changelog commit 8967d9b Author: Adam Wróblewski <adam@adguard.com> Date: Fri Feb 14 19:00:04 2025 +0100 Improve 'prevent-eval-if' — return original value for 'eval.toString()'
1 parent 9a97415 commit 60053cb

5 files changed

Lines changed: 33 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
1717
- ability in `json-prune` scriptlet to match `key` with specific `value`
1818
and remove `array`/`object` if it contains specific `item` [#183]
1919

20+
### Fixed
21+
22+
- `prevent-eval-if` and `prevent-bab` scriptlets, now `eval.toString()` call returns original value [#481]
23+
2024
[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v2.1.4...HEAD
2125
[#183]: https://github.com/AdguardTeam/Scriptlets/issues/183
26+
[#481]: https://github.com/AdguardTeam/Scriptlets/issues/481
2227

2328
## [v2.1.4] - 2025-01-20
2429

src/scriptlets/prevent-bab.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export function preventBab(source) {
9393
}
9494
};
9595
window.eval = evalWrapper.bind(window);
96+
window.eval.toString = nativeEval.toString.bind(nativeEval);
9697
}
9798

9899
export const preventBabNames = [

src/scriptlets/prevent-eval-if.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export function preventEvalIf(source, search) {
4141
hit(source, payload);
4242
return undefined;
4343
}.bind(window);
44+
45+
// Protect window.eval from native code check
46+
window.eval.toString = nativeEval.toString.bind(nativeEval);
4447
}
4548

4649
export const preventEvalIfNames = [

tests/scriptlets/prevent-bab.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const name = 'prevent-bab';
66

77
const testProp = 'evalProp';
88

9+
const nativeEval = window.eval;
10+
911
const beforeEach = () => {
1012
window.__debug = () => {
1113
window.hit = 'FIRED';
@@ -14,18 +16,22 @@ const beforeEach = () => {
1416

1517
const afterEach = () => {
1618
clearGlobalProps(testProp, 'hit', '__debug');
19+
window.eval = nativeEval;
1720
};
1821

1922
module(name, { beforeEach, afterEach });
2023

2124
test('works eval with AdblockBlock', (assert) => {
25+
const originalEvalString = window.eval.toString();
26+
2227
runScriptlet(name);
2328

2429
const evalWrap = eval;
2530
evalWrap(`(function test() { const temp = 'babasbm'; window.${testProp} = 'test';})()`);
2631

2732
assert.strictEqual(window[testProp], undefined);
2833
assert.strictEqual(window.hit, 'FIRED', 'hit fired');
34+
assert.strictEqual(window.eval.toString(), originalEvalString, 'eval.toString() should return original value');
2935
});
3036

3137
test('sample eval script works', (assert) => {

tests/scriptlets/prevent-eval-if.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ test('AG prevent-eval-if works', (assert) => {
5252
assert.strictEqual(secondActual, undefined, 'result of eval evaluation should be undefined');
5353
});
5454

55+
test('AG prevent-eval-if works, check toString', (assert) => {
56+
const originalEvalString = window.eval.toString();
57+
58+
runScriptlet(name, ['/adblock/']);
59+
60+
const agPreventEvalIf = 'agPreventEvalIf';
61+
62+
const evalWrapper = eval;
63+
const firstActual = evalWrapper(`(function () {return '${agPreventEvalIf}'})()`);
64+
assert.strictEqual(window.hit, undefined, 'hit function should not fire for not matched function');
65+
assert.strictEqual(firstActual, agPreventEvalIf, 'result of eval evaluation should exist');
66+
67+
const secondActual = evalWrapper(`(function () {const adblock = true; return '${agPreventEvalIf}'})()`);
68+
assert.strictEqual(window.hit, 'FIRED', 'hit function should fire');
69+
assert.strictEqual(secondActual, undefined, 'result of eval evaluation should be undefined');
70+
assert.strictEqual(window.eval.toString(), originalEvalString, 'toString should not be changed');
71+
});
72+
5573
test('does not work -- invalid regexp pattern', (assert) => {
5674
runScriptlet(name, ['/\\/']);
5775

0 commit comments

Comments
 (0)