نکات امنیتی در استفاده از JWT

?JSON Web Tokens (JWT): How to Use Them Safely

04 اسفند 1399
نکات امنیتی در استفاده از JWT

JWT یا JSON Web Tokens یک استاندارد باز است که در RFC 7519 منتشر شد. JWT در عمل روشی برای بررسی ادعاهای وارده درباره یک منبع خاص با استفاده از اشیاء JSON است. محتوای داخل این توکن ها قابل اعتماد هستند چرا که به صورت دیجیتالی امضا شده اند. این امضای دیجیتالی می تواند با کلیدهای متقارن (مانند الگوریتم های HMAC) یا کلیدهای نامتقارن (مانند الگوریتم های RSA یا ECDSA) انجام شود. همچنین در نظر داشته باشید که JWT توانایی انتقال داده های رمزنگاری شده را نیز دارد.

باید در نظر داشت که توکن JWT در حالت عادی رمزنگاری نشده است و رشته ای که مشاهده می کنیم تنها یک رشته base64 می باشد بنابراین می تواند به سادگی decode شود. با این حساب پاسخ به سوال «آیا JWT امن است؟» بستگی به نحوه پیاده سازی آن دارد.

هر توکن JWT یه بخش دارد:

  • header: این قسمت شامل metadata های مربوط به توکن می شود (زمان انقضای توکن، الگوریتم استفاده شده برای امضای آن و غیره).
  • Payload: محتوای JSON و اصلی
  • signature: امضایی که پس از امضا کردن payload و header به دست می آید.

همانطور که گفتم هر توکن JWT یک رشته Base64 است بنابراین هر کدام از این قسمت ها با استفاده از علامت نقطه از هم جدا می شوند. با این حساب هر توکن JWT ساختار زیر را خواهد داشت:

[header].[payload].[signature]

من یک مثال ساده از این توکن ها را برایتان قرار می دهم:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA

در صورتی که قسمت header از توکن بالا را برداشته و decode کنیم، داده زیر را دریافت می کنیم:

{

    "alg":"RS256",

    "typ":"JWT"

}

تمام قسمت های دیگر این توکن نیز به همین شکل decode می شوند.

انواع توکن های JWT

ما در این قسمت سه نوع مهم توکن های JWT را بررسی می کنیم:

  • Data token: از آنجایی که توکن های serialized شده JWT فشرده هستند، پیاده سازی آن ها در درخواست های HTTP بسیار آسان است و از آن ها برای انتقال داده استفاده می شود.
  • ID token: معمولا توسط یک Identity Manager و در سمت کاربر و پس از احراز هویت کاربر ساخته می شود. این توکن ID به برنامه سمت کلاینت (کاربر) اجازه می دهد که اطلاعات کاربر را با روشی امن دریافت کند.
  • Access token: توسط یک authorization server و در سمت کاربر تولید می شود و به برنامه سمت کلاینت اجازه می دهد که از سمت کاربر به اطلاعات محافظت شده ای دسترسی داشته باشد. این روش معمولا برای authentication (احراز هویت) و authorization استفاده می شود.

نکات امنیتی در ساخت توکن

برای ساخت هر توکن JWT نکاتی امنیتی وجود دارد که باید همیشه رعایت کنید. ما در این قسمت به بررسی برخی از این نکات می پردازیم.

امضا کردن توکن

به غیر از مواردی خاص، توکن های JWT همیشه باید امضا شوند. زمانی که ما یک توکن را امضا می کنیم، مطمئن می شویم که محتوای آن به هیچ عنوان تغییری نکرده است. چطور؟ ما ابتدا توکن را با کلید خاصی می سازیم و سپس زمانی که کاربری این توکن را برای ما ارسال کند، کلید آن را بررسی می کنیم. در صورتی که امضای تولید شده توسط ما با امضای توکن یکی نباشد یعنی محتوای آن تغییر پیدا کرده است و آن را رد می کنیم.

استفاده از رمزنگاری پیشرفته

حالا که می دانیم باید توکن ها را امضا کنیم سوالی پیش می آید: با چه الگوریتمی این کار را انجام بدهیم؟ الگوریتمی که برای امضا کردن توکن ها استفاده می کنید باید یک الگوریتم قوی باشد. در وهله اول باید بدانید که الگوریتم های متقارن مانند HMAC در برابر حملات brute-force ضعیف هستند مگر آنکه کلید بسیار قوی باشد بنابراین اگر می خواهید از الگوریتم های متقارن استفاده کنید باید entropy کافی برای آن داشته باشید. من شخصا استفاده از الگوریتم های نامتقارن مانند RSA را پیشنهاد می کنم.

تاریخ انقضا

توکن های JWT پس از امضا شدن تا ابد معتبر هستند مگر آنکه تاریخ انقضایی برایشان تعریف کرده باشید. چرا؟ به دلیل اینکه پس از گذشت زمان خاصی بهتر است کاربر دوباره مجبور به login و دریافت توکن جدید شود تا شانس نشت توکن یا سوء استفاده دیگران از آن کاهش یابد. البته همیشه بهتر است که یک id خاص را برای هر توکن در نظر بگیرید تا بعدا به کاربر اجازه منقضی کردن توکن به صورت دستی را بدهید.

تنظیم issuer و audience

برای مدیریت بهتر و ساده تر توکن ها بهتر است همیشه خصوصیات issuer (صادرکننده) و audience (مخاطب یا دریافت کننده) را در توکن های خود تعریف کنید. با انجام این کار دریافت کننده توکن به راحتی می تواند متوجه شود که این توکن برای او صادر شده است یا خیر. همچنین زمانی که توکن JWT دریافت می کنید باید این دو خصوصیت در آن را اعتبارسنجی کنید تا هکری با استفاده از توکن سایت دیگری به منابع ما دسترسی پیدا نکند.

داده های حساس

از آنجایی که توکن های JWT تنها رشته های Base64 هستند، نباید داده های حساس خود را درون این توکن ها قرار بدهید. در صورتی که باید چنین کاری را انجام بدهید، حتما payload را رمزنگاری (encrypt) کنید.

توکن های امضا نشده

امضا کردن توکن ها تنها راهی است که برای تشخیص تمامیت و صحت توکن ها داریم. هکر ها می توانند توکن را قبل از رسیدن به سرور ما دریافت کرده، امضای دیجیتالی را حذف کرده و نهایتا درخواست را ویرایش کنند بنابراین هیچ گاه توکن های امضا نشده یا توکن هایی با ‘alg: “none را قبول نکنید.


منبع: وب‌سایت bbva

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.