inspector: Add flag to Runtime.evaluate() for unsafe eval
evaluate() bypassed CSP for unsafe-eval by default. This is a useful option for debugging clients, but is not always what we want. e.g. in the devtools console we want to match the page's CSP settings to make debugging CSP issues on the page easier. Add a toggle that keeps the current behavior by default. Bug: chromium:1084558 Change-Id: Ia01142d5be00f8ef5f65e5eeba17549efc6f9120 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2250245 Commit-Queue: Peter Marshall <petermarshall@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#68432}
This commit is contained in:
parent
c6642b5112
commit
f510c66b96
@ -1370,6 +1370,11 @@ domain Runtime
|
||||
# Note that `let` variables can only be re-declared if they originate from
|
||||
# `replMode` themselves.
|
||||
experimental optional boolean replMode
|
||||
# The Content Security Policy (CSP) for the target might block 'unsafe-eval'
|
||||
# which includes eval(), Function(), setTimeout() and setInterval()
|
||||
# when called with non-callable arguments. This flag bypasses CSP for this
|
||||
# evaluation and allows unsafe-eval. Defaults to true.
|
||||
experimental optional boolean allowUnsafeEvalBlockedByCSP
|
||||
returns
|
||||
# Evaluation result.
|
||||
RemoteObject result
|
||||
|
@ -237,6 +237,7 @@ void V8RuntimeAgentImpl::evaluate(
|
||||
Maybe<bool> generatePreview, Maybe<bool> userGesture,
|
||||
Maybe<bool> maybeAwaitPromise, Maybe<bool> throwOnSideEffect,
|
||||
Maybe<double> timeout, Maybe<bool> disableBreaks, Maybe<bool> maybeReplMode,
|
||||
Maybe<bool> allowUnsafeEvalBlockedByCSP,
|
||||
std::unique_ptr<EvaluateCallback> callback) {
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
|
||||
"EvaluateScript");
|
||||
@ -262,8 +263,10 @@ void V8RuntimeAgentImpl::evaluate(
|
||||
|
||||
const bool replMode = maybeReplMode.fromMaybe(false);
|
||||
|
||||
// Temporarily enable allow evals for inspector.
|
||||
scope.allowCodeGenerationFromStrings();
|
||||
if (allowUnsafeEvalBlockedByCSP.fromMaybe(true)) {
|
||||
// Temporarily enable allow evals for inspector.
|
||||
scope.allowCodeGenerationFromStrings();
|
||||
}
|
||||
v8::MaybeLocal<v8::Value> maybeResultValue;
|
||||
{
|
||||
V8InspectorImpl::EvaluateScope evaluateScope(scope);
|
||||
|
@ -68,7 +68,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend {
|
||||
Maybe<bool> generatePreview, Maybe<bool> userGesture,
|
||||
Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect,
|
||||
Maybe<double> timeout, Maybe<bool> disableBreaks,
|
||||
Maybe<bool> replMode,
|
||||
Maybe<bool> replMode, Maybe<bool> allowUnsafeEvalBlockedByCSP,
|
||||
std::unique_ptr<EvaluateCallback>) override;
|
||||
void awaitPromise(const String16& promiseObjectId, Maybe<bool> returnByValue,
|
||||
Maybe<bool> generatePreview,
|
||||
|
@ -31,6 +31,104 @@ Running test: testEvaluatePaused
|
||||
}
|
||||
}
|
||||
|
||||
Running test: testEvaluateUnsafeEval
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
description : 2
|
||||
type : number
|
||||
value : 2
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
description : 2
|
||||
type : number
|
||||
value : 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Running test: testEvaluateUnsafeEvalDisableBypass
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
exceptionDetails : {
|
||||
columnNumber : 0
|
||||
exception : {
|
||||
className : EvalError
|
||||
description : EvalError: Code generation from strings disallowed for this context at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
url :
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Uncaught
|
||||
}
|
||||
result : {
|
||||
className : EvalError
|
||||
description : EvalError: Code generation from strings disallowed for this context at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
exceptionDetails : {
|
||||
columnNumber : 0
|
||||
exception : {
|
||||
className : EvalError
|
||||
description : EvalError: Code generation from strings disallowed for this context at new Function (<anonymous>) at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
url :
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Uncaught
|
||||
}
|
||||
result : {
|
||||
className : EvalError
|
||||
description : EvalError: Code generation from strings disallowed for this context at new Function (<anonymous>) at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Running test: testCallFunctionOn
|
||||
{
|
||||
id : <messageId>
|
||||
|
@ -36,6 +36,24 @@ InspectorTest.runAsyncTestSuite([
|
||||
await Protocol.Debugger.resume();
|
||||
},
|
||||
|
||||
async function testEvaluateUnsafeEval() {
|
||||
contextGroup.addScript(`inspector.setAllowCodeGenerationFromStrings(false);`);
|
||||
await Protocol.Debugger.onceScriptParsed();
|
||||
InspectorTest.logMessage(
|
||||
await Protocol.Runtime.evaluate({expression: 'eval("1+1")'}));
|
||||
InspectorTest.logMessage(
|
||||
await Protocol.Runtime.evaluate({expression: 'new Function("return 1+1")()'}));
|
||||
},
|
||||
|
||||
async function testEvaluateUnsafeEvalDisableBypass() {
|
||||
contextGroup.addScript(`inspector.setAllowCodeGenerationFromStrings(false);`);
|
||||
await Protocol.Debugger.onceScriptParsed();
|
||||
InspectorTest.logMessage(
|
||||
await Protocol.Runtime.evaluate({expression: 'eval("1+1")', allowUnsafeEvalBlockedByCSP: false}));
|
||||
InspectorTest.logMessage(
|
||||
await Protocol.Runtime.evaluate({expression: 'new Function("return 1+1")()', allowUnsafeEvalBlockedByCSP: false}));
|
||||
},
|
||||
|
||||
async function testCallFunctionOn() {
|
||||
await contextGroup.addScript(`inspector.setAllowCodeGenerationFromStrings(false);`);
|
||||
const globalObject = await Protocol.Runtime.evaluate({expression: 'this'});
|
||||
|
Loading…
Reference in New Issue
Block a user