https://github.com/azu/restrict-javascript
Define restrict JavaScript syntax and validate it.
https://github.com/azu/restrict-javascript
ast javascript safe subset validation
Last synced: 10 months ago
JSON representation
Define restrict JavaScript syntax and validate it.
- Host: GitHub
- URL: https://github.com/azu/restrict-javascript
- Owner: azu
- License: mit
- Created: 2019-11-30T02:53:59.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-08-23T13:38:44.000Z (almost 4 years ago)
- Last Synced: 2025-08-15T13:22:56.805Z (11 months ago)
- Topics: ast, javascript, safe, subset, validation
- Language: TypeScript
- Homepage:
- Size: 49.8 KB
- Stars: 7
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# restrict-javascript
Define restrict JavaScript syntax and validate it.
## Motivation
This validation library aim to define limited JavaScript subset.
That subset will be safe by default.
Safe means that does not call any untrusted function.
## Do
Validate following untrusted function calls and get errors.
```js
alert("hello");
alert`hello`;
const a = alert;
a("hello");
const alertName = "alert";
window[alertName]("hello");
```
Following code is passed, because it is safe.
```js
`text`;
```
### Do Not
This validation does not provide sandbox feature.
It means that the code can refer to any object like `window` by default.
In other hands, `__proto__` and `construsctor` is restricted by default.
This validation will be used with [vm](https://nodejs.org/api/vm.html) modules.
## Install
Install with [npm](https://www.npmjs.com/):
npm install restrict-javascript
## Usage
This validation is used with [Espree](https://github.com/eslint/espree).
:memo: Pass `loc: true` option to `espree.parse` function. It is needed to error position.
```js
import { validateAST } from "restrict-javascript";
const espree = require("espree");
const untrustedJSCode = `
function add(x, y){
return x + y
}
const total = add(1, 2);
`;
const AST = espree.parse(untrustedJSCode, {
loc: true, // <= require `loc` option
// Other options is optional
ecmaVersion: 2015
});
const validationResult = validateAST(AST);
if (!validationResult.ok) {
assert.deepStrictEqual(validationResult.errors, [
{id: 'DISALLOW_NODE_TYPE', line: 2, column: 0}, // function
{id: 'DISALLOW_NODE_TYPE', line: 6, column: 0}, // const
{id: 'DISALLOW_NODE_TYPE', line: 6, column: 6}, // =
{id: 'DISALLOW_UNTRUSTED_FUNCTION_CALL', line: 6, column: 14}, // add(1, 2)
{id: 'DISALLOW_NODE_TYPE', line: 6, column: 14} //function call node
]
)
}
```
### Default Options
Default Config is very strict setting.
It aim to prevent to define untrusted function/variables and invoke untrusted functions.
- Disallow any function/method/class call
- includes normal function call, `new` expression, and Tagged Function call
- Disallow any function/method/class declaration
- NG: `function`, `class`, `=>`
- Disallow any declaration variables
- NG: use `var`, `let`, `const`
- Disallow any assignment variables
- NG: `foo = "value";`
- Disallow lookup `__proto__` and `constructor` property
Summary: Disallow to create functions and call functions, and lookup the above
You can add allow list by `allow*` option.
### `allowFunctionNames: string[]`
This options allow calling specified function names.
Example: Allow `String()` and `alert()`
```js
{
allowFunctionNames: ["String", "alert"]
}
```
### `allowMethodNames: string[]`
This options allow calling specified method names.
Example: Allow `Math.random()`
```js
{
allowMethodNames: ["Math.random"]
}
```
This options accept `?` as place holder value. `?` match any name.
Example: Allow `"string".replace("a", "b")`.
`?` match `"string"`.
```js
{
allowMethodNames: ["?.replace"]
}
```
Note: method chain matching.
You can match `[].map().filter()` by following options.
```js
{
allowMethodNames: ["?.map.filter"]
}
```
### `allowNodeTypes: string[]`
This options allow to use specified `ESTree.Node`.
Default: allow safe Node types.
This options will be override default options. Be careful.
- [estree/estree: The ESTree Spec](https://github.com/estree/estree)
### `allowNodesIncludesChildren: ESTree.Node[]`
This options allow node and node's children.
Specify ESTree node object and match it partially.
This options allow especial patterns.
For example, You can allow `new Date().getTime()` signature by following options:
```js
{
allowNodesIncludesChildren: [
{
type: "ExpressionStatement",
expression: {
type: "CallExpression",
callee: {
type: "MemberExpression",
object: {
type: "NewExpression",
callee: {
type: "Identifier",
name: "Date"
},
arguments: []
},
property: {
type: "Identifier",
name: "getTime"
},
computed: false
},
arguments: []
}
}
]
}
```
See also [test/fixtures/ok.options.allowNodesIncludesChildren/](test/fixtures/ok.options.allowNodesIncludesChildren/)
:memo: Notice: This options force skip matched node, be careful treat!
Tips: [AST explorer](https://astexplorer.net/) is useful for the options.
### `debug: boolean`
Enable debug options. It is useful for debugging.
- Add `node` property to each errors.
## Changelog
See [Releases page](https://github.com/azu/restrict-javascript/releases).
## Running tests
Install devDependencies and Run `npm test`:
npm test
## Contributing
Pull requests and stars are always welcome.
For bugs and feature requests, [please create an issue](https://github.com/azu/restrict-javascript/issues).
1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D
## Author
- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)
## License
MIT © azu