JWT (Json Web Token)
JWT nədir?
JSON Web Token (JWT) iki tərəf arasında məlumatı təhlükəsiz şəkildə təmsil etmək üçün yığcam və müstəqil bir üsuldur. O, adətən veb inkişafında autentifikasiya və məlumat mübadiləsi üçün istifadə olunur. JWT üç hissədən ibarətdir: başlıq, payload və imza. Başlıq adətən işarənin növünü və imzalama alqoritmini təyin edir, paylaod isə iddiaları və ya məlumatları əhatə edir. Bu hissələr JWT yaratmaq üçün base64 kodlu və birləşdirilir. İmza, tokenin bütövlüyünü yoxlamaq üçün bir yol təqdim edən secret açardan istifadə edərək yaradılır. JWT-lər tez-tez autentifikasiya proseslərində istifadə olunur, burada istifadəçi uğurlu girişdən sonra nişan alır və istifadəçinin şəxsiyyətini və icazələrini təmin etmək üçün bu işarədən istifadə edərək sonrakı sorğular təsdiqlənə bilər.
JWT-nin formatı
JSON Veb Tokeni aşağıdakı kimi nöqtələrlə ayrılmış base64url kodlaşdırmasında başlıq, payload və imzadan ibarətdir:
Aşağıdakı həqiqi nişanı ayıraq:
Başlıqda imza üçün istifadə olunan alqoritm və işarənin növü (sadəcə JWT) kimi nişan haqqında metadata var. Bu misal üçün kodlaşdırmadan əvvəl başlıq belədir:
Payload-da proqram tərəfindən yoxlanılacaq qurum (user) haqqında məlumat (claims) var. Nümunə nişanımıza aşağıdakı claim-lər daxildir:
Nəhayət, imza yaratmaq üçün başlığa, nöqtəyə və payload-a base64url kodlamasını tətbiq etməli və sonra alqoritmdən asılı olaraq secret (simmetrik şifrələmə üçün) və ya private key (asimmetrik şifrələmə üçün) istifadə edərək hər şeyi imzalamalıyıq. HS256-nı simmetrik bir alqoritm olan başlığa yerləşdirdik, buna görə də kodlaşdırma və imzalama əməliyyatı belə olur:
Bu, bizə aşağıdakı imzanı verir, daha sonra base64url ilə kodlanmış başlığa və payload-a əlavə olunur (nöqtədən sonra):
Ümumi JWT zəiflikləri
JSON Veb Tokenləri çevik və gələcəyə davamlı olmaq üçün nəzərdə tutulmuşdur, müxtəlif istifadə hallarına və tələblərinə uyğunlaşmaq üçün çoxlu yer, həm də tətbiq və istifadədə səhvlər üçün çox yer buraxmışdır. JWT-lərlə işləyərkən təqdim edilə bilən bəzi tipik zəifliklər bunlardır.
İmzanı yoxlamaqla bağlı xətalar
Bir çox JWT kitabxanaları nişanı deşifrə etmək üçün bir üsul, onu yoxlamaq üçün isə digər üsul təqdim edir:
decode()
: İmzanı yoxlamadan yalnız base64url kodlaşdırmasından nişanı deşifrə edir.verify()
: Tokenin kodunu açır və imzanı yoxlayır.
Bəzən tərtibatçılar bu üsulları qarışdıra bilərlər. Bu halda, imza heç vaxt yoxlanılmır və proqram hər hansı işarəni (etibarlı formatda) qəbul edəcək. Tərtibatçılar sınaq üçün imza doğrulamasını deaktiv edə və sonra onu yenidən aktivləşdirməyi unuda bilərlər. Bu cür səhvlər hesaba ixtiyari girişə və ya imtiyazların artmasına səbəb ola bilər.
Məsələn, tutaq ki, heç vaxt təsdiqlənməmiş aşağıdakı etibarlı işarəmiz var:
Təcavüzkar üst səviyyə imtiyazları əldə etmək üçün ixtiyari imza ilə aşağıdakı işarəni göndərə bilər:
None
alqoritminə icazə verilərsə
None
alqoritminə icazə verilərsəJWT standartı imza yaratmaq üçün bir çox müxtəlif növ alqoritmləri qəbul edir:
RSA
HMAC
Elliptic Curve
None
None
alqoritmi işarənin imzalanmadığını müəyyən edir. Bu alqoritmə icazə verilirsə, mövcud alqoritmi None-a dəyişdirərək və imzanı silməklə imza yoxlamasını bypass edə bilərik. Gözlənilən nişanımızla başlayaq:
Şifrələnmiş və imzalanmış nişan bu kimi görünəcək (qalın hərflərlə imza):
Əgər alqoritm dəyəri kimi None
icazə verilmirsə, təcavüzkar ondan sadəcə olaraq etibarlı alqoritmi əvəz etmək üçün istifadə edə və sonra imzadan qurtula bilər:
İndi imzalanmamış olsa da, dəyişdirilmiş nişan tətbiq tərəfindən qəbul ediləcək:
Buna görə də alg
başlığında None
, none
, NONE
, nOnE
və ya hər hansı digər hal dəyişikliyi ilə tokenləri qəbul etməmək vacibdir.
Algorithm qarışıqlılığı
JWT həm simmetrik, həm də asimmetrik şifrələmə alqoritmlərini qəbul edir. Şifrələmə növündən asılı olaraq, ya paylaşılan secret, ya da public-private açar cütündən istifadə etməlisiniz:
Algorithm | Key used to sign | Key used to verify |
Asymmetric (RSA) | Private key | Public key |
Symmetric (HMAC) | Shared secret | Shared secret |
Tətbiq asimmetrik şifrələmədən istifadə etdikdə, o, açıq açarını açıq şəkildə dərc edə və private key-i gizli saxlaya bilər. Bu, proqrama private key-dən istifadə edərək nişanları imzalamağa imkan verir və hər kəs public-key istifadə edərək bu nişanı yoxlaya bilər. Alqoritm çaşqınlığı zəifliyi, proqram qəbul edilmiş işarənin alqoritminin gözlənilən alqoritmə uyğun olub-olmadığını yoxlamadıqda yaranır.
Bir çox JWT kitabxanasında imzanı yoxlamaq üçün üsul belədir:
verify(token, secret)
– nişan HMAC ilə imzalanıbsaverify(token, publicKey)
– nişan RSA və ya oxşarı ilə imzalanıbsa
Təəssüf ki, bəzi kitabxanalarda bu üsul öz-özünə qəbul edilmiş işarənin tətbiqin gözlənilən alqoritmi ilə imzalanıb-imzalanmadığını yoxlamır. Buna görə HMAC vəziyyətində bu üsul ikinci arqumenti paylaşılan secret, RSA vəziyyətində isə public-key kimi nəzərdən keçirəcəkdir.
Əgər public-key tətbiq daxilində əlçatandırsa, təcavüzkar zərərli nişanları saxtalaşdıra bilər:
Tokenin alqoritminin HMAC-ə dəyişdirilməsi
İstədiyiniz nəticəni əldə etmək üçün faydalı yükə müdaxilə
Tətbiqdə tapılan açıq açarla zərərli nişanın imzalanması
JWT-nin tətbiqə geri göndərilməsi
Tətbiq RSA şifrələməsini gözləyir, ona görə də təcavüzkar əvəzinə HMAC təmin etdikdə, verify()
metodu public-key-i HMAC-nin paylaşılan secret kimi qəbul edəcək və asimmetrik şifrələmədən daha çox simmetrik istifadə edəcək. Bu o deməkdir ki, nişan tətbiqin gizli olmayan public key ilə imzalanacaq və sonra eyni public key-dən istifadə edilərək yoxlanılacaq.
Bu zəifliyin qarşısını almaq üçün proqramlar tokeni verify()
metoduna ötürməzdən əvvəl qəbul edilmiş tokenin alqoritminin gözlənilən alqoritm olub-olmadığını yoxlamalıdır.
Önəmsiz secret-lərdən istifadə etmək
Simmetrik şifrələmə ilə kriptoqrafik imza yalnız istifadə edilən secret qədər güclüdür. Tətbiq zəif bir secret istifadə edərsə, təcavüzkar orijinal imza saxta imzaya uyğun gələnə qədər müxtəlif gizli dəyərləri sınayaraq onu sadəcə olaraq brute force edə bilər. Secret-i aşkar etdikdən sonra təcavüzkar ondan zərərli nişanlar üçün etibarlı imzalar yaratmaq üçün istifadə edə bilər. Bu zəifliyin qarşısını almaq üçün güclü secret-lər həmişə simmetrik şifrələmə ilə istifadə edilməlidir.
JSON Veb Tokenlərinə qarşı hücumlar
kid
parametrlərinin enjeksiyonları
kid
parametrlərinin enjeksiyonlarıJWT başlığında Açar İd parametri kid
ola bilər. Çox vaxt database-dən və ya fayl sistemindən açarı almaq üçün istifadə olunur. Ərizə kid
parametri vasitəsilə əldə edilən açardan istifadə edərək imzanı yoxlayır. Parametr inyeksiya edilə biləndirsə, o, imza atmağa və ya hətta RCE, SQLi və LFI kimi hücumlara yol aça bilər.
Bunu hərəkətdə görmək üçün aşağıdakı etibarlı işarə ilə başlayaq:
Kid
parametri əmr inyeksiyasına həssasdırsa, aşağıdakı modifikasiya kodun uzaqdan icrasına səbəb ola bilər:
kid
parameter injection + directory traversal = signature bypass
kid
parameter injection + directory traversal = signature bypassƏgər proqram fayl sistemindən açarı əldə etmək üçün kid
parametrindən istifadə edirsə, o, kataloq keçidinə qarşı həssas ola bilər. Bundan sonra təcavüzkar tətbiqi doğrulama üçün açar kimi dəyərini təxmin edə biləcəyi fayldan istifadə etməyə məcbur edə bilər. Bu, proqram daxilində istənilən statik fayldan istifadə etməklə edilə bilər. Açar fayl dəyərini bilən təcavüzkar zərərli nişan yarada və məlum açardan istifadə edərək onu imzalaya bilər.
Əvvəlki JWT nümunəsinə davam edərək, təcavüzkar tətbiqi boş açardan istifadə etməyə məcbur etmək üçün əsas mənbə kimi /dev/null
daxil etməyə cəhd edə bilər:
If directory traversal to /dev/null
succeeds, the attacker will be able to sign a malicious token using an empty string. The same technique can be used with known static files, for example CSS files.
kid
parameter injection + SQL injection = signature bypass
kid
parameter injection + SQL injection = signature bypassƏgər proqram database-dən açarı əldə etmək üçün kid
parametrindən istifadə edirsə, o, SQL inyeksiyasına qarşı həssas ola bilər. Müvəffəqiyyətli olarsa, təcavüzkar SQL sorğusundan kid
parametrinə qaytarılan dəyəri idarə edə və onu zərərli nişanı imzalamaq üçün istifadə edə bilər.
Yenə eyni nümunə işarəsindən istifadə edərək, deyək ki, proqram kid
parametri vasitəsilə JWT açarını əldə etmək üçün aşağıdakı həssas SQL sorğusundan istifadə edir:
Təcavüzkar daha sonra əsas dəyəri idarə etmək üçün kid
parametrinə UNION SELECT ifadəsini yeridə bilər:
SQL inyeksiyası uğurlu olarsa, proqram imza açarını əldə etmək üçün aşağıdakı sorğudan istifadə edəcək:
Bu sorğu aaa
-nı kid
parametrinə qaytararaq, təcavüzkara sadəcə aaa
ilə zərərli nişanı imzalamağa imkan verir.
Bu və digər inyeksiya hücumlarının qarşısını almaq üçün proqramlar həmişə kid
parametrinin dəyərini istifadə etməzdən əvvəl təmizləməlidir.
Jku
başlığından istifadə edərək hücumlar
Jku
başlığından istifadə edərək hücumlarJWT başlığında tərtibatçılar JSON Veb Açar Dəsti URL-ni təyin etmək üçün jku
parametrindən də istifadə edə bilərlər. Bu parametr, tətbiqin imzanı yoxlamaq üçün istifadə edilən JSON Veb Açarını (JWK) harada tapa biləcəyini göstərir - əsasən JSON formatında açıq açar.
Nümunə etmək üçün public key-i təyin etmək üçün jku
parametrindən istifadə edən aşağıdakı JWT-ni götürək:
Göstərilən key.json
faylı belə görünə bilər:
Tətbiq jku
başlıq dəyəri əsasında əldə edilmiş JSON Veb Açarından istifadə edərək imzanı yoxlayır:
İndi hücum üçün təcavüzkar jku
parametrinin dəyərini dəyişdirərək etibarlı olan əvəzinə öz JWK-ni göstərə bilər. Qəbul edilərsə, bu, təcavüzkara öz private key-dən istifadə edərək zərərli nişanları imzalamağa imkan verir. Zərərli nişan göndərildikdən sonra proqram təcavüzkarın JWK-ni alacaq və imzanı yoxlamaq üçün ondan istifadə edəcək:
Bu cür hücumların qarşısını almaq üçün proqramlar adətən URL filtrindən istifadə edir. Təəssüf ki, təcavüzkarların bu cür filtrləmədən yan keçməsinin yolları var, o cümlədən:
Tətbiq etibarlı ilə başlayan URL-ləri yoxlayırsa,
https://trusted
istifadə edərək (məsələn,https://[email protected]/key.json
)DNS adlandırma iyerarxiyasından istifadə
Açıq yönləndirmə ilə zəncirləmə
Başlıq inyeksiyası ilə zəncirləmə
SSRF ilə zəncirləmə
Bu səbəbdən, tətbiqin icazə verilən hostları white-list-ə salması və düzgün URL filtrinin olması çox vacibdir. Bundan əlavə, tətbiqdə təcavüzkarın URL filtrini bypass etməsi üçün zəncirləyə biləcəyi digər zəifliklər olmamalıdır.
Nəticə
JSON Veb Tokenləri müasir veb tətbiqetmələrin inkişafında, xüsusən də tək giriş (SSO) həyata keçirərkən autentifikasiya proseslərinin mühüm hissəsinə çevrilir. JWT zəifliklərinin qarşısını almaq üçün tərtibatçılar ən yaxşı təcrübələrə əməl etməli və öz tətbiqlərini yaymaq əvəzinə etibarlı JWT kitabxanalarından istifadə etməlidirlər. Təcavüzkarların JWT hücumlarını digər zəifliklərlə zəncirləmə riskini minimuma endirmək üçün siz həmçinin zəif tərəfləri kibercinayətkarlar tərəfindən istismar edilməzdən əvvəl tapmaq üçün yüksək keyfiyyətli zəiflik skan həllindən istifadə etməlisiniz. Invicti
kimi müasir DAST
aləti minlərlə digər problemlə yanaşı JWT zəifliklərini də müəyyən edə bilər və onu istənilən proqram təhlükəsizliyi alətlər qutusunun mühüm hissəsinə çevirir.
Praktiki nümunə
Last updated