how to restrict global variables or functions in node js - node.js

how to restrict global variables and functions in node js?
like: require method
i want to limit use of require method.
i don't want any node app to access "fs" in my node framework which i build on top of express, they can only require modules which i want them to.
and also i want to restrict access to process, global scope .
suppose when i load any js library for any app
like:
var x=require('app1.js');
in my framework
then i want to make sure this app1.js cannot access filesystem using require("fs")
app1.js
var x=require("fs");
exports.hello=function(){
console.log(typeof x.readSync);
}
i want this console to print undefined;
and in this sample
var x=require("helper.js");
exports.hello=function(){
console.log(typeof x.hello);
}
i want this console to print function;
thanks in advance

I'd create a new function that will act like require.
requireSafe = function(param){
if(!isAllowedLogic(param)) return null;
else return require(param);
}
And when someone submits code, you append var require; at the top to prevent them to use the regular require. Or you search in their submission and only approve it if it doesn't contain require nor eval.

Why would you want to do that?
It is not possible to change the way require works, as it is a build-in node.js function.

Try this library,
for a bit of detail of how its security works, from the README :
A Node.js subprocess is created by the Jailed library;
the subprocess (down)loads the file containing an untrusted code as a
string (or, in case of DynamicPlugin, simply uses the provided string
with code)
then "use strict"; is appended to the head of that code (in order to
prevent breaking the sandbox using arguments.callee.caller);
finally the code is executed using vm.runInNewContext() method, where
the provided sandbox only exposes some basic methods like
setTimeout(), and the application object for messaging with the
application site.

Related

What library can I use to generate random mock data based on Open API spec inside a node application?

I am looking for a library which would generate a mock data based on openapi spec (client side only). So the idea is not to have a separate local server, as it's done in openapi-mock-express-middleware, but rather have data to be generated on fly inside front-end application.
Something like this I guess:
const spec = someOpenApiMockGenerator('path/to/spec-file.yaml');
const anEndPointData = spec.mock("someEndpointName");
console.log(anEndPointData);
// expected output is same as in expressjs middlware mentioned above.

Exposing a node.js variable to the client

I would like to expose a node.js server variable to the client. I am trying to get express-expose to work.
I am not sure how to initialise and use that library.
In the express-expose guide the usage doesn't make sense
var express = require('express');
var expose = require('express-expose');
app = expose(app);
app.expose(...);
how can I use app in 'expose(app') before it was initialised ?
I used
const app = expose(express());
app.expose('var some = "variable";','head');
but that doesn't seem to work either.
Can anyone supply me please with an example that initialises the express-expose library and exports var 'some' to the client ?
(By exposing to the client I mean it will be available to all my javascript files as a global variable so that I could do 'console.log(some);' and it would print its value)
Using Pug
Since you're using Express with Pug, you can just call the res.render function and give it the variable you want. Here's how to do that.
Let's say you have a template called index.pug, it may look like this:
html
head
title= title
body
h1= message
On your server, the code responsible for the rendering should look like this. In this case we're passing someVariable to the view that needs to be rendered.
const someVariable = 'hello world!';
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: someVariable })
})
A note on express-expose
The express-expose library is not maintained and hasn't been updated in 5 years. My advice would be to just render your variable as described previously or just use AJAX requests.
A note on using a global variable
I am using the 'pug' view engine. It is passed to the view but I want
it as a global javascript variable.
A better idea is to use Template Inheritence to create "generic layouts" and extend them as needed. Sharing a global variable with file you're rendering will not update it magically on the front-end if you're changing it in the back-end. Even if the variable is global.
If you want to reflect "real-time changes" you should look into Socket.io.
This seems like a code smell... But regardless, there are cleaner ways to do it.
If you want to expose a data object, that is, an object just containing keys and values, you could embed it in the rendered webpage, make it available via some API endpoint that the client can acquire via an AJAX request, or expose a raw Javascript file that can be included via <script> (or I guess script(...) in pug).
If you want to expose a more complex Javascript object, such as a class or an object with function definitions, you could expose the Javascript file and include it via script(...).
However, you should be very careful exposing a file used by the server. If there are any vulnerabilities, they are now public. If there are any hard-coded passwords (which shouldn't be in code anyway), they are now public. Anything in this file is now public, so if you do indeed want to do this, be very careful about what code gets into this now client-side file.
If you need more details on how this could work, please comment :)
Edit: Also be aware that using the embedded and include methods would not allow the variable to be updated on-the-fly. If you need the client to track any changes to the data as it changes on the server, you will want to use AJAX. This is the best method, in my opinion. It offers you the most flexibility.
Another edit: Judging by the issues on the express-expose project, it seems not well supported and maybe has security issues. For now, I would avoid it. Maybe at a later time, it will be helpful and secure.
If you want to expose a variable value to the client from server , that never changes or updates, you can simply add a hidden input field in your template and add the value of it
In your EJS template file this would look like
<% if (data) { %>
<input type="hidden" value="<%= data %>" id="myGlobal"/>
<% } %>
you must pass the data value in your res.render('template',{data:"hello"}) function to the template.
You can access this variable value from client using a simple document.getElementById("myGlobal").Again don't pass any sensitive information in hidden fields.
If you want to pass sensitive information , implement an endpoint in your server with authentication and call the endpoint from client via an ajax call .This is also a best approach to update the value of the variable from client side.

React isomorphic inconvenience

I'm building isomorphic app using Node.js and ReactJS.
I've met a situation when inside some isomorphic React component (rendered both on client and server sides) I need to include only client-side dependency (some notifications library for example).
What is the best way to have it worked (compiled) both on server/client sides?
P.S: I have few thoughts about possible workarounds something like checking for browser env variables (ex. some typeof window !== 'undefined') etc. but I'm not sure it's a good way to go.
Use the lifecycle method componentDidMount which is not invoked on the server instead of checking if window is undefined.
The "downside" is if your client side dependency enhances an element for example or changes any property of it, it'll get the default property first since it was rendered server side and when componentDidMount runs it'll get changed causing a "blink".
If you are using browserify I often use process.browser which is only true in browserified code.
If you wanted to get fancy and remove server code from the browser instead there is also isbrowser which will do just that.
Another way (webpack or browserify) is to take advantage of the browser field in the package.json. You can make it so that the server requires a noop file and the browser requires a file the exposes the client side api.
I have defined variable in webpack configuration file called process.env.WEBPACK and in my code when i need something like bottstrap js or something else i just write
if(process.env.WEBPACK){
//awesome lib included or scss or whatever
}

Using node.js libraries on front-end

How can I use the 'request' node.js module on the front-end?
normally I would retrieve it like so:
var request = require('request');
but this is not possible on the front-end since require is not recognized.
What is the best way to solve this?
To use node modules in the browser you can use a library called Browserify . This allows you to work with the common module pattern as well as the you can use this package browser-request to get the features of request module

Redefining `require` on the client (but not on server) for code-sharing

I want to share a piece of coffeescript code between the server and the client on Express.
I linked the file from the server directory into the /public directory, so it can be loaded by the client.
It does have external dependencies, which I resolve statically for the client. To remove the error messages when the client tries to call require, I thought a simple conditional declaration would do.
console.log require
unless require?
require = (what) ->
console.info "this is the client, you asked me to load #{what}"
return {}
However, when run on the server, undefined will be printed and require will be overridden. The same happens for embedded Javascript:
`if( typeof require == "undefined" )
var require = function(what) {
console.info( "this is the client, you asked me to load "+what );
return {};
}
`
If I only run:
console.log require
on the server, it prints an object structure, as expected.
It seems that require is injected after at least the conditional has been evaluated and executed.
How can I override require safely, or what other paradigm might I use for sharing code between client and server?
I recommend using browserify for sharing code between the client and server. It allows you to write your javascript as you would for the server following the common js pattern, but provides a mechanism to build your module for client-side where require() works in the browser.
CoffeeScript is supported with browserify via a transform process. Coffeeify is one implementation of a transform implementation for CoffeeScript.

Resources