(породено от тази тема, тъй като това наистина е въпрос сам по себе си и не е специфичен за NodeJS и т.н.)
Внедрявам REST API сървър с удостоверяване и успешно внедрих обработка на JWT токени, така че потребителят да може да влезе през /login крайна точка с потребителско име/парола, при което JWT токен се генерира от сървърна тайна и се връща към клиент. След това токенът се предава от клиента към сървъра във всяка удостоверена заявка за API, при което тайната на сървъра се използва за проверка на токена.
Въпреки това се опитвам да разбера най-добрите практики за това как точно и до каква степен токенът трябва да бъде валидиран, за да направя една наистина сигурна система. Какво точно трябва да бъде включено в "валидирането" на токена? Достатъчно ли е, че подписът може да бъде проверен с помощта на тайната на сървъра, или трябва също така да проверя кръстосано токена и/или токена с някои данни, съхранени в сървъра?
Системата за удостоверяване, базирана на токени, ще бъде толкова безопасна, колкото предаването на потребителско име/парола във всяка заявка, при условие че е еднакво или по-трудно да се получи токен, отколкото да се получи парола на потребител. Въпреки това, в примерите, които съм виждал, единствената информация, необходима за създаване на токен, е потребителското име и тайната от страната на сървъра. Това не означава ли, че ако приемем за минута, че злонамерен потребител получи информация за тайната на сървъра, той вече може да произвежда токени от името на всеки потребител, като по този начин има достъп не само до един даден потребител, както би дали е получена парола, но всъщност за всички потребителски акаунти?
Това ме навежда на въпросите:
1) Трябва ли валидирането на JWT токена да бъде ограничено до проверка на подписа на самия токен, разчитайки само на целостта на тайната на сървъра или придружено от отделен механизъм за валидиране?
В някои случаи съм виждал комбинирано използване на токени и сървърни сесии, при които при успешно влизане през крайната точка /login се установява сесия. API заявките валидират токена и също така сравняват декодираните данни, намерени в токена, с някои данни, съхранени в сесията. Използването на сесии обаче означава използване на бисквитки и в известен смисъл проваля целта на използването на подход, базиран на токени. Това също може да създаде проблеми за определени клиенти.
Човек може да си представи, че сървърът съхранява всички токени, използвани в момента, в memcache или подобен, за да гарантира, че дори ако тайната на сървъра е компрометирана, така че нападателят да може да произведе „валидни“ токени, само точните токени, които са били генерирани чрез крайната точка /login ще бъдат приети. Това разумно ли е или просто е излишно/прекалено?
2) Ако проверката на подписа на JWT е единственото средство за валидиране на токени, което означава, че целостта на тайната на сървъра е критичната точка, как трябва да се управляват тайните на сървъра? Прочетено от променлива на средата и създадено (рандомизирано?) веднъж на разгърнат стек? Подновява се или се ротира периодично (и ако е така, как да се справят със съществуващите валидни токени, които са създадени преди ротация, но трябва да бъдат валидирани след ротация, може би е достатъчно, ако сървърът държи текущата и предишната тайна във всеки даден момент) ? Нещо друго?
Може би просто съм прекалено параноичен, когато става въпрос за риска от компрометиране на тайната на сървъра, което разбира се е по-общ проблем, който трябва да се разглежда във всички криптографски ситуации...
RSAPrivateKey privateKey
?? - person kittu   schedule 26.02.2016