-
Notifications
You must be signed in to change notification settings - Fork 214
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
Disallow None algorithm by default #228
Comments
How would you propose explicitly disabling the "None" algorithm? jsonwebtoken jumps through some hoops to guess the correct algorithm based on the provided secret, whether the token is signed etc. See here. Based on this, simply passing a list of all of the "blessed" algorithms probably won't work and I'd rather not duplicate all of that logic. jsonwebtoken doesn't appear to have an option to explicitly disable a single algorithm, only selectively enable them. The best approach seems like it might be to force users of passport-jwt to set |
Just out of curiosity i tried to reproduce the issue of accepting unsinged tokens with the default configuration. But could not reproduce it with the default configuration. @p-v-d-Veeken maybe i'm overseeing something and you could provide a small example server and a token, how to reproduce your issue? Findings
Conclusion1.) To me it seems that passport-jwt already does a great job by requiring a secret or a key (and therefore disabling Possible improvements for passport-jwt1.) Adding a check for non truthy Example serverThis is the server i used to test, where an unsigned token will be accepted: const express = require('express');
const passport = require('passport');
const app = express();
const { ExtractJwt, Strategy: JwtStrategy} = require('passport-jwt');
const opts = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKeyProvider: (req, token, cb) => cb()
}
passport.use('jwt', new JwtStrategy(opts, (jwt_payload, done) => {
console.log('Got a valid jwt payload', jwt_payload);
done(null, jwt_payload);
}));
app.get('/',
passport.authenticate('jwt', {session: false}),
function(req, res){
res.send('welcome in');
}
);
app.listen(4000); Tested with this request Used modules"dependencies": {
"express": "4.17.3",
"passport": "0.5.2",
"passport-jwt": "4.0.0"
} |
thanks for your analysis this has helped me, the simplest migration seems to me a standard algorithm (other than |
[email protected] fixed that issue with the update to [email protected]. Looks like this issue can be closed. |
Does this mean that a secret is now always required? I have a use case to use a JWT that is unsigned (None algorithm). Is there any way to accept an unsigned JWT? |
|
At my company we just discovered that the financial services application (NestJS backend) we are building has a critical security vulnerability because our JWT passport strategy accepted claims signed with the None algorithm. In the first place this is our fault of course, because we should've been more thorough with the implementation, also we weren't live for customers yet so really no harm done.
That being said, I think it's a bad design choice that using passport-jwt with the defaults unchanged results in an extremely unsafe authentication method. We were fortunate enough to find this vulnerability before any real harm was done, but I suspect there are a lot companies/projects/applications out there that unknowingly have this landmine in their codebase.
My suggestion is to disable the None algorithm (and any other unsafe algorithms) by default and optionally allow users to explicitly enable it.
Thoughts?
The text was updated successfully, but these errors were encountered: