مقدمهای بر اطلاعات آزاد
در عصر کامپیوترها، اطلاعات از مهمترین و ارزشمندترین موجودیتها هستن. در سالهای اخیر میتونید نشتهای اطلاعتی زیادی رو ببینید که خیلی از اونها ضربه سختی رو به سازمانها و کسبوکارها وارد کرده.
همیشه نشت اطلاعات اینطور نیست که مثلا اطلاعات شخصی افراد نشت پیدا کنه، گاهی اوقات اطلاعات در دسترس عموم هم ممکن هست نشت پیدا کنه. منظور از نشت اینه که مجموعهای از اطلاعات موجود هرچند آزاد، در دست یک شخص دیگهای جز ارائه دهنده قانونی اون اطلاعات باشه. برای مثال فرض کنید اطلاعات LinkedIn، تقریبا همه میتونن با ثبتنام اون رو ببینن. هدف هم به اشتراک گذاشتن رزومه افراد هست. موجودیت این اطلاعات به صورت آزاد میتونه مشکل ساز باشه وقتی برای مثال من به عنوان کاربر بتونم جستجو کنم در ماه اپریل چه اشخاصی در چه مقامی در فلان شرکت استخدام شدن. این هدفی نیست که LinkedIn براش ساخته شده. و شرکت پشت LinkedIn هم نمیخواد این چنین اتفاقاتی برای اطلاعات حساب مشتریها بیوفته. در اصل شما میتونید از LinkedIn بخواهید که اطلاعات فلان کاربر رو به من بده، ولی از اون نمیتونید بخواهید کاربرانی که در فلان ماه شروع به کار کردن رو به من بده. LinkedIn اطلاعات کاربرهارو در پایگاههایداده نگه داری میکنه و با اجازه اونها در یک فضای عمومی به اشتراک میذاره. کابر هیچ وقت توافق نکرده که از یک فیلتر مثل زمان استخدام بشه به اسم کاربر رسید. پس LinkedIn این فیلتر رو اضافه نکرده. و قطعا دوست نداره که این اتفاق هم بیوفته.
پس متوجه شدیم حفظ اطلاعات هرچند عمومی بسیار اهمیت داره. یک کسبوکار نسبت به توافقاتی که در ابتدا با یک کاربر میکنه موظف به پایبند بودن به حفظ اطلاعات هست چون اعتماد کاربران هست که ارزشمنده.
در حوزه اطلاعات آزاد برای عموم، اغلب، سرویسها یک رابط هستند برای جستوجو در پایگاهداده اون هم در چارچوب مشخص. به این معنی که قرار نیست پایگاهداده در دست همه باشه در اصل یک رابط نرمافزار وجود داره.
رباتهای وب
تا اینجا باهم درباره اهمیت حفظ اطلاعات آزاد خوندیم. و متوجه شدیم که ممکن هست یک سری اطلاعات در یک چهارچوب و برای چند هدف مشخص آزاد باشن.
اما یک دسته افراد هیچ وقت به بایدها و نبایدها اهمیت نمیدن و تلاش میکنن که نشدنیها رو انجام بدن. با گسترش اینترنت و اطلاعات آزاد، مهاجمین سایبری و استخراج کنندههای اطلاعات روزبهروز دارن زیادتر میشن.
تو مثال LinkedIn دیدیم که چطور این نرمافزار یک سری سیاست تعیین میکنه تا جستجوها در یک قالب مشخص باشه. اما همه میدونی که اگه یک شخصی بیاد و با رعایت تمام اصول و سیاستها شروع کنه و تمام کاربران LinkedIn رو چک کنه و اطلاعات اونها رو ذخیره کنه در نتیجه یک پایگاهداده داره که حالا میتونه هر نوع کاوش بدون هیچ محدودیتی روی اون انجام بده.
در دنیا نرمافزار شخص لازم نیست که خودش چندین ماه وقت بذاره و مثلا اطلاعات رو جمعآوری کنه. توسعهدهندهها به سادگی میتونن نرمافزارهایی رو بسازن که با سرعت و دقت خیلی بالاتری این کار رو انجام بده که به اونها رباتهای وب گفته میشه.
رباتهای وب در وسیعترین مفهوم برای انجام هر عمل تکراری مربوط به یک وبسرویس ساخته میشن. دقت داشته باشید رباتهای وب و یا وجودشون غیرقانونی و بد نیست و در اصل خود عمل چیزی هست که کاربرها دوستش ندارن. رباتهای وب گاهی خیلی مفید و مورد نیاز هستن.
رباتهای بد، برای اهداف مختلفی ساخته میشن. از مهمترین دلایلش میشه به جمعآوری اطلاعات از وبسایتهایی که رابط نرم افزاری (API) ارائه نمیدن یا محدودیت دارن، دیدن تبلیغات و کسب درآمد و همچنین سعی در ورود غیر مجاز به حسابها کاربران (credential stuffing) اشاره کرد.
تو این پست ما تمرکز اصلیمون روی رباتهایی هست که اطلاعات رو جمعآوری میکنن یا به اصطلاح خزش (crawl) میکنن.
دستهبندی رباتها
رباتهای وب رو میشه از براساس تواناییهاشون، سه قسمت کرد. هر کدوم ویژگیهای خودشون رو دارن و مناسب یک منظور خاصی هستن.
رباتهای ساده بر اساس درخواست HTTP
سادهترین نوع رباتهای وب، رباتهایی هستن که از کتابخانههای مبتنی بر درخواست HTTP استفاده میکنن. مثلا ماژول urllib یا requests تو Python. این نوع رباتها به منابع RAM و CPU کمتری نیاز دارن، اما قادر بارگیری صفحاتی که محتوای پویا دارن مثل وبسایتهای تکصفحهای (SPA) نیستن. چراکه این کتابخانهها نمیتونن کدهای JavaScript رو اجرا کنن. هرچند این رباتها میتونن مستقیما درخواستههای GET و POST رو انجام بدن و لازم به اجرای JavaScript نباشن.
بعلاوه، این کتابخانهها فقط محتوای Body بستههای برگشتی رو به توسعهدهنده برمیگرونه و توسعهدهنده لازم هست از کتابخانههای دیگهای مثل Beautiful Soup برای تحلیل و استخراج HTML استفاده کنن.
در زیر یک نمونه ساده رو میبینید که صفحه اول مموریلیکز رو بارگذاری میکنه و تگ H3 رو نمایش میده.
رباتهای بر اساس مروگر واقعی (Chrome, Firefox)
Selenium و Puppeteer دو چهارچوب نرمافزاری (Framework) هستن که امکان خودکار کردن کارها رو در مرورگرها میدن. مثلا بارگذاری یک صفحه، حرکت موس، تایپ کردن، کلیک کردن، و یا پیمایش صفحات. Puppeteer بیشتر برای خودکار کردن Chrome در چهارچوب NodeJS استفاده میشه، اما Selenium طیف گستردهای از مرورگرها مثل Firefox ، Chrome و Safari رو پشتیبانی میکنه. همچنین Selenium به صورت رسمی برای زبانهای برنامهنویسی و چهارچوبهای مختلفی (NodeJS, Python, Java) در دسترس هست.
برخلاف دسته اول که بر اساس کتابخانههای HTTP بودن، این دسته توانایی اجرای کدهای JavaScript رو دارن چون بر اساس یک مرورگر واقعی هستن. علاوه بر اون این نوع رباتها به منابع RAM و CPU زیادی نیازمند هستن. دقیقا مثل اجرای یک مرورگر. نکته دیگهای که درباره این رباتها وجود داره این هست که نمیشه اونها رو روی سرورهای بدون رابط گرافیکی اجرا کرد. برای رفع این مشکل توسعهدهندهها از XVFB استفاده میکنن که به عنوان یک صفحهنمایش مجازی پیاده شده با پروتکل X11 میتونه یک رابط گرافیکی رو اجرا کنه.
رباتهای بر اساس مرورگرهای Headless
در نوع سوم رباتهای وب مرورگرهای headless رو داریم. این مرورگرها تغریبا مشابه نوع دوم هستن و قابلیت اجرای کدهای JavaScript رو هم دارن. تفاوت این دسته این هست که دیگه نیازی به رابط گرافیکی و یا XVFB ندارن. عدم نیاز به رابط گرافیکی باعث شده این دسته از رباتها به طرز چشمگیری نیازمند منابع کمتری نسبت به نوع دوم باشن. این باعث شده این دسته مورد علاقه توسعهدهندههای رباتهای وب باشه.
اولین مرورگر بدون نیاز رابطه گرافیکی PhantomJS بود که بسیار محبوب بود. اما گوگل در 2017 با ارئه نسخه headless از Chrome باعث شد PhantomJS از حالت نگهداری و توسعه خارج بشه. امروزه Headless Chrome به صورت متداوم در حال توسعه و نگهداری هست.
توسعه رباتهای headless با پروتکل Chrome Devtools Protocol (CDP) انجام میشه. هرچند توسعهدادن رباتها با این پروتکل کمی دشواره برای همین چندین چهارچوب نرمافزاری دیگهای شکل گرفتن که به نحوی رابط بین توسعهدهنده و CDP باشن. یکی از این چهارچوبها Puppeteer هست. این باعث شد که مهاجرت از یک ربات از نوع دو به یک ربات بدون نیاز به رابطگرافیکی بشدت ساده بشه.
تا اینجا درباره انواع رباتها و رویکردهاشون خوندیم حالا با توجه به اطلاعاتی که داریم شروع میکنیم به مطالعه روشهای تشخیص این رباتها.
تشخیص رباتها وب
ما میتونیم تشخیص رباتهای وب رو به دو روش تقسیم کنیم:
- تشخیص از رفتار: توی این تکنیک ما رفتار های کاربر رو بررسی میکنیم مثلا حرکات ماوس یا سرعت جستجو کاربر که بتونیم تشخیص بدیم این کاربر یک انسان هست یا یک ربات.
- تشخیص از اثرانگشت (Fingerprinting): در این تکنیک ما اطلاعات مربوط به کاربر رو مورد بررسی قرار میدیم. مثلا نسخه مرورگر، سیستم عامل و یا تعداد هستههای پردازنده.
تشخیص از رفتار (Behavioral)
رویکرد این روش بر این فرضیه بنا شده که انسان و ربات به طور یکسان رفتار نمیکنه. مثلا ما میتونیم بگیم رباتها سریع تر از انسانها عمل میکنن و یا ممکن هست اصلا از ماوس استفاده نکنن. این فرضیه یک فرضیه قوی هست.
حالا شاید از خودتون بپرسید مگه امکان نداره رباتها رفتار انسانها رو تقلید کنن تا سیستم تشخیص رو دور بزنند؟ جواب اون قطعا «بله» هست اما این هم ارزشمند هست. این واقعیت که ما تونستیم رباتها رو مجبور کنیم رفتار انسانی داشته باشن خودش قدم بزرگی هست.
در روش تشخیص از رفتار ما اطلاعات رو در دو سمت Server و Client بررسی میکنیم:
ویژگیهای مورد بررسی سمت Server:
- تعداد صفحاتی که کاربر در یک نشست (Session) بازدید کرده.
- تعداد دفعات درخواست (request). تفاوت این مقدار این هست که در یک رفتار واقعی ممکن هست برای بارگذاری یک صفحه تعداد زیادی درخواست به سمت Server بیاد اما در رفتار رباتها اغلب تعداد درخواستها خیلی پایین تر هست.
- ترتیب صفحاتی که کاربر مشاهده کرده. برای مثال اگه صفحات ما شناسه عددی دارن و کاربر از الگوی مشخصی برای درخواست اون صفحات استفاده کرده باشه احتمال ربات بودن اون کاربر بیشتر هست.
- میانگین زمان درخواست دو صفحه متفاوت توسط کاربر. این مورد میتونه خیلی کمک کنه و از سرعت رباتها کم کنه و اون هارو توی باتلاق گیر بندازه.
- نوع منابع درخواستی هم میتونه روی تصمیم سیستم تشخیص تاثیر بذاره. رباتها ممکن هست علاقهای به بارگذاری منابعی مثل تصاویر، کدهای CSS و یا موارد دیگه نداشته باشن به این علت که این منابع میتونه پهنایباند رو اشغال کنه و در نتیجه هم مورد استفاده قرار نگیره.
ویژگیهای مورد بررسی سمت Client:
منبع دیگه برای بررسی ویژگیهای رفتاری، اطلاعات جمعآوری شده از مرورگر هست. این موارد شامل حرکات و کلیکهای ماوس، پیمایش صفحه و یا ورودیهای صفحهکلید هست. تمام این اطلاعات رو میشه با JavaScript جمعآوری کرد:
تمام این اطلاعات جمع شده از Server و Client بعد از جمعآوری در یک روند یادگیری ماشین استفاده میشن تا ماشینها یاد بگیرن که انسانها رو از رباتها تمیز کنن. یکی از مشکلهای این روش نیاز وجود به این اطلاعات و توسعه ماشینهای هوشمند در وهله اول هست.
علاوه براین پایه این تکنیک بررسی کاربر در طول یک نشست هست که معمولا با cookieها انجام میشه. اما از اونجا که cookieها به راحتی حذف میشن بهتره که این رفتارها با توجه به آدرس IP بررسی بشن. هرچند سرویسهایی وجود دارن که proxyهای چرخشی ارائه میدن و رباتها عملا در هر درخواست یک آدرس متفاوتی دارن. برای این مشکل هم سرویسهای موجود هستن که با توجه به گزارشها و ترافیک اینترنت یک دسته از آدرسهای IP رو به عنوان پراکسی گزارش میکنن و میتونن به روند تشخیص رباتهای وب سرعت ببخشن.
تشخیص از اثرانگشت (Fingerprinting)
تکنیک بعدی تشخیص رباتها استفاده از هرآنچیزی هست که ما به اونها ویژگیهای کاربر میگیم. این موارد بعد از ترکیب شدن، یک اثرانگشت برای هر کاربر تعیین میکنن. اثرانگشت میتونه در چند زمینه استفاده بشه؛ برای مثال یک سازوکار برای تولید cookie.
اثرانگشتها به غیر از تشخیص ربات بسیار مفید هستن. برای مثال میتونن در تشخیص نشستهای دزدیدهشده (hijacked) کمک کنن. به این صورت که از اثر انگشت برای تایید session استفاده کنن (با توجه به پیاده سازی نشست بر پایه اثرانگشت). برای اطلاعات بیشتر در این زمینه به لینک زیر مراجعه کنید:
https://hal.inria.fr/hal-01652021
در این سازوکار تشخیص، ما بسیار محتاط عمل میکنیم و فرض رو بر این میذاریم که مهاجم مقادیر تشکیل دهنده اثر انگشت رو کنترل میکنه. به همین منظور سعی میکنیم تعداد زیادی از این ویژگیهارو جمع آوری کنیم تا دقت تولید اثر انگشت رو بیشتر کنیم. مشاهده مغایرت در اثرانگشت احتمال ربات بودن کاربر رو بالا میبره.
برای اطلاعات بیشتر در رابطه با این موضوع میتونید به این مقاله مراجعه کنید:
https://www.usenix.org/system/files/conference/woot14/woot14-ho.pdf
اثر انگشت مرورگر
تولید یک اثرانگشت از یک مرورگر با استفاده از کدهای JavaScript و هدرهای HTTP که سمت سرور فرستاده میشه انجام میشه. ایده این هست که اطلاعات ماشین، سیستمعامل و مرورگر جمع آوری میشه و بعد سمت Server ارسال میشه. در این مرحله Server میتونه تا حدی تشخیص بده که آیا این اثرانگشت متعلق به ربات شناختهشدهای هست یا اینکه اثرانگشت ویرایش شده یا نه و آیا مغایرتی بین ویژگیهای اثرانگشت وجود داره؟ (برای مثال نوع سیستمعامل گزارش شده توسط JavaScript با نوع سیستمعامل در User-Agent تفاوت داره).
روشهای زیادی برای بررسی اثرانگشتها توسعه داده شده برای مثال ویژگیهای مرورگر در برابر نسخه مرورگر قرار میگیره و بررسی میشه آیا این نسخه ازمرورگر این ویژگیها رو داره؟ برای مثال در اثرانگشت ما میتونیم تشخیص بدیم آیا کاربر روی ماشینهای مجازی هست یا نه. علت بررسی این ویژگی این هست که اغلب کاربران واقعی از ماشینهای مجازی برای جستجو استفاده نمیکنن و در صورت مشاهده این موارد میتونیم از کاربر بخواهیم که یک CAPTCHA رو حل کنه تا اطمینان حاصل کنیم که کاربر یک انسان هست.
نتیجهگیری
در این مقاله درباره اهمیت محافظت از اطلاعات آزاد خوندیم و بررسی کردیم که رباتهای وب چه رویکردهایی دارن و ما چطور میتونیم از وبسایتمون محافظت کنیم.
یک نکته مهم، درک این واقعیت هست که هیچ کدوم از این سازوکارها بهترین نیستن و به تنهایی نمیتونن جلوی رباتهارو بگیرن و باید یادمون باشه که مهاجم همیشه یک قدم از ما جلوتر هست.حتی روشهایی مثل CAPTCHA با استفاده از یادگیری ماشین توسط رباتها قابل حل هست. هرچند روشهای مطمئنتری هم برای حل CAPTCHA وجود داره؛ برای مثال در کشورهای با جمعیت بالا مثل هند مکانهایی وجود داره که به اونها worker pool گفته میشه. در این مکانها انسانها در ازای مبلغ ناچیزی کارهایی مثل بازدید و یا حل CAPTCHA رو انجام میدن. این باعث شده امروزه با CAPTCHAهایی روبهرو بشیم که بسیار سختتر شدن و این واقعیت که «امنیت یک شمشیر دو سر هست» خودش رو نشون میده. این روند تا جایی پیشرفت میکنه که شاید حل CAPTCHAها برای انسان تغریبا غیر ممکن بشه. بهترین رویکرد، استفاده و همپوشانی روشهای مختلف هست تا بتونیم تا حد ممکن جلوی رباتهای وب رو بگیریم.
اما خیلی از روشها نیاز به هزینه بالایی داره و از لحاظ مهندسی در بسیاری از موارد ارزش پیاده سازی رو نداره. برای این مشکل سرویسهای زیادی مثل Datadome توسعه داده شده که به مشتریهای خودش سرویس تشخیص ربات ارائه میده.
مطالبی که می نویسم صرفا خلاصه مطالعه RFC ها و کتابهای معروفه که همتون میشناسید. و هیچ کدوم از این ها کشفیات خودم نبوده و نیست. خوشحال میشم نقد کنید و اگه موردی از نظرتون درست نبود بهم بگید.
راه ارتباطی با من معمولا aggr3ssor@protonmail.com هست و در توییتر با 0xc0d میتونید منو پیدا کنید.
مطلب جالبی بود. ایرادات کوچکی هم وجود داره:
اما همه میدونی
رباتهای وب در وسیعترین مفوهم
و لاز به اجرای JavaScript نباشن.
یک رفتار واقی ممکن هست
تا ماشینها یا دبگیرن
ممنون بابت دقت نظرتون =)