info[at]nsec.ir
(+۹۸)-۳۱-۳۳۹۱۵۳۳۶

امنیت SAML

SAML چیست؟

SAML مخفف عبارت Security Assertion Markup Language است. این یک استاندارد باز مبتنی بر XML برای انتقال داده‌های هویتی بین دو طرف است: ارائه دهنده هویت (IdP) و ارائه دهنده خدمات (SP).

SAML غالباً برای ورود به سیستم (ورود به سیستم با Google ، ورود به سیستم با Twitter و ... ) استفاده می شود. به این معنی که وقتی می خواهید به example.com وارد شوید؛ example.com می تواند به یک ارائه دهنده احراز هویت خارجی اعتماد کرده و از آن برای تأیید هویت کاربری شما استفاده کند. SAML در مورد انتقال این احراز هویت و جزئیات هویت در مرزهای سازمان (دامنه‌های وب) است.

مزایای احراز هویت SAML

بهبود تجربه کاربری - کاربران برای دسترسی به چندین ارائه‌دهنده خدمات فقط باید یک بار وارد سیستم شوند. این امر باعث می‌شود تا فرآیند احراز هویت سریع‌تر صورت پذیرد و انتظار کمتری از کاربر برای به خاطر سپردن اطلاعات متعدد ورود به سیستم برای هر برنامه وجود داشته باشد.

افزایش امنیت - SAML یک نقطه احراز هویت را ارائه می‌دهد. سپس، SAML اطلاعات هویت را به ارائه‌دهندگان خدمات منتقل می کند. این نوع احراز هویت اطمینان می دهد که اعتبارنامه ها فقط به طور مستقیم به IDP ارسال می شوند.

اتصال شل دایرکتوری‌ها -  SAML نیازی به نگهداری و همگام‌سازی اطلاعات کاربر بین دایرکتوری‌ها ندارد.

کاهش هزینه ها برای ارائه دهندگان خدمات -  با SAML ، لازم نیست اطلاعات حساب را در چندین سرویس حفظ کنید. تنها ارائه‌دهنده هویت این بار را بر دوش می کشد.

 

چرا مهم است؟

SAML در مکان های زیادی استفاده می شود؛ بنابراین با احتمال زیادی امنیت شما را نیز تحت تأثیر قرار می‌دهد. SAML اخیراً دارای آسیب پذیری های فاجعه‌بار با تأثیر زیاد بوده است. به عنوان مثال، اکثر خدمات دولتی از جمله خدمات مالیاتی و سیستم‌های ثبت پرونده سلامت در فنلاند به گونه‌ای آسیب‌پذیر بودند که مهاجم می‎توانست اظهارات مالیاتی افراد را جاسوسی کند و پرونده های بهداشتی و اساساً هر چیزی که به صورت آنلاین در دسترس دولت بود را بخواند. این امر تا حد زیادی توسط رسانه‌ها نادیده گرفته شده است؛ شاید به این دلیل که هنوز از آسیب‌پذیری ها سوءاستفاده نشده‌ است.

 

SAML چگونه کار می کند؟

یک فرایند احراز هویت معمولی SSO شامل این سه طرف است:

  • طرف اصلی : که تقریباً همیشه یک کاربر انسانی است که سعی می کند به یک برنامه میزبانی‌شده دسترسی پیدا کند.
  • ارائه دهنده هویت : یک سرویس نرم افزاری ابری است که هویت کاربر را ذخیره و تأیید می کند: معمولاً از طریق ورود به سیستم. اساساً نقش IdP این است که بگوید: «من این شخص را می شناسم و در اینجا کاری است که او مجاز به انجام آن است».
  • ارائه دهنده خدمات : همان برنامه یا سرویسی است که کاربر می خواهد از آن استفاده کند. نمونه های رایج شامل سیستم عامل‌های ایمیل ابری مانند Gmail و Microsoft Office365  ، خدمات ذخیره سازی ابری مانند Google Drive و برنامه های ارتباطی مانند Slack و Skype است. معمولاً یک کاربر فقط به طور مستقیم وارد این خدمات می شود؛ اما وقتی از SSO استفاده می شود؛ کاربر به جای آن وارد SSO می شود و SAML برای دسترسی مستقیم به آنها استفاده می شود.

 

چرا SAML ناامن است؟

SAML  از امضای مبتنی بر مقادیر محاسبه‌شده استفاده می‌کند. این کار، ذاتاً ناامن است و بنابراین SAML  از نظر  طراحی ناامن است.

چرا امضای مقادیر محاسبه شده خطرناک است؟

به طور خلاصه، هنگامی که امنیت خود را بر اساس برخی از ویژگی های محاسبه شده بنا می‌کنید؛ مهاجم می‌تواند از هر گونه نقص، اختلاف و ابهام در این محاسبه استفاده کند. جالب آن که هرچه محاسبات پیچیده‌تر باشد؛ خطرناک‌تر می‌شود و محاسبه امضای SAML بسیار پیچیده است.

 

اما بیایید به توضیح مفهوم بپردازیم. بیایید یک سند هویت شبهSAML تهیه کنیم:

ما می توانیم فایل فوق را فقط به عنوان یک دسته بایت امضا کنیم:

حال اگر فایل را کمی تغییر دهیم. متوجه می شویم که امضا تغییر می کند:

این ویژگی بسیار خوبی است زیرا در حالت ایده‌آل می خواهیم هرگونه تغییر (حتی آن‌هایی که در سطح JSON بی معنی تلقی می شوند) در سند امنیتی مهم (که SAML است) امضای متفاوتی ایجاد کند. حال اگر دو قطعه کد متفاوت داشته باشید که سند SAML را پردازش می‌کنند و تفسیر و رفتار متفاوتی در رابطه با محتوای معنایی پیام های تکراری JSON دارند ، چه اتفاقی می افتد؟

یک مهاجم از ارائه‌دهنده هویت خواسته است تأییدی را برای او امضا کند؛ اما به دلیل شکل‌پذیری SAML او توانست به تفاوت‌های مفسر حمله کرده و سند را دستکاری کند تا همچنان برای اعتبارسنجی امضا معتبر باشد اما به عنوان کاربر دیگری دسترسی داشته باشد.

 

 

آسیب‌پذیری SAML در عمل

آنچه در مورد این آسیب پذیری های SAML اتفاق افتاده است؛ به آسانی مانند مثال JSON ما نیست. اما اصل و اساس این آسیب‌پذیری‌ها و علت اصلی آنها امضای مقادیر محاسبه شده و شکل پذیری است. بیشتر آن که سایر آسیب‌پذیری‌های SAML به دلیل ناپایداری رفت و برگشت XML است.

به طور خلاصه این آسیب‌پذیری ناشی از تجزیه XML است -> نوشتن XML سند معنایی متفاوتی تولید می کند؛ به عبارت دیگر کدگذاری (رمزگشایی (xmlDocument‏))! = xmlDocument).

 

چرا SAML اینگونه طراحی شده است ؟

با فرض اینکه طراحان SAML می دانستند به کارگیری روش‌هایی با انعطاف‌پذیری کمتر در طراحی این پروتکل بهتر است با این حال در طراحی آن از روش هایی با قابلیت انعطاف‌پذیری بالا استفاده کرده‌اند.

در این پروتکل زمانی که کاربر یک امضا  ایجاد می کند؛ خروجی به عنوان signature بصورت زیر دریافت می کند:

ارسال signature به تنهایی کافی نیست و باید به همراه contentToSign  ارسال شود تا کاربر با تطبیق آن ها از صحت اطلاعات خروجی اطمینان حاصل کند.

به نظر می آید ارسال contentToSign  به تنهایی منجر به طراحی با قابلیت انعطاف کمتر می شود.  در این حالت طراحان SAML  می بایست SAML document و signature را در دو فایل جداگانه ارسال می کردند ( احتمالا signature را از طریق HTTP header و یا پارامتر های URL ارسال می کردند.)

با این حال طراحان SAML   تصمیم گرفتند برای سادگی بیشتر، کلیه ی اطلاعات را در یک فایل XML   جا داده و ارسال کنند:

از نظر فنی ، در ساختار فوق  signature  پایین تر از contentToSign قرار گرفته است و این نحوه  قرارگیری ایجاب می کند که signature در فرآیند ارزیابی نادیده گرفته شود!

در عمل در ساختار فوق از گنجاندن signature  در contentToSign خودداری شده است؛  چرا که منجر به شکل‌گیری مشکلات فنی غیر قابل بازگشت می شود :

در بررسی ساختار ساده‌تر که signature در contentTosign گنجانده نشده است؛ می خواهیم امکان پیاده‌سازی فرایند ارزیابی signature به صورت byte-based را بررسی کنیم!

مشکل موجود این است که فرایند استخراج بایت های متعلق به contentToSign  از فایل XML  بسیار دشوار است چرا که این ویژگی توسط API هایی که به عنوان XML parser عمل می کنند، پشتیبانی نمی شود. این در حالی‌ست که در  samldocument  برای دسترسی  به زیر شاخه ی contentTosign  تنها امکان دسترسی سطح  XML توسط طراحان فراهم شده است؛ که البته به نظر می رسد دقت لازم را بکار نگرفته‌اند و برای آسودگی به امضای داده سطح XML رضایت داده‌اند.

در واقع ، امضای خروجی عملیات واکاوی XML  ‪(XML parsing)‬ دشوار است چرا که باید نهایت دقت به کار گرفته شود که امضای ورودی (input signature) از خروجی عملیات واکاوی XML  مستقل نگه داشته شود؛  چراکه خروجی عملیات واکاوی بسته به نوع کتابخانه‌ها و زبان های برنامه نویسی به کار گرفته شده، می تواند متفاوت باشد. با توجه به دلایل فوق ،  ابزار  XML dsig  به منظور پردازش خروجی XML بکار گرفته می شود. کتابخانه ی مورد نظر  این امکان را فراهم می کند که با مرتب سازی attributeهای فایل XML ،  به چینش  پایداری از بایت ها دست پیدا کنیم و به این ترتیب امکان ارزیابی امضای ورودی فراهم شود؛ چرا که نهایتاً فرایند ارزیابی byte-based خواهد بود.

در ادامه مثالی برای درک بیشتر تغییر صورت‌گرفته توسط این کتابخانه در الگوی چینش بایت آورده شده است:

که می‌شود:

به صورت خلاصه  امضا و اعتبارسنجیِ زیرشاخه‌های فایل های XML دشوار است با این حال روش ها و ابزارهایی وجود دارند که این امکان را فراهم می کنند و شواهد تجربی نشان می‌دهد که این یک کابوس امنیتی است و به نظر می‌رسد کلیه پروتکل‌هایی که مبتنی بر روش‌هایی مشابه پروتکل SAML  فعالیت می کنند در معرض آسیب‌پذیری شدید امنیتی قرار دارند.

 

کاهش آسیب پذیری

برای رعایت  احتیاط در مسائل امنیتی می بایست فرایند ارزیابی پایداری  پیش از پردازش فایل XML صورت پذیرد. به‌طور خلاصه برای ارزیابی امضا بجای استفاده از روش های ارزیابی byte-based  باید مراحل زیر طی شود :

- ارزیابی پایداری round-trip  

- انجام مجدد واکاوی فایل XML 

- ایجاد canonical XML  ( با استفاده از XML design عملیات رمز کردن مجدد ولی این بار با قوانین و تبدیلات پیچیده‌تر صورت می گیرد.)

همانطور که بنظر می رسد مراحل فوق پیچیده هستند و همین پیچیدگی احتمال وجود خطا ها و مشکلات امنیتی را افزایش می دهد.

 

چگونه SAML می توانست بهتر طراحی شود ؟

به عنوان یک ایده ی ساده می توان به مثال زیر اشاره کرد.

به جای استفاده از ساختار زیر که امکان  امضا و اعتبارسنجی آن به صورت امن و دقیق دشوار است :

می توان از ساختار جایگزین زیر استفاده کرد که در آن محتوای تگ <Assertion> را serialize کرده و به صورت مجموعه‌ای از بایت ها در آورده و به فرمت base64 یا فرمت های مشابه ذخیره می‌کنیم. بدین‌ترتیب می‌توانیم آن‌ها را به صورت مجموعه‌ای از بایت‌ها انتقال دهیم و پس از تایید signature فقط عملیات XML-parse را بر روی آن انجام دهیم :

به این ترتیب کلیه محتوای خروجی مورد نظر در یک فایل ارسال می شود و نیازی به ارسال  signature و contentToSign به صورت جداگانه وجود ندارد ولی می بایست دو مرحله XML-parse صورت گیرد :

در مرحله اول : بر روی document خروجی و سپس ارزیابی اعتبار امضا

در مرحله دوم : بر روی document داخلی در صورت تطابق امضا

اگرچه ساختار پیشنهادی از نظر ظاهری ، ساختار چندان مطلوب به نظر نمی رسد؛ اما مزیت‌های مهمی ایجاد می‌کند از جمله اینکه با جا دادن کلیه  محتوای خروجی در SAMLContentToSign  دارای انعطاف کمتری است همچنین نیاز به بکارگیری XML dsig  و واکاوی داده‌های ضروری امنیتی پیش از تایید شدن از سمت منبع وجود ندارد .

 

از دیگر ویژگی های غیر عادی SAML :

SAML در مواردی کاربران را ملزم به استفاده از XML document هایی می‌کند که دربردارنده مجموعه‌ای از داده‌های ناایمن هستند که ممکن است تحت کنترل مهاجمان سایبری باشند. در این موارد کاربر نیاز به بکارگیری کد‌های اضافه برای دور انداختن داده‌های ناایمن دارد.

 

چرا SMAL با وجود اشکلات امنیتی فراوان همچنان مورد استفاده قرار می گیرد ؟

یکی از پاسخ ها می تواند این باشد که زمانی که پروتکلی قدرت را به دست می‌گیرد و کابران بسیاری را یا خود همراه می کند؛ مهاجرت کاربران به گزینه‌های بهتری که ممکن است پس از آن ارائه شود، دشوار خواهد بود و تطابق با استاندارد جدید هزینه‌هایی را برای کابران در پی خواهد داشت که اغلب از آن سر باز می‌زنند.

 

پیشنهاد‌های جایگزین برای SAML :

برخی کارشناسان OAuth2 و OpenID connect  را پیشنهاد می‌کنند :