mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
fix: safe mode validations (#2912)
This commit is contained in:
parent
4fbd2f0bdb
commit
4bdbfb5c0c
@ -64,7 +64,7 @@ const JsSandboxModeModal = ({ collection }) => {
|
|||||||
<span className='beta-tag'>BETA</span>
|
<span className='beta-tag'>BETA</span>
|
||||||
</label>
|
</label>
|
||||||
<p className='text-sm text-muted mt-1'>
|
<p className='text-sm text-muted mt-1'>
|
||||||
JavaScript code is executed in a secure sandbox and cannot excess your filesystem or execute system commands.
|
JavaScript code is executed in a secure sandbox and cannot access your filesystem or execute system commands.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label htmlFor="developer" className="flex flex-row gap-2 mt-6 cursor-pointer">
|
<label htmlFor="developer" className="flex flex-row gap-2 mt-6 cursor-pointer">
|
||||||
|
@ -50,7 +50,7 @@ const SecuritySettings = ({ collection }) => {
|
|||||||
<span className='beta-tag'>BETA</span>
|
<span className='beta-tag'>BETA</span>
|
||||||
</label>
|
</label>
|
||||||
<p className='text-sm text-muted mt-1'>
|
<p className='text-sm text-muted mt-1'>
|
||||||
JavaScript code is executed in a secure sandbox and cannot excess your filesystem or execute system commands.
|
JavaScript code is executed in a secure sandbox and cannot access your filesystem or execute system commands.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label htmlFor="developer" className="flex flex-row gap-2 mt-6 cursor-pointer">
|
<label htmlFor="developer" className="flex flex-row gap-2 mt-6 cursor-pointer">
|
||||||
|
@ -10,6 +10,7 @@ const { newQuickJSWASMModule, memoizePromiseFactory } = require('quickjs-emscrip
|
|||||||
// execute `npm run sandbox:bundle-libraries` if the below file doesn't exist
|
// execute `npm run sandbox:bundle-libraries` if the below file doesn't exist
|
||||||
const getBundledCode = require('../bundle-browser-rollup');
|
const getBundledCode = require('../bundle-browser-rollup');
|
||||||
const addPathShimToContext = require('./shims/lib/path');
|
const addPathShimToContext = require('./shims/lib/path');
|
||||||
|
const { marshallToVm } = require('./utils');
|
||||||
|
|
||||||
let QuickJSSyncContext;
|
let QuickJSSyncContext;
|
||||||
const loader = memoizePromiseFactory(() => newQuickJSWASMModule());
|
const loader = memoizePromiseFactory(() => newQuickJSWASMModule());
|
||||||
@ -48,14 +49,18 @@ const executeQuickJsVm = ({ script: externalScript, context: externalContext, sc
|
|||||||
const vm = QuickJSSyncContext;
|
const vm = QuickJSSyncContext;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { bru, req, res } = externalContext;
|
const { bru, req, res, ...variables } = externalContext;
|
||||||
|
|
||||||
bru && addBruShimToContext(vm, bru);
|
bru && addBruShimToContext(vm, bru);
|
||||||
req && addBrunoRequestShimToContext(vm, req);
|
req && addBrunoRequestShimToContext(vm, req);
|
||||||
res && addBrunoResponseShimToContext(vm, res);
|
res && addBrunoResponseShimToContext(vm, res);
|
||||||
|
|
||||||
const templateLiteralText = `\`${externalScript}\`;`;
|
Object.entries(variables)?.forEach(([key, value]) => {
|
||||||
const jsExpressionText = `${externalScript};`;
|
vm.setProp(vm.global, key, marshallToVm(value, vm));
|
||||||
|
});
|
||||||
|
|
||||||
|
const templateLiteralText = `\`${externalScript}\``;
|
||||||
|
const jsExpressionText = `${externalScript}`;
|
||||||
|
|
||||||
let scriptText = scriptType === 'template-literal' ? templateLiteralText : jsExpressionText;
|
let scriptText = scriptType === 'template-literal' ? templateLiteralText : jsExpressionText;
|
||||||
|
|
||||||
@ -66,7 +71,6 @@ const executeQuickJsVm = ({ script: externalScript, context: externalContext, sc
|
|||||||
return e;
|
return e;
|
||||||
} else {
|
} else {
|
||||||
let v = vm.dump(result.value);
|
let v = vm.dump(result.value);
|
||||||
let vString = v.toString();
|
|
||||||
result.value.dispose();
|
result.value.dispose();
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@ -124,6 +128,9 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
|||||||
// resolve module
|
// resolve module
|
||||||
return globalThis.requireObject[mod];
|
return globalThis.requireObject[mod];
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
throw new Error("Cannot find module " + mod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,10 @@ const addLocalModuleLoaderShimToContext = (vm, collectionPath) => {
|
|||||||
throw new Error('Access to files outside of the collectionPath is not allowed.');
|
throw new Error('Access to files outside of the collectionPath is not allowed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
throw new Error(`Cannot find module ${filename}`);
|
||||||
|
}
|
||||||
|
|
||||||
let code = fs.readFileSync(filePath).toString();
|
let code = fs.readFileSync(filePath).toString();
|
||||||
|
|
||||||
return marshallToVm(code, vm);
|
return marshallToVm(code, vm);
|
||||||
|
@ -13,7 +13,9 @@ post {
|
|||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"boolean": false,
|
"boolean": false,
|
||||||
"number": 1,
|
"number_1": 1,
|
||||||
|
"number_2": 0,
|
||||||
|
"number_3": -1,
|
||||||
"string": "bruno",
|
"string": "bruno",
|
||||||
"array": [1, 2, 3, 4, 5],
|
"array": [1, 2, 3, 4, 5],
|
||||||
"object": {
|
"object": {
|
||||||
@ -24,25 +26,38 @@ body:json {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vars:pre-request {
|
vars:pre-request {
|
||||||
number: 1
|
|
||||||
boolean: false
|
boolean: false
|
||||||
undefined: undefined
|
undefined: undefined
|
||||||
null: null
|
null: null
|
||||||
string: foo
|
string: foo
|
||||||
|
number_1: 1
|
||||||
|
number_2: 0
|
||||||
|
number_3: -1
|
||||||
}
|
}
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
req.body.boolean: isBoolean false
|
req.body.boolean: isBoolean false
|
||||||
req.body.number: isNumber 1
|
req.body.number_1: isNumber 1
|
||||||
req.body.undefined: isUndefined undefined
|
req.body.undefined: isUndefined undefined
|
||||||
req.body.string: isString bruno
|
req.body.string: isString bruno
|
||||||
req.body.null: isNull null
|
req.body.null: isNull null
|
||||||
req.body.array: isArray
|
req.body.array: isArray
|
||||||
req.body.boolean: eq false
|
req.body.boolean: eq false
|
||||||
req.body.number: eq 1
|
req.body.number_1: eq 1
|
||||||
req.body.undefined: eq undefined
|
req.body.undefined: eq undefined
|
||||||
req.body.string: eq bruno
|
req.body.string: eq bruno
|
||||||
req.body.null: eq null
|
req.body.null: eq null
|
||||||
|
req.body.number_2: eq 0
|
||||||
|
req.body.number_3: eq -1
|
||||||
|
req.body.number_2: isNumber
|
||||||
|
req.body.number_3: isNumber
|
||||||
|
boolean: eq false
|
||||||
|
undefined: eq undefined
|
||||||
|
null: eq null
|
||||||
|
string: eq foo
|
||||||
|
number_1: eq 1
|
||||||
|
number_2: eq 0
|
||||||
|
number_3: eq -1
|
||||||
}
|
}
|
||||||
|
|
||||||
tests {
|
tests {
|
||||||
@ -51,7 +66,9 @@ tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("number pre var", function() {
|
test("number pre var", function() {
|
||||||
expect(bru.getRequestVar('number')).to.eql(1);
|
expect(bru.getRequestVar('number_1')).to.eql(1);
|
||||||
|
expect(bru.getRequestVar('number_2')).to.eql(0);
|
||||||
|
expect(bru.getRequestVar('number_3')).to.eql(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("null pre var", function() {
|
test("null pre var", function() {
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
meta {
|
||||||
|
name: vars asserts
|
||||||
|
type: http
|
||||||
|
seq: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{host}}/api/echo/json
|
||||||
|
body: json
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"boolean": false,
|
||||||
|
"number": 1,
|
||||||
|
"string": "bruno",
|
||||||
|
"array": [1, 2, 3, 4, 5],
|
||||||
|
"object": {
|
||||||
|
"hello": "bruno"
|
||||||
|
},
|
||||||
|
"null": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vars:pre-request {
|
||||||
|
vars_asserts__request_var: vars_asserts__request_var__value
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
vars_asserts__request_var: eq vars_asserts__request_var__value
|
||||||
|
vars_asserts__runtime_var: eq vars_asserts__runtime_var__value
|
||||||
|
vars_asserts__env_var: eq vars_asserts__env_var__value
|
||||||
|
}
|
||||||
|
|
||||||
|
script:pre-request {
|
||||||
|
bru.setVar('vars_asserts__runtime_var', 'vars_asserts__runtime_var__value');
|
||||||
|
bru.setEnvVar('vars_asserts__env_var', 'vars_asserts__env_var__value');
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
meta {
|
||||||
|
name: invalid and valid module imports
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{host}}/ping
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
invalid_module_error_thrown: eq true
|
||||||
|
valid_module_no_error: eq true
|
||||||
|
}
|
||||||
|
|
||||||
|
script:pre-request {
|
||||||
|
try {
|
||||||
|
bru.setVar('invalid_module_error_thrown', false);
|
||||||
|
// should throw an error
|
||||||
|
const invalid = require("./lib/invalid");
|
||||||
|
}
|
||||||
|
catch(error) {
|
||||||
|
bru.setVar('invalid_module_error_thrown', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
bru.setVar('valid_module_no_error', true);
|
||||||
|
// should not throw an error
|
||||||
|
const math = require("./lib/math");
|
||||||
|
}
|
||||||
|
catch(error) {
|
||||||
|
bru.setVar('valid_module_no_error', false);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user