// Test that debugger evaluation can bypass CSP restrictions when bypassCSP option is set.
var g = newGlobal({newCompartment: true}); var dbg = new Debugger(g);
// Create a function to trigger a debugger statement before enabling CSP.
g.eval("function triggerDebugger() { debugger; }");
// Create functions that will use eval/new Function and which will be called // from Frame.eval.
g.eval("function triggerEval() { return eval('2 + 2'); }");
g.eval("function triggerNewFunction() { return new Function('return 2 + 2')(); }");
const EXPECTED_VALUE = 4; function assertSuccess(expression, options = {}) {
let evaluated = false;
dbg.onDebuggerStatement = function (frame) {
assertEq(frame.eval(expression, options).return, EXPECTED_VALUE);
evaluated = true;
};
g.triggerDebugger();
assertEq(evaluated, true);
}
function assertThrows(expression, options = {}) {
let evaluated = false;
dbg.onDebuggerStatement = function (frame) {
assertEq(frame.eval(expression, options).throw !== undefined, true);
evaluated = true;
};
g.triggerDebugger();
assertEq(evaluated, true);
}
// Default value for bypassCSP, should all fail
assertThrows("eval('2 + 2')");
assertThrows("new Function('return 2 + 2')()");
assertThrows("triggerEval()");
assertThrows("triggerNewFunction()");
// Define a few functions using eval with and without bypassCSP. // They should both behave the same when triggered from a later Frame.eval, and // only the bypassCSP flag for the later Frame.eval should matter.
dbg.onDebuggerStatement = function (frame) {
frame.eval("globalThis.fnWithBypass = () => eval('2 + 2')", { bypassCSP: true });
frame.eval("globalThis.fnWithoutBypass = () => eval('2 + 2')", { bypassCSP: false });
};
g.triggerDebugger();
// Call the function defined with bypassCSP=true, should only work when // bypassCSP is true for the current Frame.eval.
assertThrows("globalThis.fnWithBypass()");
assertThrows("globalThis.fnWithBypass()", { bypassCSP: false });
assertSuccess("globalThis.fnWithBypass()", { bypassCSP: true });
// Call the function defined with bypassCSP=false, should only work when // bypassCSP is true for the current Frame.eval.
assertThrows("globalThis.fnWithoutBypass()");
assertThrows("globalThis.fnWithoutBypass()", { bypassCSP: false });
assertSuccess("globalThis.fnWithoutBypass()", { bypassCSP: true });
// Test async code with bypassCSP=true, only the eval before the await should be // successful.
dbg.onDebuggerStatement = function (frame) {
frame.onPop = completion => {
frame.eval(asyncEvalExpression, { bypassCSP: true });
dbg.removeDebuggee(g); // avoid the DebuggeeWouldRun exception
drainJobQueue();
dbg.addDebuggee(g);
}
};
g.triggerDebugger();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.