MickCrozier
MickCrozier

Reputation: 312

Sails.js socket.io general security

Using sails sockets. From a browser I can get all 'tasks' where the user id is 1. I can now listen for the 'task' event and look for 'created' in the verb to get new tasks and add them to the list.

However I get events from ALL created tasks regardless of user. This seems to be me as a major security issue. All someone needs to do jump into the console and set up a listener to get notified whenever any user creates a new task.

I had a look around for sometime but can't find any posts on the topic. Being new to this kind of thing - can someone be kind enough to help out?

What is the best practise for dealing with lists over socket.io in Sails?

Cheers!

Upvotes: 4

Views: 313

Answers (1)

Alex Alksne
Alex Alksne

Reputation: 518

This should be what you're looking for; it prevents you from subscribing to all existing tasks on the client side. It only subscribes if you're logged in and only to tasks that belong to you. Keep in mind that this is just a first-step in implementing a secure REST API for your app - but it should get you started.

In your client-side app you'd write:

socket.on('connect', function socketConnected()
{
    // This subscribes the user to all tasks that belong to him and only him.
    socket.get('/task/subscribe', null, function response(data, jwres)
    {
        // We don’t really care about the response.
    });

    // This 1.) creates a new task and 2.) subscribes the user to that task.
    // If the 'rest' blueprint is on, POSTing to /task gets redirected to TaskController.create automatically by sails.
    // If it's not on, you write "socket.get('/task/create' ..."
    socket.post('/task', {name : 'MyNewTask'}, function response(data, jwres)
    {
        // Add the created task inside of 'data' to your client side app.
    });
})

Then in TaskController.js you would write:

subscribe : function(req, res)
{
    // Is the user logged in?
    if(!req.session.user)
    {
        return res.badRequest();
    }

    // Find all tasks that belong to the currently logged in user.
    Task.find({userID : req.session.user.id}, findUsersCB(err, tasks)
    {
        // Subscribe the user to all of his tasks.
        Task.subscribe(req.socket, tasks);

        // Send user's tasks back to the client.
        res.json(tasks);
    });
}

create : function(req, res)
{
    //Is the user logged in?
    if(!req.session.user)
    {
        return res.badRequest();
    }

    var taskToBeCreated = 
    {
        name : req.param('name'),
        userID : req.session.user.id;
    };

    // Attempt to create the given task.
    Task.create(taskToBeCreated, function createTaskCB(err, createdTask)
    {
        // Subscribe the user to the newly-created task.
        Task.subscribe(req.socket, createdTask);

        // Send user's task back to the client.
        res.json(task);
    });
}

I haven't shown an example for the 'update' and 'destroy' actions but the idea is the same for both.

Upvotes: 1

Related Questions