# Хук jwt: виявлення перевірки JWT без закріпленого алгоритму

> Перевірте кодову базу на перевірку JWT без закріпленого алгоритму або оцініть окремий виклик просто з командного рядка.

Канонічна URL-адреса: https://lagune.ai/uk-UA/docs/hooks/jwt
Мова: uk-UA
Оригінал: https://lagune.ai/docs/hooks/jwt
Останнє оновлення: 2026-11-03

Хук `jwt` позначає **перевірку JWT без закріпленого алгоритму**, тобто діру плутанини алгоритмів, коли верифікатор довіряє заголовку `alg` самого токена, а також **повністю вимкнену перевірку**. Він **враховує мову** й читає кожен файл з огляду на його бібліотеку JWT. Це детермінований рушій [спеціалізації `federation`](https://lagune.ai/uk-UA/docs/catalog), який ви можете запускати самі в режимі **scan** або **check**.

## Запуск

**Перевірити кодову базу**

```bash
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
```

**Перевірити виклик**

```bash
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`](https://lagune.ai/uk-UA/docs/catalog), бо це питання судження.

## Часті запитання

### Що таке плутанина алгоритмів JWT?

Верифікатор, що читає алгоритм із заголовка токена, дає зловмиснику змогу замінити RS256 на HS256 і підписати токен публічним ключем. Закріплення надійного allowlist алгоритмів у коді запобігає цьому, а хук jwt позначає виклик перевірки, який не задає жодного allowlist або задає небезпечний.
