Socket.io sanitize incoming data (xss) - javascript

im using socket.io in expressjs 3. And i want to sanitize incoming messages with express-validator. I have this code:
var expressValidator = require('express-validator')
, sanitize = require('express-validator').sanitize;
socket.on('chat', function (data) {
io.sockets.in('test').emit('chat', {
user: sh.session.user,
message: data.message,
time: new Date()
});
});
how do i use sanitize(data.message).xss? Because this does not work.

In this case you want to use validator instead of express-validator. First install it thru npm:
npm install validator
Then use it pretty much the same way:
var sanitize = require('validator').sanitize;
// later on
message = sanitize(data.message).xss()
The reason for this is because express-validator is used for when you are dealing with an HTTP request that went thru expressjs. In the case of Websockets, you are not going thru expressjs, but rather just listening on the same port as it. So express-validator is not actually "present" in the context of your Websocket's data event.

Related

How can I debug Stanza.js Authentication?

I'm currently attempting to setup an XMPP client using Stanza.js
https://github.com/legastero/stanza
I have a working server that accepts connections from a Gajim client, however when attempting to connect using Stanza.js client.connect method, the server opens up a websocket connection, but no events for authentication, or session started ever fire.
The server logs do not show any plaintext password authentication attempts.
How can I actually see any of the stanza logs to debug this issue?
import * as XMPP from 'stanza';
const config = { credentials: {jid: '[jid]', password: '[password]'}, transports: {websocket: '[socketurl]', bosh: false} };
const client = XMPP.createClient(config)
client.on('raw:*', (data) => {
console.log('data', data)
})
client.connect();
onconnect event does fire, but this is the only event that fires.
Is there a way to manually trigger authentication that isn't expressed in the documentation?
The raw event handler should be able to give you the logging you want - but in your code sample, you are invoking it incorrectly. Try the following.
client.on('raw:*', (direction, data) => {
console.log(direction, data)
})
For reference, the docs state that the callback for the raw data event handler is
(direction: incoming | outgoing, data: string) => void
So the data that you are looking for is in the second argument, but your callback only has one argument (just the direction string "incoming" or "outgoing", although you have named the argument "data").
Once you fix the logging I expect you will see the stream immediately terminates with a stream error. Your config is incorrect. The jid and password should be top level fields. Review the stanza sample code. For the options to createClient - there is no credentials object. Try the following:
const config = { jid: '[jid]', password: '[password]', transports: {websocket: '[socketurl]', bosh: false} };
Since your username and password are hidden behind an incorrect credentials object, stanza.io does not see them and you are effectively trying to connect with no username and password so no authentication is even attempted.
This issue happened to be caused by a configuration problem.
The jabber server was using plain authentication.
Adding an additional line to the client definition file helped.
Also adding
client.on('*', console.log)
offered more complete server logs.
client.sasl.disable('X-OAUTH2')
How can I actually see any of the stanza logs to debug this issue?
If the connection is not encrypted, you can sniff the XMPP traffic with tools like
sudo tcpflow -i lo -Cg port 5222
You can force ejabberd to not allow encryption, so your clients don't use that, and you can read the network traffic.
Alternatively, in ejabbed.yml you can set this, but probably it will generate a lot of log messages:
loglevel: debug

How to make a turn server on node.js for peer connection

I'm using a node.js server to send iceCandidates and connect two computers by peer connection (javascript). I want to use TURN-server as iceServer, but I don't have one, so I want to make TURN-server on my server. How is it possible?
you can use node-turn to write your own server or using it as a standalone server.
var Turn = require('node-turn');
var server = new Turn({
// set options
authMech: 'long-term',
credentials: {
username: "password"
}
});
server.start();

redis php and javascript connection

I am making a web chat client where I use redis for pub/sub. I am having trouble with the subscribe part. I am able to publish but I am not sure how to subscribe. I have a php script written to subscribe (it work when I run php) it listens and echos the message. I want to be able to get that message in javascript. How do I call the php file and listen? I tried ajax in jquery and listening for the echo in the success function but it does not seem to work. I am new to this any advice is helpful
EDIT: Here is the javascript
$.ajax({
url:"http://localhost/redisphp.php",
type: GET,
success: function(response){ ...},
...
Here is the redis. I modeled after this link https://xmeng.wordpress.com/2011/11/14/pubsub-in-redis-using-php/
<?php
function f($redis, $chan, $msg) {
switch($chan) {
case 'chan-1':
echo $msg;
}
}
ini_set('default_socket_timeout', -1);
$redis = new Redis();
$redis->pconnect('128.0.0.0',6378);
$redis->subscribe(array('chan-1'), 'f');
print "\n";
?>
I have a php script written to subscribe (it work when I run php) it listens and echos the message. I want to be able to get that message in javascript.
It sounds like you would need to create an Express API that would connect to your Redis server.
Please keep in mind I am going on very limited information that you have provided. So first thing with your Express API is to create your package.json file like so:
{
"dependencies": {
"express": "4.16.3",
"redis": "2.8.0",
"nodemon": "1.18.3"
},
"scripts": {
"dev": "nodemon",
"start": "node index.js"
}
}
You don't want it to look exactly like this of course, but just pointing you in the right of what you want to be doing. Of course you will need to do an npm install for those particular dependencies.
Then if I were you I would create a server/keys.js file like so:
module.exports = {
redisHost: process.env.REDIS_HOST,
redisPort: process.env.REDIS_PORT,
};
And then require that inside a server/index.js file where you will also add the following:
const keys = require("./keys");
// Express App Setup
const express = require("express");
const app = express();
// Redis Client Setup
const redis = require(‘redis’);
const redisClient = redis.createClient({
host: keys.redisHost,
port: keys.redisPort,
retry_strategy: () => 1000
});
const redisPublisher = redisClient.duplicate();
So this retry_strategy takes an arrow function and it is saying that if we ever lose connection to the redis server try to reconnect to it once every second.
The key for retry_strategy is separated by an underscore as opposed to the JavaScript standard of camelCase.
According to the Redis documentation for the Javascript library, if we ever have a client that is listening or publishing information on Redis we have to make a duplicate connection between when a connection is turned into one that is going to listen, subscribe or publish information, it cannot be used for other purposes.
So thats why I am doing this duplicate() thing at the end of redisClient.
So that is pretty much it.

Socket IO 1.2 Query Parameters

I can't figure out how to retrieve query parameters on the server side for socket.io
1.2.1
Here's my client side code
var socket = io('http://localhost:3000/',{_query:"sid=" + $('#sid').attr('data-sid') + "&serial=" + $('#serial_tracker').text()});
and the server side:
io.use(function(socket,next){ //find out if user is logged in
var handshake = socket.request;
console.log(socket.request._query);
handshake.sid = handshake.query.sid;
}
socket.request._query is:
{ EIO: '3', transport: 'polling', t: '1419909065555-0' }
Does anyone know how query parameters work in socket io 1.2.1?
Thanks for any help and if you need any more information, just ask me.
When sending handshake query data to socket.io, use the following property name in the object:
{
query: 'token=12345'
}
I see above you used _query for a property name instead.
You should be able to access the query information at socket.request._query at that point. I'm not sure if there is a better way to get a hold of that data? I'm guessing yes, since they put an underscore in front of it, but I haven't found a better way yet.
Here's the full example of a connect query that is working for me (forgive the formatting, I'm copy/pasting this out of different node modules into an inline solution).
Server (using socket 1.2.1 nodejs):
var restify = require('restify');
var api = restify.createServer();
var socketio = require('socket.io');
var io = socketio.listen(api.server); // api is an instance of restify, listening on localhost:3000
io.use(function(socket, next) {
// socket.request._query.token is accessible here, for me, and will be '12345'
next();
});
api.listen(3000, function() {
console.log('%s listening at %s', api.name, api.url);
});
Client (chrome browser using the client library located at https://cdn.socket.io/socket.io-1.2.1.js):
var socket = io.connect('http://localhost:3000/', { query: 'token=12345' });

node.js making localhost client requests when system proxy is set

Here's the deal: I'm using node.js to connect to a local CouchDB instance.
The problem: the "response" event isn't firing. So I'm assuming it's not getting a connection.
var http = require('http'),
sys = require('sys'),
url = require('url');
var server = http.createServer(function (request, response) {
var client = http.createClient(5984, '127.0.0.1'); // couchdb
var request_db = client.request('GET', '/_all_dbs');
console.log('Created a request for _all_dbs');
request_db.addListener('response', function(response_db) {
console.log('Some response from CouchDB');
});
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
The only only output is:
Server running at http://127.0.0.1:8124/
Created a request for _all_dbs
I'm also guessing this might be a proxy problem. In Ubuntu 10.10, I have a system-wide proxy setting, but I tell it to ignore 127.0.0.1. Doing a curl on 127.0.0.1:5984/_all_dbs gives an error on "Error Code: 502 Proxy Error.".
First, try accessing 127.0.0.1:8124/_utils as #PartlyCloudy suggests.
Second, try using a couchdb lib such as cradle to make your life easier (and minimize mistakes)
npm install cradle
Remember to stop into #node.js and ask questions! Make sure to report back with your findings.
If you are using request to make the http request set proxy as empty string.. It will take preference over the system settings (you can do it only when the target ip is current machine ip)
var options = {
agent: ...,
url: ...,
method: ...,
proxy: ''
};
var req= request(options);
.
.
.

Categories

Resources