PDA

View Full Version : گفتگو: روش های حفظ امنیت در سرویس های اینترنتی



alismith
پنج شنبه 25 اسفند 1390, 19:42 عصر
سلام

دوستان برای حفظ امنیت در سرویس هایی که نیاز به عملیات login نیست چه نظری دارید؟

فرض کنید ما سرویسی داریم که یک فرم در اختیار کاربر قرار میده تا در وب سایت یا بلاگش بذاره تا کاربران اون سایت اطلاعاتی رو از طریق این فرمها بفرستند تا در سرور ما که ارائه دهنده این سرویس هست ذخیره بشند

در گام اول مدیر سایت یه بلاگ در سایت ما عضو میشه
در گام دوم بعد از چند مرحله یک اسکریپت که فراخان یک فایل js هست به کاربر داده میشود

فایل js در هرجایی که قرار بگیرد یک فرم با آدرسی مشخص برای ارسال اطلاعات به سرور ما درست می کند و نمایش می دهد

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

روشها:
1- استفاده از یک کلید و رشته یکتا در فرم که هنگام ارسال اطلاعات با مقدار ذخیره شده در سرویس دهنده بررسی بشه، البته این مقدار با هر بار Refresh سایت کابر و فراخوانی دوباره اون فایل js تغییر خواهد کرد ولی باز این روش امنیت کامل رو برقرار نمیکنه، و میشه ارسال های جعلی از این فرم برای حسابی که مدیر سایت در سرویس ما ساخته فرستاد در حالی که این اطلاعات از سایت اصلی کاربر ارسال نشده!
2- آدرس سایت کاربری که از سرویس ما استفاده می کنه (مدیر سایت یا بلاگ) را در مثلا پروفایل کابر به عنوان اطلاعات ضروری ذخیره کنیم تا بعد که فرم با username این کاربر ارسال شد بررسی کنیم که درخواست از سایت مربوطه بوده یا از مکان دیگری به سرور ما ارجاع داده شده، که باز نمیدونم پیاده سازی این روش و حفظ امنیت و کارایی آن تا چه حد ممکن و قابل اعتماد است!

ممنون میشم ایده های خودتون رو مطرح کنید...


با تشکر-موفق باشید

eshpilen
جمعه 26 اسفند 1390, 23:33 عصر
منظورت اینه که بازدیدکنندگان اون سایتی که از فرم شما استفاده میکنه نتونن از راهی غیر از فرم موجود در صفحات اون سایت به سایت شما اطلاعات مورد نظر رو ارسال کنن؟

alismith
شنبه 27 اسفند 1390, 01:40 صبح
منظورت اینه که بازدیدکنندگان اون سایتی که از فرم شما استفاده میکنه نتونن از راهی غیر از فرم موجود در صفحات اون سایت به سایت شما اطلاعات مورد نظر رو ارسال کنن؟

بله دقیقا مهندس

البته اگر در ارسال اطلاعات از سایت کاربر به سرور ارائه دهنده سرویس و کلا پیاده سازی این مدل سرویس ها نکات امنیتی ای میبینید که لازمه رعایت بشه، لطفا بیان کنید



خیلی ممنون

eshpilen
شنبه 27 اسفند 1390, 08:49 صبح
بنظرم میشه چنین کاری کرد که فقط فرمهایی که از طریق سایت مورد نظر لود شدن پذیرفته بشن.
اما فقط با جاوااسکریپت و HTML نمیشه و باید سمت سرور هم یک کد PHP داشته باشه.
ضمنا مسلمه که اعتبار این روش بر پایهء اعتماد به مالک سایت مورد نظره. چون در این روش از کلید محرمانه ای که برای هر سایت طرف قرارداد تولید شده استفاده میشه که هرکس این کلید رو داشته باشه بنابراین میتونه درخواستهای جعلی هم ارسال کنه. بنابراین شما دارید به مالک/ادمین سایت طرف قرارداد اعتماد میکنید که این کلید رو در اختیار کس دیگری قرار نده و ازش سوء استفاده نکنه. ضمنا اگر کلید به هر صورتی سرقت بشه طبیعتا دیگه امنیتی وجود نداره (مگر اینکه این قضیه فاش و اون کلید باطل بشه و کلید جدید دیگری تخصیص داده بشه).

از طرف دیگه شما هیچوقت نمیتونید مطمئن بشید که سمت کلاینت واقعا یک مرورگر صفحه رو لود کرده و یک برنامهء دیگری نیست. چون مرورگر هم یک برنامه هست مثل برنامه های دیگه و هر برنامهء دیگری هم میتونه رفتار مرورگر رو شبیه سازی کنه. اما اگر میخواید اطمینان بیشتری باشه که طرفی که فرم رو ارسال کرده انسان باشه و نه یک برنامهء خودکار، باید در فرم مورد نظر یک کپچا هم باشه.

پس دوتا قضیه شد:

1) اطمینان از اینکه فرمی که ارسال شده، از طریق سایت مورد نظر توسط کلاینت دریافت شده.
همونطور که گفتم در این روش از یک کلید محرمانه برای هر سایت طرف قرارداد استفاده میکنیم. اگر خواستید بعدا الگوریتمش رو مطرح میکنم.
اما این گزینه به تنهایی اطمینان نمیده که فرم توسط یک انسان پست شده باشه. یعنی ممکنه یک برنامهء خودکار فرم رو از سایت طرف قرارداد شما دریافت کرده و سپس بطور خودکار فیلدهای اون رو پر و ارسال کرده.

2) اطمینان از اینکه فرم توسط یک انسان ارسال شده (یا حداقل یک انسان بصورتی در مراحل ارسال اون نقش داشته). این کار با کپچا قابل انجام هست که حداکثر امنیتش بستگی به میزان امنیت کپچا داره. چون خیلی کپچاها کرک شدن و وضع هر روز بدتر میشه و از طرف دیگر تاجاییکه میدونم سرویسهای پولی کرک کپچا هم وجود داشتن که درواقع یک عده آدم نشستن پشت رایانه و با دریافت مبلغ کمی بابت هر کپچا اون رو میخونن!

تنها چیزی که نمیتونیم کاری براش بکنیم (یا راه راحت و سرراستی نداره - یا الان به ذهن بنده نمیرسه) اینه که بتونیم مطمئن باشیم تمام این عملیات تحت یک مرورگر واقعی در سمت کلاینت انجام شدن. چون همونطور که گفتم میشه رفتار مرورگر رو توسط برنامه های دیگر هم شبیه سازی کرد.

alismith
شنبه 27 اسفند 1390, 16:01 عصر
به نکات خوبی اشاره کردید دوست عزیز، استفاده از کلید محرمانه و کپچا

اما چیزی که الان جای بحث داره اینکه چطوری از این کلید استفاده کنیم تا امنیت آن در سایت سرویس گیرنده و سرویس دهنده حفظ بشه؟

فرض کنید ما یک سایت داریم و براش یک comment service نوشتیم که قراره برای حفظ امنیت اون از کپچا و یک کلید محرمانه رندوم استفاده کنیم که در هربار استفاده از این سرویس توسط کاربران مقادیر آنها تغییر می کنند، در اینجا اگه سرویس ما برپایه Ajax کار کنه چطوری باید امنیت خود کپچا و اون کلید رندوم رو حفظ کنیم که کسی نتونه غیر مستقیم و روشهای دیگه ای بهشون دسترسی داشته باشه؟ کلا در این سرویس ها که بیشتر از js استفاده می کنند و بخش عمده کار در سمت کلاینت انجام میشه، حفظ امنیت و اطمینان از صحت داده های ارسالی کار مشکلیه!

به نظر شما در پیاده سازی یک comment service که بر مبنای Ajax کار می کنه چه کارهایی لازمه تا امنیت آن حفظ بشه، مثلا کسی نتونه از این فرمها استفاده غیر مجاز کنه و ارسال های جعلی داشته باشه؟

حالا اینجا ما به سرور هم دسترسی داریم، در سرویس قبلی که گفتم، در سمت کلاینت فقط باید به یک فایل js اکتفا می کردیم!

ممنون میشم هم نظرتون رو بگید هم اینکه اگر برای پیاده سازی این سرویس و حفظ امنیت اون ایده ای دارید ذکر کنید، تا اگه بعد بحث جالب تر و حرفه ای تر شد (البته با کمک شما) به کد نویسی هم بپردازیم



با تشکر

eshpilen
شنبه 27 اسفند 1390, 22:31 عصر
من نمیدونم منظورت از comment service دقیقا چیه. چون تاحالا استفاده نکردم و چیزی راجع بهش نخوندم.
البته تاجاییکه شنیدم سرویسهای آنلاین هستن که امکان کامنت رو در اختیار سایتهای دیگه قرار میدن، ولی جزییاتشون رو نمیدونم.

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

شما گفتید:

فرض کنید ما سرویسی داریم که یک فرم در اختیار کاربر قرار میده تا در وب سایت یا بلاگش بذاره تا کاربران اون سایت اطلاعاتی رو از طریق این فرمها بفرستند تا در سرور ما که ارائه دهنده این سرویس هست ذخیره بشند

در گام اول مدیر سایت یه بلاگ در سایت ما عضو میشه
در گام دوم بعد از چند مرحله یک اسکریپت که فراخان یک فایل js هست به کاربر داده میشود

فایل js در هرجایی که قرار بگیرد یک فرم با آدرسی مشخص برای ارسال اطلاعات به سرور ما درست می کند و نمایش می دهد

الان باید ببینیم چه روشهای امنیتی ای پیاده سازی کنیم تا این فرمها که می تونند در خیلی از سایتها و بلاگها باشند، فقط توسط کاربران حقیقی به سرویس ما ارسال شوند
گفتید کاربران حقیقی.
منظور از کاربران حقیقی دقیقا چیه؟
اگر منظورتون اطمینان از انسان بودن ارسال کنندهء فرم هست، جوابش استفاده از کپچا است.
البته امنیت کپچا الان خودش خیلی خدشه داره و صرفا بهترین و عملی ترین راه در دسترس هست، نه راه کاملا یا حتی خیلی امن. ضمنا کپچا در نهایت فقط نشون میده یک انسان حداقل در یک مرحله از عملیات دخالت داشته. اینکه چطور و تا چه حد دیگه نمیشه فهمید. مثلا ممکنه فقط خوندن کپچا رو یک انسان انجام داده باشه و بقیهء موارد مثل دریافت و ارسال و حتی پر کردن محتویات فرم توسط یک برنامهء خودکار انجام شده باشه. نمیشه تضمین کرد که کاربر حتما یک کاربر عادی بوده که کل سایت رو در یک مرورگر لود کرده و دیده. شاید فقط کسی بوده که کپچا رو دیده و خونده و در اختیار برنامهء خودکار گذاشته.

اما کپچا به تنهایی تضمین نمیکنه که فرمی که ارسال شده از طریق سایت مورد نظر شما لود شده بوده.
برای اینکه از این امر مطمئن بشیم هم راه وجود داره، اما باهاش فقط میشه گفت که اون فرم از طریق فلان سایت مورد نظر به دست کلاینتی که فرم رو ارسال میکنه رسیده. باز اینکه این کار تحت یک مرورگر و تمام مراحلش بصورت دستی انجام شده باشن و کاربر مطالب سایت رو دیده باشه قابل تضمین نیست. شاید یک برنامهء خودکار بوده که فرم رو از سایت مورد نظر لود کرده (و هر بخش دیگری رو که لازم بوده). اما حداقل در این حالت اگر اون سایت فقط به کاربران عضو اجازهء ارسال کامنت داده باشه، میشه مطمئن بود که فرم مورد نظر توسط یک کاربر احراز هویت شدهء اون سایت لود شده بوده. بنظرم تنها مزیتی که داره همینه!

بطور کلی بنظرم هیچ راهی وجود نداره که بتونی مطمئن باشی یک بازدیدکنندهء عادی با یک مرورگر استاندارد سایت مورد نظر رو باز کرده و فرم رو دستی پر و ارسال کرده.
فقط با استفاده از کپچا و کلید محرمانه میتونی از دو چیز تاحدی مطمئن بشی:
1) یک انسان در عملیاتی که منجر به ارسال فرم مورد نظر شده دخالت مستقیم داشته.
2) فرم ارسال شده از طریق سایت مورد نظر دریافت شده بوده (که ممکنه این رو فقط به کاربران عضو خودش یا با هر معیار دیگری که داشته محدود کرده باشه).

در ضمن گذشته از این موارد که قبلا هم مطرح کردم، در گام اول گفتید مدیر سایت یک وبلاگ در سایت شما عضو میشه. خب چطور از این قضیه اطمینان حاصل میکنید بنظر خودتون؟ از کجا معلوم اونی که ثبت نام کرده واقعا مدیر اون وبلاگ بوده؟ شاید یک اسپمر بوده باشه که ثبت نام کرده و صرفا میخواسته کلید محرمانه ای رو از سیستم بگیره تا بتونه باهاش دیتابیس comment service شما رو پر کنه (البته بنظرم احتمالا محدودیتی روی تعداد کامنت در واحد زمان میذارن، ولی این قضیه رو بطور کلی رفع نمیکنه و طرف میتونه تعداد بیشتر اکانت ایجاد کنه).
یک راه برای این قضیه اینه که با دخالت خودتون از هویت طرف مطلع بشید. یعنی از یک راهی هویت طرف رو خودتون بررسی کنید و مطمئن بشید اونی که ثبت نام کرده واقعا مدیر سایت مورد نظر بوده. یا شاید با مراجعه به سایت مورد نظر و دیدن اینکه فرم مورد نظر با کلید مربوطه در اون سایت درج شده از این مسئله مطمئن بشید. یا اینکه بگید یک فایل مثلا با اسم dh5m8xksas.txt رو در ریشهء سایت خودش قرار بده و بعد شما وجود اون فایل رو چک کنید تا مطمئن بشید طرف واقعا به اون سایت دسترسی داره.
دوما اومدیم و یکی واقعا مالک یک سایتی هم بود اما بازم قصد سوء استفاده داشت یا یک هکر کلید رو سرقت کرد و بعدا از کلید محرمانه برای پر کردن دیتابیس شما یا اسپم سایت مورد نظر سوء استفاده کرد.

alismith
یک شنبه 28 اسفند 1390, 14:46 عصر
منظور از کاربران حقیقی دقیقا چیه؟
اگر منظورتون اطمینان از انسان بودن ارسال کنندهء فرم هست، جوابش استفاده از کپچا است.

کاربرانی که به وب سایت ما می آیند.

به نظر شما در comment service استفاده از


$_SERVER['HTTP_REFERER']

برای اطمینان از اینکه فرم از سایت ما ارسال شده و با استفاده از کپچا بدون محدود کردن کاربران به عضویت برای ارسال نظر، تا چه حد منطقی و مناسب هستش؟

خود شما اگه یک cms برای خودتون طراحی کنید و برای بخش نظرات اون اگر بخاین هم با Ajax کار کنه هم کاربر پسند باشه و هم سهولت دسترسی بهش بدید و مثلا نیاز به login نداشته باشه، چه تدابیر امنیتی ای لحاظ می کنید؟


با تشکر

eshpilen
یک شنبه 28 اسفند 1390, 22:18 عصر
HTTP_REFERER براحتی قابل جعل است.

برای اطمینان از اینکه فرم مورد نظر از سایت مورد نظر دریافت شده بوده دو راه بنظرم میرسه:

1) استفاده از کلید محرمانه به ازای هر سایت (که قبلا گفتم).
البته با الگوریتم خاصی اساسا مشابه Challenge-Response هر بار یک کلید مشتق شدهء جدید برای هر فرم تولید میشه و کلید محرمانهء اصلی هیچوقت به سمت کلاینت ارسال نمیشه، چون در اون صورت دیگه امنیتی وجود نداره و کلاینت هم کلید محرمانه رو داره. بنابراین ما کلیدهای مشتق شدهء یک بار مصرف برای هر فرم تولید میکنیم.

2) فرم به خود سایت مورد نظر پست بشه و نه comment service، بعد سایت مورد نظر اطلاعات پست شده رو بدون اینکه ذخیره کنه به comment service ارسال میکنه (توسط سوکت).
بنابراین سرور comment service میتونه IP ارسال کننده رو چک کنه تا مطمئن بشه ارسالها از سایت مورد نظر هستن.
البته در این روش درواقع جلوگیری از ارسال های جعلی گردن خود سایت مورد نظر میفته. یعنی باید فکری بکنه برای اینکه فرم مورد نظر از همون سایت لود شده باشه، یا مثلا فقط کاربران عضو بتونن کامنت بذارن. بهرحال قبلا توضیح دادم که نمیشه بصورت کامل و مطلق تضمین کرد که واقعا یک کاربر عادی صفحهء شامل فرم مورد نظر رو در یک مرورگر باز و ارسال کرده.


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


خود شما اگه یک cms برای خودتون طراحی کنید و برای بخش نظرات اون اگر بخاین هم با Ajax کار کنه هم کاربر پسند باشه و هم سهولت دسترسی بهش بدید و مثلا نیاز به login نداشته باشه، چه تدابیر امنیتی ای لحاظ می کنید؟CMS چه ربطی به comment service داره؟

alismith
یک شنبه 28 اسفند 1390, 23:21 عصر
CMS چه ربطی به comment service داره؟

دوست عزیز این یک سوال جداگانه بود، و اینطور بیان کردم :

خود شما اگه یک cms برای خودتون طراحی کنید و برای بخش نظرات اون اگر بخاین هم با Ajax کار کنه هم کاربر پسند باشه و هم سهولت دسترسی بهش بدید و مثلا نیاز به login نداشته باشه، چه تدابیر امنیتی ای لحاظ می کنید؟

منظورم مثل همه وبلاگ ها و وبسایت ها بود، سروس هایی مثل php.nuke - wordpress - disqus



1) استفاده از کلید محرمانه به ازای هر سایت (که قبلا گفتم).
البته با الگوریتم خاصی اساسا مشابه Challenge-Response هر بار یک کلید مشتق شدهء جدید برای هر فرم تولید میشه و کلید محرمانهء اصلی هیچوقت به سمت کلاینت ارسال نمیشه، چون در اون صورت دیگه امنیتی وجود نداره و کلاینت هم کلید محرمانه رو داره. بنابراین ما کلیدهای مشتق شدهء یک بار مصرف برای هر فرم تولید میکنیم.



لطف می کنید اگر یکم درباره نحوه ساخت این کلید محرمانه (که از یک روش امنیتی استاندارد برای ساختش استفاده شده باشه) و نحوه پیاده سازیش در این سرویس توضیح بدید



با تشکر

Unique
دوشنبه 29 اسفند 1390, 03:27 صبح
شما میتونی با js یک iframe ایجاد کنی در سایتی که میخواد فرم شما توش نمایش داده بشه و حالا که iframe داره از سایت خودتون استفاده میکنه میتونی خیلی راحت از کلید محرمانه و مشتق سازی اون استفاده کنی !

eshpilen
دوشنبه 29 اسفند 1390, 11:09 صبح
خود شما اگه یک cms برای خودتون طراحی کنید و برای بخش نظرات اون اگر بخاین هم با Ajax کار کنه هم کاربر پسند باشه و هم سهولت دسترسی بهش بدید و مثلا نیاز به login نداشته باشه، چه تدابیر امنیتی ای لحاظ می کنید؟سوال کلی بیان شده که در نتیجه وقت ندارم همهء موارد رو مد نظر قرار بدم و توضیح بدم.
ولی اگر منظورتون فقط جلوگیری از اسپم شدن هست خب دو تا ابزار هست برای این کار: 1) کپچا 2) نیاز به تایید مدیر برای درج کامنت.

کپچا رو میذارید تا از سابمیت خودکار جلوگیری بشه و با روبات دخلتون رو نیارن.
اون دومی هم (احتمالا بعلاوهء اولی) برای اینکه ملت چرت و پرت و تبلیغات ننویسن توی سایتتون. ضمنا اگر کپچا کرک بشه این سیستم میتونه جلوی خسارت/سوء استفاده زیاد رو بگیره.

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


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

ایده ای که کاربر Unique (http://barnamenevis.org/member.php?11933-Unique) گفت هم بنظرم بد نیست.
اگر از iframe و لود فرم مستقیما از سایت comment service استفاده کنی، میشه سیستم ساده تر و کم هزینه تری رو طراحی کرد. به این شکل که برای هر فرمی که تولید میکنید یک کلید رندوم تولید کرده و در یک فیلد hidden در فرمی که به سمت کلاینت ارسال میکنید ذخیرش کنید، و همچنین این کلید در جایی در سمت سرور مثل سشن برای کلاینت مورد نظر هم باید ذخیره بشه. بعد که سابمیت فرم رو دریافت کردید وجود و برابری مقدار کلید فرم رو با کلید موجود در سشن چک کنید و تنها اگر مطابقت داشتن سابمیت رو قبول کنید.
به این شکل میتونید مطمئن بشید که سابمیت مورد نظر از طریق فرمی بوده که از سایت خودتون لود شده بوده.

ضمنا این سیستم برای جلوگیری از حمله های XSRF هم بکار میره و این نقش رو هم ایفا میکنه.

البته بازم میگم که این سیستم یا حتی اون سیستمی که بنده مد نظر داشتم نمیتونن تضمین کنن که کاربر یک کاربر عادی بوده که کل صفحه رو در مرورگر لود کرده. چون یک برنامه غیر از مرورگر هم میتونه رفتار مرورگر رو شبیه سازی کنه و فرم رو قبل از ارسال از سایت خودتون دریافت کنه. ولی اگر کپچا رو هم به این مجموعه اضافه کنید باعث میشه اطمینان بیشتری باشه که طرف انسان بوده و نه یک برنامهء خودکار؛ بنابراین فکر نمیکنم دیگه برای کسی توجیه چندانی داشته باشه که بخواد از طریق غیرمستقیمی فرم رو دریافت و ارسال بکنه.

تنها مزیت سیستم بنده نسبت به روش iframe احتمالا اینه که در اون روش خود سایت مورد نظر روی فرایند کنترل داره و مثلا میتونه امکان کامنت دادن رو بر اساس معیارهایی مثل عضو بودن یا نبودن کاربران محدود بکنه.