ArkeologeN / node-linkedin

LinkedIn 2.0 wrapper in Node.js
MIT License
163 stars 79 forks source link

If I scale nodejs Application to use more than 1 instance it gives Error { [CSRF Alert: Possible CSRF attack, state parameters do not match.] name: 'CSRF Alert' } #56

Open jagdish-176 opened 8 years ago

jagdish-176 commented 8 years ago

When I scale my nodejs application to use more than 2 instances it gives error, Error { [CSRF Alert: Possible CSRF attack, state parameters do not match.] name: 'CSRF Alert' }

As the "states" parameter in auth.js is using memory store it will create problem to scale application.

Scenario is '/oauth/linkedin' goes to App-0 (creates state parameter "xxxx" + store in memory) '/oauth/linkedin/callback' goes to App-1 (here it will check if received state is "xxxx" + check if in memory)

ArkeologeN commented 8 years ago

@jagdish-176 good catch! So you solution do you recommend for it? do you want to pass your own redis / mongodb adapter? or what if whenever have to save a new state, we may execute the internal-callback function by which you could handle your own state?

jagdish-176 commented 8 years ago

redis/mongodb adapter would be best..:D.

ArkeologeN commented 8 years ago

I am so much stuck in chores, may be I will try to get it done soon but I think, observer pattern is good. Whenever a new state is registered, you will be acknowledged in your registered callback function for the observed change and then, you're free to use any adapter you want in your own code. This actually helps a lot so that the wrapper remains stateless.

ericuldall commented 7 years ago

Is there any quick fix for this?

ericuldall commented 7 years ago

I just created a quick fix for this issue in distributed systems and you can use it here:

https://www.npmjs.com/package/node-linkedin-distributed

NOTE: This is not totally secure as it could be easier for a 3rd party to spoof a callback, so it is not recommended to use this library for user authentication that would give a user access to personal info stored in your database. I may be adding some support for a redis backend in the future and will happily provide any pull requests if you want.

Example usage:

var Linkedin = require('node-linkedin')('app-id', 'secret', 'callback');
app.get('/auth', function(req, res,next){
    Linkedin.auth.authorize(res, scope); // use this call as you normally do
});
app.get('/auth/cb', function(req, res, next){
    /**
      * Add your callback in the 4th argument to bypass CSRF check
      */
    Linkedin.auth.getAccessToken(res, req.query.code, req.query.state, 'callback', function(err, results) {
        if ( err )
            return console.error(err);

        /**
         * Results have something like:
         * {"expires_in":5184000,"access_token":". . . ."}
         */

        console.log(results);
        return res.redirect('/');
    });
});
ArkeologeN commented 7 years ago

Hi @ericuldall thanks for taking the step further. I think it would be great if implement the callback mechanism for state generation so that everyone can generate their own state (save, retrieve) and we wouldn't stick to any particular data store (redis, mongo) etc.

And of course, would love to see if you can contribute via pull request! :)

ericuldall commented 7 years ago

Yes, the callback idea is nice. Unfortunately we had a production system using the module that was broken, so I needed a quick fix. I'll see if I can do some work on a PR in the near future.

joeauty commented 7 years ago

@ericuldall thanks for your workaround! I might take a crack at that PR too, at some point, unless you beat me to the punch. I'll drop you a line though so this isn't a potentially duplicated effort!

ericuldall commented 7 years ago

That's all you @joeauty

Not sure I'll have time for a PR here anytime soon.

ArkeologeN commented 7 years ago

It would be great idea @ericuldall @joeauty

I'm merely out of play due to workload. I also intend to rewrite it with mocha test and support promises. But when? who knows!

joeauty commented 5 years ago

Surprise, surprise, this ancient thread lives! I've implemented this fix in this PR: https://github.com/ArkeologeN/node-linkedin/pull/91/files

Feedback welcome.

captainjackrana commented 5 years ago

This issue will also occur if you just happen to restart the server during the time the user is authorizing the app on linkedin. The state memory store is flushed resulting in a CSRF alarm.