質問

I currently have Reddit authorization set up for my Node app just like in this example. I have the app on Reddit setup for the callback url http://example.com/auth/reddit/callback and everything is fine. Users can enter http://example.com/auth/reddit and log in and everything is good.

The problem comes in when a user tries to log in through http://www.example.com/. It appears that Reddit's CSRF protection sees these requests as an issue. As per the example:

/**
 * Authentication route
 */
app.get('/auth/reddit', function(req, res, next) {
    var n = crypto.randomBytes(32).toString('hex');
    req.session.state = n;
    passport.authenticate('reddit', {
        state    : n,
        duration : 'permanent'
    })(req, res, next);
});

/**
 * Authentication callback
 */
app.get('/auth/reddit/callback', function(req, res, next) {
    // Check for origin via state token
    if (req.query.state === req.session.state) {
        /* authenticate the user */
    } else { next(new Error(403)); }
}

For requests from http://example.com/auth/reddit, req.query.state === req.session.state. However, for requests made from http://www.example.com/auth/reddit, these values do not match. req.query.state takes the new state value, but req.session.state retains an old state value.

Is there a good work-around or solution to this problem? One work-around could be to automatically redirect all 'www' request to the root, but I haven't found a way to do that. Another option would be to remove the state check, but this would open up my code to CSRF attacks. Leaving everything as-is is not an option, as to users it's (understandably) very counter-intuitive to have the root domain work but the 'www' subdomain not work.

Thanks!

役に立ちましたか?

解決 2

To solve this, I'm using the node.js package express-force-domain

See here: https://stackoverflow.com/a/12755464/1222411

他のヒント

From what I understand, reddit redirects the user back to non-www domain, as per reddit application setup, and thus your session data is not available to you.

There are two solutions to this:

  1. Configure cookies to use .mydomain.com. See this answer for details.

  2. Ignore state flag, since it's not mandatory in OAuth2 spec, albeit recommended. Example has it for one simple reason, reddit fails to process a request if state field is not present. At least is was the case when I was writing the library. You are free to send any random string as a state value without checking for it on return.

I'd personally recommend the first approach as a default one, since state flag is designed to prevents a certain type of attack. You might want to go with second approach for simplicity, but do so only if you're well informed of potential consequences - which might strip it of the simplicity value.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top