You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: files/en-us/web/javascript/reference/global_objects/eval/index.md
+95-5Lines changed: 95 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,12 @@ sidebar: jssidebar
7
7
---
8
8
9
9
> [!WARNING]
10
-
> Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. See [Never use direct eval()!](#never_use_direct_eval!), below.
10
+
> The argument passed to this method is dynamically evaluated and executed as JavaScript.
11
+
> APIs like this are known as [injection sinks](/en-US/docs/Web/API/Trusted_Types_API#concepts_and_usage), and are potentially a vector for [cross-site-scripting (XSS)](/en-US/docs/Web/Security/Attacks/XSS) attacks.
12
+
>
13
+
> You can mitigate this risk by always passing {{domxref("TrustedScript")}} objects instead of strings and [enforcing trusted types](/en-US/docs/Web/API/Trusted_Types_API#using_a_csp_to_enforce_trusted_types).
14
+
>
15
+
> See [Security considerations](#security_considerations) for more information.
11
16
12
17
The **`eval()`** function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.
13
18
@@ -36,15 +41,22 @@ eval(script)
36
41
### Parameters
37
42
38
43
-`script`
39
-
- : A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects. It will be parsed as a script, so [`import`](/en-US/docs/Web/JavaScript/Reference/Statements/import) declarations (which can only exist in modules) are not allowed.
44
+
- : A {{domxref("TrustedScript")}} instance or string representing a JavaScript expression, statement, or sequence of statements.
45
+
The expression can include variables and properties of existing objects. It will be parsed as a script, so [`import`](/en-US/docs/Web/JavaScript/Reference/Statements/import) declarations (which can only exist in modules) are not allowed.
40
46
41
47
### Return value
42
48
43
-
The completion value of evaluating the given code. If the completion value is empty, {{jsxref("undefined")}} is returned. If `script` is not a string primitive, `eval()` returns the argument unchanged.
49
+
The completion value of evaluating the given code. If the completion value is empty, {{jsxref("undefined")}} is returned.
50
+
If `script` is not a {{domxref("TrustedScript")}} or string primitive, `eval()` returns the argument unchanged.
44
51
45
52
### Exceptions
46
53
47
-
Throws any exception that occurs during evaluation of the code, including {{jsxref("SyntaxError")}} if `script` fails to be parsed as a script.
54
+
- {{jsxref("SyntaxError")}}
55
+
- : The `script` parameter cannot be parsed as a script.
56
+
- {{jsxref("TypeError")}}
57
+
- : `script` is passed a string when [Trusted Types](/en-US/docs/Web/API/Trusted_Types_API) are [enforced by a CSP](/en-US/docs/Web/API/Trusted_Types_API#using_a_csp_to_enforce_trusted_types) and no default policy is defined.
58
+
59
+
The methods also throws any exception that occurs during evaluation of the code.
48
60
49
61
## Description
50
62
@@ -60,7 +72,8 @@ In strict mode, declaring a variable named `eval` or re-assigning `eval` is a {{
60
72
const eval = 1; // SyntaxError: Unexpected eval or arguments in strict mode
61
73
```
62
74
63
-
If the argument of `eval()` is not a string, `eval()` returns the argument unchanged. In the following example, passing a `String` object instead of a primitive causes `eval()` to return the `String` object rather than evaluating the string.
75
+
If the argument of `eval()` is not a {{domxref("TrustedScript")}} or string, `eval()` returns the argument unchanged.
76
+
In the following example, passing a `String` object instead of a primitive causes `eval()` to return the `String` object rather than evaluating the string.
@@ -345,8 +358,85 @@ Note that since JSON syntax is limited compared to JavaScript syntax, many valid
345
358
346
359
Passing carefully constrained data instead of arbitrary code is a good idea in general. For example, an extension designed to scrape contents of web-pages could have the scraping rules defined in [XPath](/en-US/docs/Web/XML/XPath) instead of JavaScript code.
347
360
361
+
### Security considerations
362
+
363
+
The method can be used to execute arbitrary input with the privileges of the caller.
364
+
If the input is a potentially unsafe string provided by a user, this is a possible vector for [Cross-site-scripting (XSS)](/en-US/docs/Web/Security/Attacks/XSS) attacks.
365
+
366
+
For example, the following code shows how `eval()` might execute `untrustedCode` provided by a user:
Websites with a [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/Guides/CSP) that specifies [`script-src`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src) will prevent such code running by default.
374
+
You can specify [`unsafe-eval`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#unsafe-eval) in your CSP to allow `eval()` to execute, but this is unsafe as it disables one of the main protections of CSP.
375
+
376
+
If you must allow the scripts to run via `eval()` you can mitigate the risks by always assigning a {{domxref("TrustedScript")}} instance instead of a string, and [enforcing trusted types](/en-US/docs/Web/API/Trusted_Types_API#using_a_csp_to_enforce_trusted_types) using the [`require-trusted-types-for`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for) CSP directive.
377
+
This ensures that the input is passed through a transformation function.
378
+
379
+
To allow `eval()` to run, you will additionally need to specify the [`trusted-types-eval` keyword](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#trusted-types-eval) in your CSP `script-src` directive.
380
+
This acts in the same way as `unsafe-eval`, but _only_ allows the method to evaluate if trusted types are enabled (if you were to use `unsafe-eval` it would allow execution even on browsers that do not support trusted types).
381
+
382
+
For example, the required CSP for your site might look like this:
The behavior of the transformation function will depend on the specific use case that requires a user provided script.
389
+
If possible you should lock the allowed scripts to exactly the code that you trust to run.
390
+
If that is not possible, you might allow or block the use of certain functions within the provided input.
391
+
348
392
## Examples
349
393
394
+
Note that the first example shows how to use the method with trusted types.
395
+
The other examples omit this step for brevity.
396
+
397
+
### Using TrustedScript
398
+
399
+
To mitigate the risk of XSS, we should always assign `TrustedScript` instances to the `script` parameter.
400
+
We also need to do this if we're enforcing trusted types for other reasons and we want to allow some script sources that have been permitted (by `CSP: script-src`).
401
+
402
+
Trusted types are not yet supported on all browsers, so first we define the [trusted types tinyfill](/en-US/docs/Web/API/Trusted_Types_API#trusted_types_tinyfill).
403
+
This acts as a transparent replacement for the trusted types JavaScript API:
Next we create a {{domxref("TrustedTypePolicy")}} that defines a {{domxref("TrustedTypePolicy/createScript", "createScript()")}} method for transforming input strings into {{domxref("TrustedScript")}} instances.
411
+
412
+
For the purpose of this example we'll assume that we have a function `transformedScript()` that defines our tranformation/filtering logic.
- : A {{domxref("TrustedScript")}} or a string containing the JavaScript statements comprising the function definition.
59
59
60
+
### Exceptions
61
+
62
+
- {{jsxref("SyntaxError")}}
63
+
- : Function parameter arguments can't be evaluated as valid identifiers, or the `functionBody` can't be parsed as a script.
64
+
- {{jsxref("TypeError")}}
65
+
- : Any parameter is passed a string when [Trusted Types](/en-US/docs/Web/API/Trusted_Types_API) are [enforced by a CSP](/en-US/docs/Web/API/Trusted_Types_API#using_a_csp_to_enforce_trusted_types) and no default policy is defined.
66
+
67
+
The methods also throws any exception that occurs during evaluation of the code.
68
+
60
69
## Description
61
70
62
71
`Function` objects created with the `Function` constructor are parsed when the function is created. This is less efficient than creating a function with a [function expression](/en-US/docs/Web/JavaScript/Reference/Operators/function) or [function declaration](/en-US/docs/Web/JavaScript/Reference/Statements/function) and calling it within your code, because such functions are parsed with the rest of the code.
Websites with a [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/Guides/CSP) that specifies [`script-src`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src) will prevent such code running by default.
112
-
113
-
You can specify [`unsafe-eval`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#unsafe-eval) in your CSP to allow it to execute without any further restriction, but this is unsafe as it disables one of the main protections of CSP.
121
+
You can specify [`unsafe-eval`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#unsafe-eval) in your CSP to allow `Function()` to execute, but this is unsafe as it disables one of the main protections of CSP.
114
122
115
123
If you must allow the scripts to run via `Function()` you can mitigate these issues by always assigning {{domxref("TrustedScript")}} objects instead of strings, and [enforcing trusted types](/en-US/docs/Web/API/Trusted_Types_API#using_a_csp_to_enforce_trusted_types) using the [`require-trusted-types-for`](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for) CSP directive.
116
124
This ensures that the input is passed through a transformation function.
117
-
Instead of specifying `unsafe-eval` you will instead use the CSP [`trusted-types-eval` keyword](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#trusted-types-eval).
125
+
126
+
To allow `Function()` to run, you will additionally need to specify the [`trusted-types-eval` keyword](/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#trusted-types-eval) in your CSP `script-src` directive.
118
127
This acts in the same way as `unsafe-eval`, but _only_ allows the method to evaluate if trusted types are enabled (if you were to use `unsafe-eval` it would allow execution even on browsers that do not support trusted types).
119
128
120
129
For example, the required CSP for your site might look like this:
@@ -189,6 +198,7 @@ sayHello("world");
189
198
190
199
## See also
191
200
201
+
-[Using the function constructor](/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#using_the_function_constructor) in `eval()`
0 commit comments