Limit scope in Node JS - node.js

I want to let users create custom plugins for one of my apps Programmed in Node JS.
I thought of using some method similar than dynamic libraries, but using Node Modules. The problem is don't want the users to be able to do harmful things like making inappropriate use of the network or accessing the file system.
Is there any way you can limit the NODE Native API for an specific module?

I doubt there is any real defense if you grant someone code execution level access to your server. At the best, you will be in an arms race trying to plug holes as they are discovered.
If you want to allow customers to expand the functionality of your product, you should probably just develop an API for the customer products to interface with. This way, there is a limited attack surface area and you can control all the access points to your application.

One of the solutions would be to recompile node without unwanted API calls.
Another way to achieve this is to monkey patch unwanted calls and unwanted modules after the process starts.
> var fs = require("fs");
> fs.openSync("/etc/passwd", 0);
12
> fs.openSync = function(){}
> var fs = require("fs");
> fs.openSync("/etc/passwd", 0);
'Not allowed'
You have to also monkey patch in the same way require.reload and think about how else this can be circumvented.

I realice how to do this: the trick is using the with operator.
For example you can limit the access to some APIs in a browser using:
with({windows: null, document: null: XMLHttpRequest: null}){
console.log(document)
}

Related

Node.js express app architecture with testing

Creating new project with auto-testing feature.
It uses basic express.
The question is how to orginize the code in order to be able to test it properly. (with mocha)
Almost every controller needs to have access to the database in order to fetch some data to proceed. But while testing - reaching the actual database is unwanted.
There are two ways as I see:
Stubbing a function, which intends to read/write from/to database.
Building two separate controller builders, one of each will be used to reach it from the endpoints, another one from tests.
just like that:
let myController = new TargetController(AuthService, DatabaseService...);
myController.targetMethod()
let myTestController = new TargetController(FakeAuthService, FakeDatabaseService...);
myTestController.targetMethod() // This method will use fake services which doesnt have any remote connection functionality
Every property passed will be set to a private variable inside the constructor of the controller. And by aiming to this private variable we could not care about what type of call it is. Test or Production one.
Is that a good approach of should it be remade?
Alright, It's considered to be a good practice as it is actually a dependency injection pattern

Feathers JS nested Routing or creating alternate services

The project I'm working on uses the feathers JS framework server side. Many of the services have hooks (or middleware) that make other calls and attach data before sending back to the client. If I have a new feature that needs to query a database but for a only few specific things I'm thinking I don't want to use the already built out "find" method for this database query as that "find" method has many other unneeded hooks and calls to other databases to get data I do not need for this new query on my feature.
My two solutions so far:
I could use the standard "find" query and just write if statements in all hooks that check for a specific string parameter that can be passed in on client side so these hooks are deactivated on this specific call but that seems tedious especially if I find this need for several other different services that have already been built out.
I initialize a second service below my main service so if my main service is:
app.use('/comments', new JHService(options));
right underneath I write:
app.use('/comments/allParticipants', new JHService(options));
And then attach a whole new set of hooks for that service. Basically it's a whole new service with the only relation to the origin in that the first part of it's name is 'comments' Since I'm new to feathers I'm not sure if that is a performant or optimal solution.
Is there a better solution then those options? or is option 1 or option 2 the most correct way to solve my current issue?
You can always wrap the population hooks into a conditional hook:
const hooks = require('feathers-hooks-common');
app.service('myservice').after({
create: hooks.iff(hook => hook.params.populate !== false, populateEntries)
});
Now population will only run if params.populate is not false.

Mocking Repository but Then Swapping Out for Real Implementation in Node.js

I'm building a Repository layer with higher level API for my abstractions above to make calls to the database persistence. But since JavaScript doesn't have the concept of Interfaces like a language such as C# or Java does, how do you swap out the mock for the real implementation?
I prefer creating custom mocks, node repository modules with data persitence high level methods in them vs. Sinon.js or something like that.
If I'm creating node modules, then how? I could send in a mock representation of the repository where I mock out what the repository methods are doing but then the actual node modules using those repository modules would need to use the real repository implementation that calls the real database. How is this done in Node? I want to just inject via a property, I don't want some gigantic injection IoC framework either.
Since there's no concept of an interface then wtf do you do in Node/JS? I have to create a data layer below the repository (whether it be a custom set of modules making real query calls to Postgres or whether I'm using Mongoose or whatever it may be, I need a DL set of modules that the repository calls for tis real DB calls under the hood).
And lets say I do choose to use some framework like Sinon.js, what's the common interface for the module you're mocking that can be shared by the mocking framework and the real module?
There's more than one way to do it. If you come from a different background it may take some getting used to Node.
You can do this:
module.exports = function(db) {
this.db = db;
this.myQuery = function(n, cb) {
this.db.query(n, cb);
}
}
Then in config.js
var exports.db = require('./mydb');
Then
var config = require('./config.js');
var db = require('./db')(config.db);
There are lots of variations possible. You could do a dynamic require somewhere based on a string or something. Or use classes or init functions. Most are going to probably end up being similar.
The proxyrequire module could be helpful. So can Sinon.js.
Since there really isn't type checking people generally are verifying that with their tests at runtime. If you are really doing TDD it might not make a huge difference.

Is it possible to replace or alias core modules in Node.js?

I'm currently working on a project where one of the core Node.js modules (dns) does not behave the way I need it to. I've found a module that seems like it would work as a replacement: https://github.com/tjfontaine/node-dns. However, the code using the DNS module is several layers down from the application code I've written. I'm using the Request module (https://github.com/mikeal/request) which makes HTTP requests and uses several core modules to do so. The Request module does not seem to be using the DNS module directly, but I'm assuming one of those core modules is calling the DNS module.
Is there a way I can tell Node to use https://github.com/tjfontaine/node-dns whenever require('dns') is called?
Yes and you should not,
require.cache is a dangerous thing, extremely. It can cause memory leaks if you do not know what you are doing and cache mismatch which is potentially worse. Most requests to change core modules can also result in unintentional side effects (such as discoverability failures with DNS).
You can create a user-space require with something like : https://github.com/bmeck/node-module-system ; however, this faces the same dangers but is not directly tied to core.
My suggestion would be to wrap your require('dns').resolve with require('async').memoize, but be aware that DNS discoverability may fall over.
For better or worse, I've implemented module white lists before doing something as demonstrated below. In your case, it ought to be possible to explicitly check for dns module name and delegate everything else to original require(). However, this implementation assumes that you have full control of when and how your own code is being executed.
var _require = constructMyOwnRequire(/*intercept 'dns' and require something else*/);
var sandbox = Object.freeze({
/* directly import all other globals like setTimeout, setInterval, etc.. */
require : Object.freeze(_require)
});
try {
vm.runInContext(YOUR_SCRIPT, Object.freeze(vm.createContext(sandbox)));
} catch (exception) {
/* stuff */
}
Not really.
require is a core var which is local to each module, so you can't stub it, because Node will give the untouched require var to the loaded module.
You could run those things using the vm module. However, you would have to write too much code to do a "simple workaround" (give all needed variables to the request module, stub the needed ones to work properly, etc, etc...).

Node.js: Connect-Auth VS. EveryAuth

Can anyone give a good comparison between:
https://github.com/ciaranj/connect-auth
and https://github.com/bnoguchi/everyauth
Which seem to be the only options for express/connect
I'm the author of everyauth.
I wrote everyauth because I found using connect-auth lacking in terms of:
Easy and powerful configuration
To get particular, one area where it was lacking in terms of configurability was setting facebook's "scope" security settings dynamically.
Good debugging support
I found connect-auth not-so-straightforward to debug in terms of pinpointing the part of the auth process was failing. This is mostly due to the way that connect-auth sets up its nested callbacks.
With everyauth, I tried to create a system that solved the issues I ran into with connect-auth.
On configuration - every everyauth auth module is defined as a series of steps and configurable parameters. As a result, you have surgery-like precision over what parameters (e.g., hostname, callback url, etc.) or steps (e.g., getAccessToken, addToSession) you want altered. With connect-auth, if you want to change one thing besides the few built in configurable parameters each auth strategy provides, you have to re-write the entire this.authenticate function that defines the logic for all of that strategy. In other words, it has less precision of configurability than everyauth. In other cases, you cannot use connect-auth, as is -- for example, achieving dynamic facebook "scope" configurability - i.e., asking users for more facebook permissions progressively as they get to portions of your app that require more permissions.
In addition to configurable steps and parameters, you can also take advantage of everyauth's auth module inheritance. All modules inherit prototypically from the everymodule auth module. All OAuth2-based modules inherit from the oauth2 module. Let's say you want all oauth2 modules to behave differently. All you need to do is modify the oauth2 auth module, and all oauth2-based modules will inherit that new behavior from it.
On debugging - everyauth, in my opinion, has better debugging visibility because of the very fact that it segments each module explicitly into the steps of which it is composed. By setting
everyauth.debug = true;
you get output of what steps in the authentication process have completed and which ones have failed. You also have granular control over how long each step in each auth strategy has before it times out.
On extensibility - I designed everyauth to maximize code re-use. As mentioned before, all modules inherit prototypically from the everymodule auth module. This means that you can achieve very modular systems while at the same time having fine grained control in terms of over-riding a specific step from an ancestor module. To see how easy it is to extend everyauth with your own auth module, just take a look at any of the specific auth modules in everyauth's source.
On readability - I find everyauth source easier to read in terms of what is going on. With connect-auth, I found myself jumping around the several files to understand under what contexts (i.e., during what steps, in everyauth parlance) each nested callback configured by a strategy was running. With everyauth, you know exactly what piece of logic is associated with which context (aka step). For instance, here is the code describing what happens when an oauth2 provider redirects back to your service:
.get('callbackPath',
'the callback path that the 3rd party OAuth provider redirects to after an OAuth authorization result - e.g., "/auth/facebook/callback"')
.step('getCode')
.description('retrieves a verifier code from the url query')
.accepts('req res')
.promises('code')
.canBreakTo('authCallbackErrorSteps')
.step('getAccessToken')
.accepts('code')
.promises('accessToken extra')
.step('fetchOAuthUser')
.accepts('accessToken')
.promises('oauthUser')
.step('getSession')
.accepts('req')
.promises('session')
.step('findOrCreateUser')
.accepts('session accessToken extra oauthUser')
.promises('user')
.step('compile')
.accepts('accessToken extra oauthUser user')
.promises('auth')
.step('addToSession')
.accepts('session auth')
.promises(null)
.step('sendResponse')
.accepts('res')
.promises(null)
Without needing to explain how this works, its pretty straightforward to see what an oauth2 strategy does. Want to know what getCode does? The source again is very straightforward:
.getCode( function (req, res) {
var parsedUrl = url.parse(req.url, true);
if (this._authCallbackDidErr(req)) {
return this.breakTo('authCallbackErrorSteps', req, res);
}
return parsedUrl.query && parsedUrl.query.code;
})
Compare this all to connect-auth's facebook code, which for me at least, took more time than I thought it should have to figure out what is getting executed when. This is mostly because of the way in which the code is spread across files and because of the use of a single authenticate method and nested callbacks to define authentication logic (everyauth uses promises to break down the logic into easily digestible steps):
that.authenticate= function(request, response, callback) {
//todo: makw the call timeout ....
var parsedUrl= url.parse(request.url, true);
var self= this;
if( parsedUrl.query && parsedUrl.query.code ) {
my._oAuth.getOAuthAccessToken(parsedUrl.query && parsedUrl.query.code ,
{redirect_uri: my._redirectUri}, function( error, access_token, refresh_token ){
if( error ) callback(error)
else {
request.session["access_token"]= access_token;
if( refresh_token ) request.session["refresh_token"]= refresh_token;
my._oAuth.getProtectedResource("https://graph.facebook.com/me", request.session["access_token"], function (error, data, response) {
if( error ) {
self.fail(callback);
}else {
self.success(JSON.parse(data), callback)
}
})
}
});
}
else {
request.session['facebook_redirect_url']= request.url;
var redirectUrl= my._oAuth.getAuthorizeUrl({redirect_uri : my._redirectUri, scope: my.scope })
self.redirect(response, redirectUrl, callback);
}
}
A few other differences:
everyauth supports traditional password-based authentication. connect-auth, as of this writing, does not.
The foursquare and google support in connect-auth is based on the older OAuth1.a spec. everyauth's foursquare and google modules are based on their implementations of the newer OAuth2 spec.
OpenId support in everyauth.
everyauth's documentation is much more comprehensive than connect-auth's.
Finally, to comment on Nathan's answer which was unsure about everyauth support for multiple providers at the same time, everyauth does support multiple, concurrent providers. The README on everyauth's github page provides instructions about how to use everyauth to achieve this.
To conclude, I think choice of libraries depends on the developer. I, and others, find everyauth more powerful from their point of view. As Nathan's answer illustrates, yet others find connect-auth more tuned in to their preferences. Whatever your choice, I hope this write-up about why I wrote everyauth helps you in your decision.
Both libraries are pretty close in feature sets, especially in terms of supported providers. connect-auth provides support out-of-the-box to make your own oAuth providers, so that could well help you out if you’re going to need that sort of thing.
The main thing I’ve noted between the two is that I find connect-auth much cleaner with the way it creates and accepts the middleware; you only have to look at the amount of pre-configuration required for the middleware in everyauth to see that it's going to get messy.
Another thing that isn't clear is whether everyauth supports multiple providers at the same time; with connect-auth, it seems possible/more straightforward, though I’ve yet to try this myself.
Thought I'd mention that there is now a new player in the town called PassportJS which features a lot of the same benefits as everyauth however authentication providers are provided by npm modules - so optin in rather than include everything.
I spent a morning playing with everyauth and mongoose-auth to find the examples were broke and they were dead projects. Here are the commit histories:
https:// github.com/jaredhanson/passport/commits/master - June 5th (it's June 18th)
https:// github.com/ciaranj/connect-auth/commits/master - April 18th (2 months ago)
https:// github.com/bnoguchi/mongoose-auth/commits/master - Feb 2012
Here's a google Trends of everyauth, connect-auth, and passportjs
http://www.google.com/trends/explore?q=passportjs%2C+connect-auth%2C+everyauth#q=passportjs%2C%20connect-auth%2C%20everyauth&cmpt=q
My experience with each:
everyauth is far more configurable. For example, I wish to handle my own sessions. With everyauth, with its modularity and introspection, a straightforward task. On the other hand have found everyauth filled with minor bugs and incomplete and/or incorrect documentation. For me, each authentication strategy has required its own understanding and troubleshooting.
passport might be a good bet if you're doing everything "by the book". But any deviation could make life very difficult very quickly, making it, for me, a non-starter.

Resources