How to sanitize the req.log.error in node js - javascript

I am trying to fix the Checkmarx scanning tool reported issue, I tried to sanitized the err as well as req in the below route module.
However, it still complains about the same error.
index.js
const express = require('express')
const router = express.Router()
const fs = require('fs')
const config = require('config')
var _require = require('jsdom'),
JSDOM = _require.JSDOM;
var window = new JSDOM('').window;
var DOMPurify = createDOMPurify(window);
function sanitizeError(value){
return DOMPurify.sanitize(value);
}
function sanitizeObject(obj) {
var sanitizedObject = {};
Object.keys(obj).forEach(function (key) {
sanitizedObject[key] = sanitizeValue(obj[key]);
});
return sanitizedObject;
};
//error handler route
router.use('/error',(err, req, res, next) => {
//sanitizeObject(req)
req.logger.error('uncaught error page', sanitizeError(err))
res.redirect('/toanotehrerror page')
})
module.exports = router
Checkmarx Error:
Reflected_XSS error. It is referring to the line req.logger.error in the above module
The application's router.use embeds untrusted data in the generated output with error, at line x of \routes\index.js. This untrusted data is embedded straight into the output without proper sanitization or encoding, enabling an attacker to inject malicious code into the output.
The attacker would be able to alter the returned web page by simply providing modified data in the user input error, which is read by the router.use method at line x of \routes\index.js. This input then flows through the code straight to the output web page, without sanitization.
This can enable a Reflected Cross-Site Scripting (XSS) attack.

Checkmarx does not have DOMPurify in the list of its recognized sanitizers. What it does recognize are the ESAPI library, xss-filters and htmlescape packages
https://www.npmjs.com/package/xss-filters
https://www.npmjs.com/package/node-esapi
https://www.npmjs.com/package/htmlescape
While technically your code can prevent XSS, I would rewrite it using using any of the packages above. For instance if we are to use xss-filters:
var xssFilters = require('xss-filters');
function sanitizeError(value){
return xssFilters.inHTMLData(value);
}

Related

Nuxt FingerprintJS Module Server and Client solution?

I using fingerprintJS in NuxtJS+Firebase Projects VuexStore.
When i call that function in client side can get Visitor ID. But i cant get if i use in server side like a nuxtServerInit.
const fpPromise = FingerprintJS.load();
const abc = (async() => {
const fp = await fpPromise
const result = await fp.get()
const visitorId = result.visitorId
return visitorId;
})()
abc.then(
function(value) {
state.visitorId = value
},
function(error) {
return error
}
)
is there a solution to this?
From the NuxtJS documentation (about server rendering):
Because you are in a Node.js environment you have access to Node.js
objects such as req and res. You do not have access to the window or
document objects as they belong to the browser environment. You can
however use window or document by using the beforeMount or mounted
hooks.
FingerprintJS depends heavily (example here) on the browser (hence browser fingerprinting). That means it needs e.g. window object which is not available in the server-side rendering context.
I'm not very experienced with NuxtJS, however, according to the documentation, you should add your fingerprinting code to the .vue file like
if (process.client) {
require('external_library')
}
Good luck!

Use Actions SDK for Google Assistant

I am trying to use Actions SDK in my own Server, the actions that I made are showed in Google Assistant, but it's not working, the assistant just closes without showing any errors. This is my code:
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
var exps = express();
exps.use(bodyParser.json());
const {actionssdk} = require('actions-on-google');
const app = actionssdk({debug: true});
const asyncTask = () => new Promise(
resolve => setTimeout(resolve, 1000)
);
exps.post('/', function(request, response) {
app.intent('actions.intent.MAIN', (conv) => {
return asyncTask()
.then(() => conv.ask('Hi, this is a test!'));
});
});
express().use(bodyParser.json(), app).listen(3000);
Request and Debug tabs
Both Errors and Response are empty.
I think the issue is that you are creating two different express objects. One gets mounted on the '/' path, but isn't setup to listen on any port. The other listens on a port, but doesn't have any paths setup for it to handle.
Changing your listener line to
exps.use(bodyParser.json(), app).listen(3000);
will make it so the express object where you've setup the '/' path will also be the one listening on the port.
It also appears that your webhook is listening at the '/' path, but you've specified the webhook in your actions.json file as using the '/node/' path. (It is a little difficult to read the screen shot - which is why we request you post the text and not a screen shot.) If you either change your webhook to listen to '/node/' or change the actions.json file to use '/', it should work.
Looking at the documentation (https://developers.google.com/actions/assistant/responses) suggests that you are attempting to call conv.ask() incorrectly. I would imagine you'd need something like this:
conv.ask(new SimpleResponse({speech: 'Hi, this is a test!', text: 'Hi, this is a test!'}));

Running untrusted javascript code on server in sandbox

I can't seem to figure out how to set up a node sandbox, which can run untrusted code safely, and allows a user to interact with the program through api calls (sys in and out). I'm trying to set up a console in the browser for users to run their own code from the server.
Are there any node packages that support this, or do I need to write my own node VM? Thanks.
Edit: I want a user to be able to write readline() and have the program wait at the breakpoint for data to be transferred in. similarly console.log()'s output should redirect to the response of the input api call.
You can use the vm2 module and run almost any code that comes with user input in a secure way.
You can even define whether the user-supplied code will have access to require native Node modules or other modules via relative path or even define whether a code coming from the user input can make an external call.
You can envelop and execute this "untrusted" code in a try/catch to observe catastrophic failures or even set a timeout so that this run does not overwhelm.
quick example
const {VM} = require('vm2');
const vm = new VM();
vm.run(`process.exit()`); // TypeError: process.exit is not a function
using "request" module "bultin" for access external resource
const {NodeVM} = require('vm2');
const vm = new NodeVM({
require: {
external: true // allow all modules or use Array for one e.g: ['request']
}
});
vm.run(`
var request = require('request');
request('http://www.google.com', function (error, response, body) {
console.error(error);
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
`, 'vm.js');
By default the entry is compiled into javascript but you can pass a function with your custom compiler.

How to inject module from different app in Node.js

I've two node apps/services that are running together,
1. main app
2. second app
The main app is responsible to show all the data from diffrent apps at the end. Now I put some code of the second app in the main app and now its working, but I want it to be decoupled. I mean that the code of the secnod app will not be in the main app (by somehow to inject it on runtime )
like the second service is registered to the main app in inject the code of it.
the code of it is just two modules ,is it possible to do it in nodejs ?
const Socket = require('socket.io-client');
const client = require("./config.json");
module.exports = (serviceRegistry, wsSocket) =>{
var ws = null;
var consumer = () => {
var registration = serviceRegistry.get("tweets");
console.log("Service: " + registration);
//Check if service is online
if (registration === null) {
if (ws != null) {
ws.close();
ws = null;
console.log("Closed websocket");
}
return
}
var clientName = `ws://localhost:${registration.port}/`
if (client.hosted) {
clientName = `ws://${client.client}/`;
}
//Create a websocket to communicate with the client
if (ws == null) {
console.log("Created");
ws = Socket(clientName, {
reconnect: false
});
ws.on('connect', () => {
console.log("second service is connected");
});
ws.on('tweet', function (data) {
wsSocket.emit('tweet', data);
});
ws.on('disconnect', () => {
console.log("Disconnected from blog-twitter")
});
ws.on('error', (err) => {
console.log("Error connecting socket: " + err);
});
}
}
//Check service availability
setInterval(consumer, 20 * 1000);
}
In the main module I put this code and I want to decouple it by inject it somehow on runtime ? example will be very helpful ...
You will have to use vm module to achieve this. More technical info here https://nodejs.org/api/vm.html. Let me explain how you can use this:
You can use the API vm.script to create compiled js code from the code which you want run later. See the description from official documentation
Creating a new vm.Script object compiles code but does not run it. The
compiled vm.Script can be run later multiple times. It is important to
note that the code is not bound to any global object; rather, it is
bound before each run, just for that run.
Now when you want to insert or run this code, you can use script.runInContext API.
Another good example from their official documentation:
'use strict';
const vm = require('vm');
let code =
`(function(require) {
const http = require('http');
http.createServer( (request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
})`;
vm.runInThisContext(code)(require);
Another example of using js file directly:
var app = fs.readFileSync(__dirname + '/' + 'app.js');
vm.runInThisContext(app);
You can use this approach for the conditional code which you want to insert.
You can create a package from one of your apps and then reference the package in the other app.
https://docs.npmjs.com/getting-started/creating-node-modules
There are several ways to decouple two applications. One easy way is with pub/sub pattern (in case you don't need a response).
(Now if you have an application that is very couple, it will be very difficult to decouple it unless you do some refactoring.)
zeromq offers a very good implementation of pub/sub and is very fast.
e.g.
import zmq from "zmq";
socket.connect('tcp://127.0.0.1:5545');
socket.subscribe('sendConfirmation');
socket.on('message', function (topic, message) {
// you can get the data from message.
// something like:
const msg = message.toString('ascii');
const data = JSON.parse(msg);
// do some actions.
// .....
});
//don't forget to close the socket.
process.on('SIGINT', () => {
debug("... closing the socket ....");
socket.close();
process.exit();
});
//-----------------------------------------
import zmq from "zmq";
socket.bind('tcp://127.0.0.1:5545');
socket.send(['sendConfirmation', someData]);
process.on('SIGINT', function() {
socket.close();
});
This way you could have two different containers (docker) for your modules, just be sure to open the corresponding port.
What i don't understand, is why you inject wsSocket and also you create a new Socket. Probably what I would do is just to send the
socket id, and then just use it like:
const _socketId = "/#" + data.socketId;
io.sockets.connected[socketId].send("some message");
You could also use another solution like kafka instead of zmq, just consider that is slower but it will keep the logs.
Hope this can get you an idea of how to solve your problem.
You can use npm link feature.
The linking process consists of two steps:
Declaring a module as a global link by running npm link in the module’s root folder
Installing the linked modules in your target module(app) by running npm link in the target folder
This works pretty well unless one of your local modules depends on another local module. In this case, linking fails because it cannot find the dependent module. In order to solve this issue, one needs to link the dependent module to the parent module and then install the parent into the app.
https://docs.npmjs.com/cli/link

How to determine function parameters in Javascript?

I am a Java developer learning Javascript (Node.js).
This is the first piece of code I tried running :
var sys = require("sys"),
my_http = require("http");
my_http.createServer(function(request,response){
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8080);
IF there was no documentation, how would have I known that createServer takes a function which takes request and response as parameter ? I am asking this because I want to prepare myself for all the undocumented code I will start facing soon. Here is the source for createServer function :
function createServer(options) {
var bunyan = require('./bunyan_helper');
var InternalError = require('./errors').InternalError;
var Router = require('./router');
var Server = require('./server');
var opts = shallowCopy(options || {});
var server;
opts.name = opts.name || 'restify';
opts.log = opts.log || bunyan.createLogger(opts.name);
opts.router = opts.router || new Router(opts);
server = new Server(opts);
server.on('uncaughtException', function (req, res, route, e) {
if (this.listeners('uncaughtException').length > 1 ||
res._headerSent) {
return (false);
}
res.send(new InternalError(e, e.message || 'unexpected error'));
return (true);
});
return (server);
}
I understand Javascript is a dynamically typed language, but wondering how do people debug or understand each other's code without knowing types.
Well the nice thing about javascript is it's interpreted meaning you always have access to the actual source code itself. For node, you can look in node_modules/blah to read the source, but the vast majority of what is on npm is also open source on github and you can read the source there, too.
In the browser the developer tools has an auto-format button if you encounter minified code, but in node usually you don't need that as code is published unminified.
That said, some things are documented well, sometimes documentation is wrong or out of date, and sometimes reading the source code is neither quick nor straightforward. But if something is really problematic for you and is both undocumented and hard to read, you can and should switch to something else on npm because "ain't nobody got time for that".
you must be very familiar with the api when using JavaScript.for example, document.getElementById(id). There is no hint in what the id is in the code,but it is well understood.

Categories