|
2 | 2 |
|
3 | 3 | This library is part of the [NX framework](http://nx-framework.com/).
|
4 | 4 | The purpose of this library is to allow the execution of strings as code in the
|
5 |
| -context of a sandbox object with optional security restrictions. |
| 5 | +context of a sandbox object. |
6 | 6 |
|
7 | 7 | ## Installation
|
8 | 8 |
|
@@ -46,137 +46,16 @@ strict mode.
|
46 | 46 | const expression = compiler.compileExpression('prop1 || prop2')
|
47 | 47 | ```
|
48 | 48 |
|
49 |
| -### compiler.secure(String, ..., String) |
50 |
| - |
51 |
| -This methods secures the sandbox and the compiled code. It prevents access to the global scope |
52 |
| -from inside the passed code. You can optionally pass global variable names as strings to expose |
53 |
| -them to the sandbox. Exposed global variables and the prototypes of literals (strings, numbers, etc.) |
54 |
| -are deep frozen with Object.freeze() to prevent security leaks. Deep frozen means that their whole prototype chain and all constructors found on that prototype chain are frozen. Calling secure more than once throws an error. |
55 |
| - |
56 |
| -```js |
57 |
| -compiler.secure('console', 'setTimeout') |
58 |
| -``` |
59 |
| - |
60 |
| -This method is experimental, please do not use it in a production environment yet! |
61 |
| - |
62 | 49 | ## Example
|
63 | 50 |
|
64 | 51 | ```js
|
65 | 52 | const compiler = require('@risingstack/nx-compile')
|
66 |
| -compiler.secure('console') |
67 |
| - |
68 |
| -const sandbox = {name: 'nx-compile', version: '1.0'} |
69 |
| -const code = compiler.compileCode('console.log(name + version)', sandbox) |
70 |
| - |
71 |
| -// outputs 'nx-compile1.0' to console |
72 |
| -code() |
73 |
| -``` |
74 |
| - |
75 |
| -## Features, limitations and edge cases |
76 |
| - |
77 |
| -#### lookup order |
78 |
| - |
79 |
| -The compiled function tries to retrieve the variables first from the sandbox and then from the global object. |
80 |
| - |
81 |
| -```js |
82 |
| -const compiler = require('@risingstack/nx-compile') |
83 |
| - |
84 |
| -global.prop = 'globalValue' // in a browser global would be window |
85 |
| -const sandbox = {prop: 'sandboxValue'} |
86 |
| - |
87 |
| -const code = compiler.compileCode('console.log(prop)', sandbox) |
88 |
| - |
89 |
| -// outputs 'sandboxValue' to the console |
90 |
| -code() |
91 |
| - |
92 |
| - |
93 |
| -// the key is still present in the sandbox |
94 |
| -// outputs 'undefined' to the console |
95 |
| -sandbox.prop = undefined |
96 |
| -code() |
97 |
| - |
98 |
| -// the key is not present in the sandbox |
99 |
| -// outputs 'globalValue' to the console |
100 |
| -delete sandbox.prop |
101 |
| -code() |
102 |
| -``` |
103 |
| - |
104 |
| -#### local variables can't be exposed |
105 |
| - |
106 |
| -You can only expose variables declared on the global object. |
107 |
| - |
108 |
| -```js |
109 |
| -// this code is assumed to run in a module, so declared variables are not global |
110 |
| -const compiler = require('@risingstack/nx-compile') |
111 |
| - |
112 |
| -const localVariable = 'localValue' |
113 |
| -const code = compiler.compileCode('console.log(localVariable)', {}) |
114 |
| - |
115 |
| -// tries to retrieve 'localVariable' from the global object |
116 |
| -// throws a ReferenceError |
117 |
| -code() |
118 |
| -``` |
119 |
| - |
120 |
| -#### 'this' inside the sandboxed code |
121 |
| - |
122 |
| -`this` points to the sandbox inside the sandboxed code. |
123 |
| - |
124 |
| -```js |
125 |
| -const compiler = require('@risingstack/nx-compile') |
126 |
| - |
127 |
| -const message = 'local message' |
128 |
| -const sandbox = {message: 'sandboxed message'} |
129 |
| -const code = compiler.compileCode('console.log(this.message)', sandbox) |
130 |
| - |
131 |
| -// outputs 'sandboxed message' to the console |
132 |
| -code() |
133 |
| -``` |
134 |
| - |
135 |
| -#### functions defined inside the sandboxed code |
136 |
| - |
137 |
| -Functions defined inside the sandboxed code are also sandboxed. |
138 |
| - |
139 |
| -```js |
140 |
| -const compiler = require('@risingstack/nx-compile') |
141 |
| - |
142 |
| -const message = 'local message' |
143 |
| -const sandbox = {message: 'sandboxed message'} |
144 |
| -const code = compiler.compileCode('setTimeout(() => console.log(message))', sandbox) |
145 |
| - |
146 |
| -// outputs 'sandboxed message' to the console |
147 |
| -code() |
148 |
| -``` |
149 |
| - |
150 |
| -#### globals in secure mode |
151 |
| - |
152 |
| -Unexposed global variable access is prevented in secure mode. |
153 |
| - |
154 |
| -```js |
155 |
| -const compiler = require('@risingstack/nx-compile') |
156 |
| -compiler.secure('console') |
157 |
| - |
158 |
| -const sandbox = {} |
159 |
| -const code = compiler.compileCode('console.log(setTimeout)', sandbox) |
160 |
| - |
161 |
| -// console is exposed, setTimeout is not exposed |
162 |
| -// outputs 'undefined' to the console |
163 |
| -code() |
164 |
| -``` |
165 |
| - |
166 |
| -#### frozen objects in secure mode |
167 |
| - |
168 |
| -Exposed globals and literal prototypes are frozen in secure mode. |
169 |
| - |
170 |
| -```js |
171 |
| -const compiler = require('@risingstack/nx-compile') |
172 |
| -compiler.secure('console') |
173 | 53 |
|
174 |
| -const sandbox = {} |
175 |
| -const rawCode = '({}).constructor.create = function(/* evil stuff */) {}' |
176 |
| -const code = compiler.compileCode(, sandbox) |
| 54 | +const sandbox = {name: 'nx-compile', version: '3.0.0'} |
| 55 | +const expression = compiler.compileExpression('name + version)', sandbox) |
177 | 56 |
|
178 |
| -// throws a TypeError, Object.create() can not be overwritten |
179 |
| -code() |
| 57 | +// outputs 'nx-compile3.0.0' to console |
| 58 | +console.log(expression()) |
180 | 59 | ```
|
181 | 60 |
|
182 | 61 | ## Contributions
|
|
0 commit comments