
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
babel-plugin-run-on-server
Advanced tools
Babel plugin that compiles id mappings for run-on-server.
This is the companion babel plugin for run-on-server.
It does two things:
require
with eval("require")
within runOnServer
callsSee the documentation below for an explanation of each functionality and the rationale behind it.
require
with eval("require")
If you try to compile this using webpack:
runOnServer(
(code) => {
const prettier = require("prettier");
return prettier.format(code);
},
[code]
);
Then webpack will include the "prettier" module in your clientside code.
Since you're only using it serverside, this is unnecesary.
If eval("require")
is used instead of require
, then webpack won't include the module in your clientside code:
runOnServer(
(code) => {
const prettier = eval("require")("prettier");
return prettier.format(code);
},
[code]
);
This plugin can replace require
with eval("require")
for you.
run-on-server
lets you run arbitrary code written on the client (browser, node) on the server (node). It can be great for prototyping, but it's insecure out of the box because its server will eval any JavaScript code you throw at it. That makes it unsuitable for production use because any deployed server would be wide open for attackers to run code on.
This babel plugin solves that issue by making run-on-server/server
refuse to run any code except for the code that appeared in your source.
Here's how it works:
runOnServer
runOnServer
with an autogenerated IDrunOnServer
.This id mappings file can then be fed into run-on-server/server
, which configures the server so that it only runs code appearing in the id mappings file.
It might be easier to visualize with an example:
Normally, run-on-server/client
code looks like this:
// src/client.js
import createClient from "run-on-server/client";
const runOnServer = createClient("http://localhost:3001");
runOnServer(() => process.version).then((version) => console.log(version));
The babel plugin compiles it to this:
// dist/client.js
import createClient from "run-on-server/client";
const runOnServer = createClient("http://localhost:3001");
runOnServer({
id: "073f3eb62747a1dbb64a5527c79224ad",
}).then((version) => console.log(version));
And the babel plugin also creates an id mappings file with this content:
// run-on-server-id-mappings.js
/*
This file was generated by the run-on-server babel plugin. It should not
be edited by hand.
*/ module.exports = {
"073f3eb62747a1dbb64a5527c79224ad": () => process.version,
};
Note that the autogenerated id (073f3eb62747a1dbb64a5527c79224ad
) is the same in the code and the id mappings file.
Now, if you feed the id mappings into run-on-server/server
:
const createServer = require("run-on-server/server");
const server = createServer({
idMappings: require("./run-on-server-id-mappings"),
});
server.listen(3001, () => {
console.log("Server is listening on port 3001");
});
Then the server will be locked down so that it can only ever run () => process.version
.
By leveraging this babel plugin, run-on-server
becomes feasible for use in production-facing libraries and applications.
Install the package babel-plugin-run-on-server
:
$ npm install --save-dev babel-plugin-run-on-server
# OR
$ yarn add --dev babel-plugin-run-on-server
Add it to your .babelrc
:
{
"plugins": ["run-on-server"]
}
By default, the plugin doesn't do anything. You need to enable each feature by passing options to the plugin in your .babelrc
:
{
"plugins": [
[
"run-on-server",
{
"evalRequire": {
"enabled": true
},
"idMappings": {
"enabled": true,
"outputPath": "./server/idMappings.js"
}
}
]
]
}
evalRequire.enabled
Whether to compile require
into eval("require")
within runOnServer
calls. Defaults to false
.
idMappings.enabled
Whether to compile id mappings and replace the code in runOnServer
calls with id mappings. Defaults to false
.
idMappings.outputPath
By default, the id mappings file will be written to run-on-server-id-mappings.js
in whatever directory you run babel in. You can configure it by setting the idMappings.outputPath
option.
The plugin never removes entries from the id mappings file, it only adds them. This means that your id mappings file will grow over time and contain entries for code you no longer have. To clean the entries up, remove the id mappings file and re-run babel. It's best practice to clear out all entries before releasing a new production-facing build.
If you are building content from a src
directory into a dist
directory, my recommendation is to output the id mappings file into dist
, and then clear the contents of dist
before running each build (as part of your build script).
The outputPath in .babelrc
is resolved relative to where you run babel
(process.cwd()
). This usually works, but if your id mappings file is getting put in the wrong place, you might want to use this workaround to give an absolute path to the plugin:
.babelrc
to have this content:{
"presets": ["./.babelrc.js"]
}
.babelrc.js
in the same directory as .babelrc
, and make it export a config object containing everything your .babelrc
had in it before:module.exports = {
plugins: [
[
"run-on-server",
{
idMappings: {
enabled: true,
outputPath: "./server/idMappings.js",
},
},
],
],
};
path
module and wrap your outputPath
like so:const path = require("path");
module.exports = {
plugins: [
[
"run-on-server",
{
idMappings: {
enabled: true,
outputPath: path.resolve(__dirname, "./server/idMappings.js"),
},
},
],
],
};
Note: If you are using Babel 7, you don't need to do the
"presets": ["./.babelrc.js"]
.babelrc
workaround, as.babelrc.js
will be loaded by babel without any additional config.
FAQs
Babel plugin that compiles id mappings for run-on-server.
The npm package babel-plugin-run-on-server receives a total of 0 weekly downloads. As such, babel-plugin-run-on-server popularity was classified as not popular.
We found that babel-plugin-run-on-server demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.