I noticed that you do have your full mongoose model inside the generated json webtoken. This is a huge security flaw, as a json webtoken is only signed but not encrypted, meaning that everyone who can retrieve a token from a user ( e.g sniffing ) is able to obtain the users cleartext password, even from expired tokens.
Edit: I got asked to go a little more indepth about the underlying security issue here.
A JsonWebToken is signed but not encrypted, that means while we can verify that the content has not changed, it is still public for everyone. If you now receive a token by the API it contains all user information, including the cleartext password.
"$__": {
"strictMode": true,
"selected": {},
"getters": {},
"_id": "59ce4a552d40846c0b938085",
"wasPopulated": false,
"activePaths": {
"paths": {
"__v": "init",
"admin": "init",
"password": "init",
"name": "init",
"_id": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"__v": true,
"admin": true,
"password": true,
"name": true,
"_id": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"pathsToScopes": {},
"emitter": {
"domain": null,
"_events": {},
"_eventsCount": 0,
"_maxListeners": 0
}
},
"isNew": false,
"_doc": {
"__v": 0,{
"$__": {
"strictMode": true,
"selected": {},
"getters": {},
"_id": "59ce4a552d40846c0b938085",
"wasPopulated": false,
"activePaths": {
"paths": {
"__v": "init",
"admin": "init",
"password": "init",
"name": "init",
"_id": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"__v": true,
"admin": true,
"password": true,
"name": true,
"_id": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"pathsToScopes": {},
"emitter": {
"domain": null,
"_events": {},
"_eventsCount": 0,
"_maxListeners": 0
}
},
"isNew": false,
"_doc": {
"__v": 0,
"admin": true,
"password": "password",
"name": "Nick Cerminara",
"_id": "59ce4a552d40846c0b938085"
},
"$init": true,
"iat": 1506691722,
"exp": 1506778122
}
"admin": true,
"password": "password",
"name": "Nick Cerminara",
"_id": "59ce4a552d40846c0b938085"
},
"$init": true,
"iat": 1506691722,
"exp": 1506778122
}
This means that everyone who can receive that token has all information about the user. For example, if we would insert an email field for the user it will also show up there. This is even true for expired tokens. So every token the user ever created has all information about him inside, including the cleartext password.
This is obviously a huge security flaw.
A possible fix would be to only include selected attributes inside the payload of the token, not the entire model.
Further edit: Accidentally closed this issue. Lesson learned. Look where you click! Sorry! #