Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting 403 forbidden because token has changed #54

Closed
marlonmantilla opened this issue Jul 13, 2015 · 20 comments
Closed

Getting 403 forbidden because token has changed #54

marlonmantilla opened this issue Jul 13, 2015 · 20 comments
Labels
bug Bug or defect
Milestone

Comments

@marlonmantilla
Copy link

Hi guys, I'm working in a HapiJS API and a separate Web client app (Just HTML and JS) which basically will have a form with a CSRF crumb token. So the Web app basically makes a call to GET /generate and HapiJS will return the CSRF token. After that when I submit the form I hit POST /send and sends the token with X-CSRF-Token header but for some reason is returning 403 ...

HAPIJS Routes

server.route([
        {
            method: 'GET',
            path: '/generate',
            handler: Controllers.Auth.generate_csrf,
            config: {
                auth: false,
                jsonp: 'callback'
            }
        },
        // request header "X-CSRF-Token" with crumb value must be set in request for this route
        {
            method: 'POST',
            path: '/send',
            handler: Controllers.Auth.csrf_handshake,
            config: {
                auth: false
            }
        }
    ]);

HapiJS routes handlers:

exports.generate_csrf = function (request, reply) {
    request.log.info(request.info, 'Request to generate CSRF Token');
    return reply({csrf_token: request.plugins.crumb});
};

exports.csrf_handshake = function (request, reply) {
   return reply('OK');
};

On the web side:

(function () {

    var form = $("#sms-form");
    var host = "http://localhost:3002"; // HAPIJS Host

    var getAuth = function () {
        $.ajax({
            url: host + "/generate",
            jsonp: "callback",
            dataType: "jsonp",
            success: function( response ) {
                var token = response.csrf_token; 
                var input = $('<input name="csrf_token" type="hidden" value="'+token+'">');
                form.append(input);
            },
            error: function (req, status, err) {
                console.log('error');
            }
        });
    };

    getAuth();


    form.on('submit', function (e) {
        e.preventDefault();

        var authorizationToken = $(e.currentTarget).find('input[name="csrf_token"]').val();

        console.log(authorizationToken);
        if(authorizationToken) {
            $.ajax({
                type:"POST",
                beforeSend: function (request)
                {
                    request.setRequestHeader("X-CSRF-Token", authorizationToken);
                },
                url: host + "/send",
                data: {crumb: authorizationToken},
                dataType: "json",
                success: function(msg) {
                    console.log(msg);
                }
            });
        }else {
            console.log("We're having issues this request");
        }


    });

})();

Here's plugin config:

{
register: require('crumb'),
options: { restful: false }
}

Also I noticed that when calling multiple times GET /generate is returning the same CSRF token, not sure how to generate a new one per request.

When adding a debugger to crumb/lib/index.js, I noticed that the they're not the same:

          debugger;
            if (content instanceof Stream) {

                return reply(Boom.forbidden());
            }

            if (content[request.route.settings.plugins._crumb.key] !== request.plugins.crumb) {
                return reply(Boom.forbidden());
            }

Am I missing something here ?

@zoe-1
Copy link

zoe-1 commented Jul 14, 2015

@marlonmantilla @hapijs/university 's current assignment is related to crumb.
Follow instructions in the README to get started.
Specifics about the assignment are at: Assignment8.
Hopefully, you will join and submit a PR for the current assignment :-) Doing this assignment should clear your questions about crumb.

Plus, I made a sample app fulfilling requirements of Assignment8 here. The app has 100% test coverage and uses crumb in AJAX post requests, so should provide the solutions you are looking for. The tests code for the login and logout routes should be very relevant too. Cheers!

@stongo
Copy link
Contributor

stongo commented Jul 14, 2015

If you're trying pass the token as a "X-CSRF-Token" header you'll need to set crumb's plugin option restful: true
Otherwise, crumb expects the token to be in the POST payload: { "crumb": "TOKEN" }

@marlonmantilla
Copy link
Author

@stongo I tried with both disabling restful: true|false, you can see data: {crumb: authorizationToken} but as soon as I debug the tokens are not the same is like Crumb generate a new one when cheking.

@stongo
Copy link
Contributor

stongo commented Oct 22, 2015

Getting a similar error in one test only when converting crumb to hapi 9 f728d64. This may be related to this issue

@stongo stongo added the bug Bug or defect label Oct 22, 2015
@stongo stongo added this to the 5.0.0 milestone Oct 22, 2015
@stongo
Copy link
Contributor

stongo commented Nov 12, 2015

Closing due to inactivity. Re-open if this bug still reproduce-able with Crumb >= 5.x

@stongo stongo closed this as completed Nov 12, 2015
@davemackintosh
Copy link

@stongo, I'm still seeing this issue with:

Crumb@5.0.0
Hapi@11.1.1

@hoshin
Copy link

hoshin commented Jul 5, 2016

Same here with
Crumb@6.0.2
Hapi@13.4.2

:-/

Note : right now I'm not even trying to integrate the plugin, i'm just fiddling with the "restful.js" demo app (had trouble integrating, so I cut all the "this might be due to some weird plugin interaction / configuration" issues and just tried the demo app barebone.

As far as I can tell, the "generate" function is called on the /crumbed call (when i'd expect to check the token I have in my headers).

I'm using the default configuration. Right now I'm trying to see how it fares when deactivating the auto-generation, so far no luck

@hoanghiep
Copy link

Here is my config

server.register({ register: require('crumb'), options :{ restful : true, cookieOptions : {isSecure : false} } }, (err) => {
  Hoek.assert(!err, err);
});

And form

      <form action="/login" method="post">
        <div>{{message}}</div>
        <input type="text" name="username" value="john"/>
        <input type="text" name="password" value="password"/>
        <input type="hidden" name="crumb" value="{{crumb}}"/>
        <input type="submit" value="Đăng nhập">
      </form>

Result
{"statusCode":403,"error":"Forbidden"}

restful : true does not work with form :(

@afgallo
Copy link

afgallo commented Jul 6, 2016

I am also getting the same error as per @hoshin. The generate function gets called twice:

  1. When I request my crumb token via GET /generate
  2. When I post the token to POST /crumbed

Relevant part when debugging:

    // Set crumb cookie and calculate crumb

    if ((settings.autoGenerate ||
        request.route.settings.plugins._crumb) &&
        (request.route.settings.cors ? request.info.cors.isOriginMatch : true)) {

        generate(request, reply);
    }

@hoshin
Copy link

hoshin commented Jul 6, 2016

@stongo I'd gladly re-open if I could but it doesn't seem possible on my end =)

@mtharrison mtharrison reopened this Jul 6, 2016
@genediazjr
Copy link

I encountered this issue as well using the server example.

@stongo stongo modified the milestones: 6.0.3, 5.0.0 Aug 2, 2016
@stongo
Copy link
Contributor

stongo commented Aug 2, 2016

found a bug related to the generate function. fixing in upcoming release

@stongo
Copy link
Contributor

stongo commented Aug 4, 2016

It might have been a problem with the example, in fact. Using server.plugins.crumb.generate()
If someone can verify #88 that'd be great

@afgallo
Copy link

afgallo commented Aug 5, 2016

@stongo it didn't work for me .... if #88 is only about fixing the example, when I tried to reproduce it on my local env it didn't really work :(
Still keen to help though.

@stongo
Copy link
Contributor

stongo commented Aug 5, 2016

@afgallo check the pr example now, forgot to add the generate function args :(
the generate route in the example shouldn't cause the problem you described anymore

@afgallo
Copy link

afgallo commented Aug 6, 2016

@stongo still no luck :(

I noticed that the objects request.plugins.crumb and server.plugins.crumb are different. If this is by design, you can ignore my comment, but wouldn't this cause issues? When calling request.server.plugins.crumb.generate I noticed that request.plugins.crumb was already populated ...

I also created a gist for you to have a look and see if I am making any stupid mistakes: https://gist.github.com/afgallo/e62fba828b2fcb1a96a808f754b94c3f

@afgallo
Copy link

afgallo commented Aug 8, 2016

@stongo finally some good news! I reviewed your tests cases and found what appeared to fix my unit tests.

I simply modified my test cases from:

headers: { 'X-CSRF-token': token }

to:

headers: { 'X-CSRF-token': token, cookie: 'crumb=' + token }

It seems to be working now! I'll let you know if I come across any other issues.

identityclash added a commit to identityclash/hapi-login-test that referenced this issue Aug 9, 2016
@stongo
Copy link
Contributor

stongo commented Aug 12, 2016

Excellent @afgallo
For anyone else having issues please use latest example and version 6.0.3 and re-open if there's still an issue.

@stongo stongo closed this as completed Aug 12, 2016
@hoshin
Copy link

hoshin commented Aug 13, 2016

Thanks =)

@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Bug or defect
Projects
None yet
Development

No branches or pull requests

9 participants