Skip to content

Commit

Permalink
feat: add safe eval for browser and eval option (#185)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

- Removes `preventEval` property. Prefer `eval: false` instead.
- Changed behavior of `eval` property. In the browser, `eval`/`Function` won't be used by default to evaluate expressions. Instead, we'll safely evaluate using a subset of JavaScript. To resume using unsafe eval in the browser, pass in the option `eval: "native"`

Also:
- feat: add `ignoreEvalErrors` property.
  • Loading branch information
80avin authored May 5, 2024
1 parent 324b8e5 commit f08447c
Show file tree
Hide file tree
Showing 26 changed files with 5,279 additions and 1,210 deletions.
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,20 @@ evaluate method (as the first argument) include:
it is necessary to distinguish between a result which is a failure
and one which is an empty array), it is recommended to switch the
default to `false`.
- ***preventEval*** (**default: false**) - Although JavaScript evaluation
expressions are allowed by default, for security reasons (if one is
operating on untrusted user input, for example), one may wish to
set this option to `true` to throw exceptions when these expressions
are attempted.
- ***eval*** (**default: "safe"**) - Script evaluation method.
`safe`: In browser, it will use a minimal scripting engine which doesn't
use `eval` or `Function` and satisfies Content Security Policy. In NodeJS,
it has no effect and is equivalent to native as scripting is safe there.
`native`: uses the native scripting capabilities. i.e. unsafe `eval` or
`Function` in browser and `vm.Script` in nodejs. `false`: Disable JavaScript
evaluation expressions and throw exceptions when these expressions are attempted.
`callback [ (code, context) => value]`: A custom implementation which is called
with `code` and `context` as arguments to return the evaluated value.
`class`: A class which is created with `code` as constructor argument and code
is evaluated by calling `runInNewContext` with `context`.
``
- ***ignoreEvalErrors*** (**default: false**) - Ignore errors encountered during
script evaluation.
- ***parent*** (**default: null**) - In the event that a query could be
made to return the root node, this allows the parent of that root node
to be returned within results.
Expand Down
2 changes: 1 addition & 1 deletion badges/coverage-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion badges/tests-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 47 additions & 3 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,59 @@
<body>
<h2>JSONPath Demo <i id="demoNode">(To demo on Node instead, see the <a href="https://npm.runkit.com/jsonpath-plus">library on Runkit</a>.)</i>
</h2>
<form>
<form onsubmit="return false">
<div>
<label><b>JSONPath:</b>
<input id="jsonpath" placeholder="$.books" />
<input type="text" id="jsonpath" placeholder="$.books" value="$..book[?(@parent.bicycle && @parent.bicycle.color === &quot;red&quot;)].category" />
</label>
<label><b>eval:</b>
<select id="eval">
<option value="safe">safe</option>
<option value="native">native</option>
<option value="false">false</option>
</select>
</label>
</div>
<div id="jsonSampleContainer" class="container">
<label><b>JSON sample:</b>
<textarea id="jsonSample" placeholder="{&quot;books&quot;: []}"></textarea>
<textarea id="jsonSample" placeholder="{&quot;books&quot;: []}">
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
</textarea>
</label>
</div>
<div id="resultContainer" class="container">
Expand Down
7 changes: 6 additions & 1 deletion demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const updateResults = () => {
}
const result = new JSONPath.JSONPath({
path: $('#jsonpath').value,
json
json,
eval: $('#eval').value === 'false' ? false : $('#eval').value
});

$('#results').value = JSON.stringify(result, null, 2);
Expand All @@ -46,3 +47,7 @@ $('#jsonpath').addEventListener('input', () => {
$('#jsonSample').addEventListener('input', () => {
updateResults();
});

$('#eval').addEventListener('change', () => {
updateResults();
});
Loading

0 comments on commit f08447c

Please sign in to comment.