Skip to content

Commit

Permalink
Add variable for logging decoded content
Browse files Browse the repository at this point in the history
Improve checkIfValidBase64 and add more tests
  • Loading branch information
AdamWr committed May 6, 2024
1 parent f0f931e commit 788f70b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
17 changes: 12 additions & 5 deletions src/scriptlets/trusted-replace-outbound-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,17 @@ export function trustedReplaceOutboundText(
* @param str - The string to be checked.
* @returns A boolean indicating whether the string is a valid base64 encoded string.
*/
const checkIfValidBase64 = (str: string) => {
const checkIfValidBase64 = (str: string): boolean => {
try {
return str === '' ? false : btoa(atob(str)) === str;
if (str === '') {
return false;
}
const decodedString = atob(str);
const encodedString = btoa(decodedString);
// Encoded string may contains padding characters, so it's necessary to remove it before comparison
const stringWithoutPadding = str.replace(/=+$/, '');
const encodedStringWithoutPadding = encodedString.replace(/=+$/, '');
return encodedStringWithoutPadding === stringWithoutPadding;
} catch (e) {
return false;
}
Expand Down Expand Up @@ -216,6 +224,7 @@ export function trustedReplaceOutboundText(

const logOriginalContent = !textToReplace || !!logContent;
const logModifiedContent = !!logContent;
const logDecodedContent = !!decodeMethod && !!logContent;

// This flag allows to prevent infinite loops when trapping props that are used by scriptlet's own code.
let isMatchingSuspended = false;
Expand All @@ -242,9 +251,7 @@ export function trustedReplaceOutboundText(
}

const patternRegexp = toRegExp(textToReplace);
// If textToReplace is not set and decodeMethod and logContent are set
// then decoded content should be logged.
const modifiedContent = textToReplace || (decodeMethod && logContent)
const modifiedContent = textToReplace || logDecodedContent
? decodeAndReplaceContent(result, patternRegexp, replacement, decodeMethod, logContent)
: result;

Expand Down
25 changes: 19 additions & 6 deletions tests/scriptlets/trusted-replace-outbound-text.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,19 @@ test('replace text - Array.prototype.join, decode base64', (assert) => {
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
});

test('replace text - Array.prototype.join, decode base64, test for padding "="', (assert) => {
runScriptlet(name, ['Array.prototype.join', 'fooBarTest=', 'Test=', 'base64']);
const expectedText = 'Test=';
const expectedTextInBase64 = btoa(expectedText);
const textInBase64 = 'Zm9vQmFyVGVzdD0';
const splittedText = textInBase64.split('');
const result = splittedText.join('');
const decodedResult = atob(result);
assert.deepEqual(result, expectedTextInBase64, 'content in base64 is modified');
assert.deepEqual(decodedResult, expectedText, 'content is modified');
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
});

test('replace text decode - Array.prototype.join, match stack', (assert) => {
runScriptlet(name, ['Array.prototype.join', 'disable_ads:false', 'disable_ads:true', 'base64', 'decodeStackFunc']);
const decodeStackFunc = () => {
Expand All @@ -203,12 +216,12 @@ test('log - Array.prototype.join, base64', (assert) => {
const argsLength = args.length;
const consoleContent = args[0];
if (argsLength === 1 && consoleContent.includes('Original text content:')) {
assert.ok(consoleContent.includes('Original text content:'), 'should log original text in console');
assert.ok(consoleContent.includes('Zm9vOmJhcixxd2VydHk6MTIzNA=='), 'should log original text in console');
assert.ok(consoleContent.includes('Original text content:'), '1 should log original text in console');
assert.ok(consoleContent.includes('Zm9vOmJhcixxd2VydHk6MTIzNA=='), '2 should log original text in console');
}
if (argsLength === 1 && consoleContent.includes('Decoded text content:')) {
assert.ok(consoleContent.includes('Decoded text content:'), 'log information about decoded content');
assert.ok(consoleContent.includes('foo:bar,qwerty:1234'), 'log information about decoded content');
assert.ok(consoleContent.includes('Decoded text content:'), '1 log information about decoded content');
assert.ok(consoleContent.includes('foo:bar,qwerty:1234'), '2 log information about decoded content');
}
if (argsLength === 1 && consoleContent.includes('Decoded text content was not modified')) {
assert.ok(
Expand All @@ -227,7 +240,7 @@ test('log - Array.prototype.join, base64', (assert) => {
const splittedText = textInBase64.split('');
const result = splittedText.join('');
const decodedResult = atob(result);
assert.deepEqual(result, expectedTextInBase64, 'Text content is intact');
assert.deepEqual(decodedResult, expectedText, 'Text content is intact');
assert.deepEqual(result, expectedTextInBase64, 'Encoded text content is intact');
assert.deepEqual(decodedResult, expectedText, 'Decoded text content is intact');
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
});

0 comments on commit 788f70b

Please sign in to comment.