Хук jwt позначає перевірку JWT без закріпленого алгоритму, тобто діру плутанини алгоритмів, коли верифікатор довіряє заголовку alg самого токена, а також повністю вимкнену перевірку. Він враховує мову й читає кожен файл з огляду на його бібліотеку JWT. Це детермінований рушій спеціалізації federation, який ви можете запускати самі в режимі scan або check.
Запуск
- Перевірити кодову базу
- Перевірити виклик
npx lagune read jwt # scans the whole project
npx lagune read jwt --dir src # scans a directory
npx lagune read jwt --file auth.ts # scans a single file
npx lagune read jwt --lang javascript --pattern 'jwt.verify(token, secret)' # => unpinned
npx lagune read jwt --lang python --pattern 'jwt.decode(t, k, options={"verify_signature": False})' # => unpinned
npx lagune read jwt --lang python --pattern 'jwt.decode(t, k, algorithms=["HS256"])' # => safe
Кожен рядок під Unpinned JWT verification found є викликом перевірки, який не задає allowlist algorithms (там, де бібліотека його потребує), приймає небезпечний (none або асиметричний алгоритм, змішаний з HMAC) чи взагалі вимикає перевірку підпису, тож довіряє alg самого токена. Це підтверджена вразливість, тому хук завершується з ненульовим кодом. Чистий запуск виводить no unpinned JWT verification found.
Як читати вердикт
| Вердикт | Значення |
|---|---|
unpinned | Виклик перевірки без allowlist алгоритмів (там, де він потрібен), з небезпечним allowlist або з вимкненою перевіркою. |
safe | Виклик перевірки, що закріплює надійний allowlist алгоритмів або чия бібліотека закріплює його неявно. |
invalid | Фрагмент не містить розпізнаваного виклику перевірки, який можна оцінити. |
Параметри CLI
| Параметр | Значення | Опис |
|---|---|---|
--pattern | фрагмент коду | Перевірити один виклик. Повторіть, щоб перевірити кілька, по вердикту на рядок. |
--lang | мова | Обов'язковий із --pattern: одна з javascript, python, go, java, kotlin, php, ruby, rust, csharp. |
--dir | каталог | Обмежити перевірку каталогом. Повторюється й поєднується з --file. |
--file | файл | Обмежити перевірку одним файлом. Повторюється й поєднується з --dir. |
Без параметрів хук перевіряє весь проєкт. --pattern потребує --lang і не поєднується з --dir чи --file.
Підтримувані мови
Перевірка читає ці бібліотеки, визначаючи їх за розширенням файлу. Оскільки деякі з них закріплюють алгоритм неявно (відсутність явного списку там цілком надійна), правило "немає allowlist ⇒ unpinned" діє лише там, де бібліотека очікує явний список, тож правильно налаштований виклик ніколи не позначається.
| Мова | Бібліотека | Чи позначає відсутність allowlist як unpinned? | Позначає завжди |
|---|---|---|---|
| JavaScript / TypeScript | jsonwebtoken, jose | Так | none, змішування асиметричного алгоритму з HMAC |
| Python | PyJWT, python-jose | Так (PyJWT його вимагає, у python-jose за замовчуванням algorithms=None) | none, verify_signature: False |
| Go | golang-jwt | Так (без WithValidMethods) | none, ParseUnverified |
| Ruby | ruby-jwt | Так | none, verify = false |
| Java / Kotlin | jjwt, nimbus | Ні (виводиться з ключа) | none, непідписаний чи unsecured парсер |
| PHP | firebase/php-jwt | Ні (Key містить алгоритм) | none |
| Rust | jsonwebtoken | Ні (Validation його вимагає) | none, insecure_disable_signature_validation |
| C# | Microsoft.IdentityModel | Ні (багаторядкові параметри) | none, RequireSignedTokens = false |
Хук вирішує лише щодо закріплення алгоритму: перевірки claims, ключів і потоку і далі охоплює спеціалізація federation, бо це питання судження.
Часті запитання
Верифікатор, що читає алгоритм із заголовка токена, дає зловмиснику змогу замінити RS256 на HS256 і підписати токен публічним ключем. Закріплення надійного allowlist алгоритмів у коді запобігає цьому, а хук jwt позначає виклик перевірки, який не задає жодного allowlist або задає небезпечний.
