تعداد بازدید: 5199

امنیت و رمزنگاری در php

امنیت و رمز نگاری دو مبحث مهم در برنامه ها به شمار میره. به طور کلی ما باید برای حفاظت باید برنامه هامون در برابر حملات مقاوم کنیم و همچنین از داده ها محافظت کنیم (برای این کار از رمز نگاری استفاده کنیم).

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

  • Cyptography
    • Hashing
    • encryption
  • Security
    • authentication
    • authorization
    • Brute Force Attack
    • Dictionary Attack
    • SQL Injection
    • DDOS
    • XSS
    • CSRF

رمزنگاری در php

ما در رمز نگاری با دو دسته تابع برگشت پذیر(encryption) و برگشت ناپذیر(hashing) مواجهیم.

توابع برگشت پذیر یا encryption

این نوع توابع معمولا برای پنهان کردن یک متن از دید کاربر استفاده می شوند . مثلا یک رشته که حاوی یه سری داده خاص برای ما باشه برای این که این داده ها در رشته معلوم نباشه اون رو encode می کنیم و در نهایت داخل کدمون اون رو decode می کنیم تا اطلاعات رو ازش دربیاریم .

معمولا ما در این توابع از دو اصطلاح encode و decode استفاده می کنیم.

  • تبدیل رشته عادی به رشته نامفهوم میشه encode
  • تبدیل رشته نامفهوم به رشته عادی میشه decode

برای مقایسه دو رشته رمز نگاری شده با استفاده از توابع برگشت پذیر باید اون ها رو encode و decode کنیم.

string → encode → base64 → decode → string

به طور مثال تابع base_64  از جمله توابع رمزنگاری برگشت پذیر در پی اچ پی است. چون این توابع دارای نوع decode و encode هست ساختار کامل اون به شکل های base64_encode و base64_decode می باشد.

توابع برگشت ناپذیر یا Hashing

از این توابع برای احراز هویت (پسورد ها) استفاده میشه . مثلا برای این که پسورد های موجود در پایگاه داده اگر لو رفت کسی نتونه پسورد رو تشخیص بده باید پسورد ها به شکل نامفهوم دربیاریم. از طرفی نباید از توابع برگشت پذیر استفاده بشه چون هکر می تونه با استفاده از decode اون توابع پسورد ها رو برگردونه.

هر رشته ای که به این دسته توابع داده بشه به یه تعداد مشخص کاراکتر نامفهوم تبدیلش میکنه. همونطور که گفتم برای هر رشته با هر تعداد کاراکتر خروجی به یک اندازه است . تعداد خروجی برخی توابع برگشت ناپذیر پی اچ پی رو مشاهده کنید:

  • md5 → 32
  • sha1 → 40
  • sha256 → 64
  • sha512 → 128

پس حجم ستون ذخیره پسورد های تولید شده برای کاربران در پایگاه داده رو میتونید با توجه به نوع الگوریتم رمزنگاری در کدهاتون تشخیص بدید.

برای مقایسه توابع رمز نگاری شده می تونیم مقدار decode (تبدیل شده) هر کدوم رو با هم مقایسه کنیم تا بفهمیم که دو رشته اصلی برابرند یا خیر.

فلسفه وجود نمک یا salt

توابع برگشت ناپذیر به طور تئوری برگشت ناپذیر و به طور عملی برگشت پذیر هستند. پس بهتره بعد از برگشت پسورد به حالت اصلی هم هکر نفمه که رشته اصلی کدومه . برای این منظور ما به رشته پسورد نمک (یک رشته اضافه بر سازمان) اضافه می کنیم که به اون می گن نمک.

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

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

پس نمک در کدهاست.

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

نتیجه گیری :‌ در نهایت ما برای ایمنی پسورد هامون باید نکات زیر رو رعایت کنیم.

  • از الگوریتم های رمزنگاری بروز و برگشت ناپذیر استفاده کنیم.
  • از نمک در کدنویسی قسمت احراز هویت استفاده کنیم.
  • کاربران رو مجبور به استفاده از پسورد های ایمن و غیر قابل حدس کنیم.

امنیت در php

ما در مبحث امنیت باید یه سری اصول امنیتی نظیر authentication و authorization رو رعایت کنیم و همچنین خطراتی که برنامه رو تحدید می کنه رو تشخیص بدیم و برای مقابله با اون ها تدابیری رو در نظر بگیریم.

احراز هویت یا Authentication

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

سیستم لاگین باید به صورتی باشه که کاربر برای استفاده از امکانات برنامه باید احراز هویت بشه و در غیر این صورت نمیتونه از امکانات برنامه استفاده کنه.

سطوح دسترسی یا authorization

مثلا برنامه ما امکانات ۱ و ۲ و ۳ و ۴ و ۵ رو داره و کاربر با سطح دسترسی admin به همه اون ها و با سطح دسترسی editor به مورد ۲ و ۳ و ۴ دسترسی داره. سیستم باید به گونه باشه که کاربر با سطح دسترسی editor نتونه از ماژول ۱ استفاده کنه.

برای این کار یک جدول میتونید درست کنید که نوع سطح دسترسی و همچنین ماژول های فعال برای کاربر اون سطح دسترسی رو تعیین کنه و هر یک از کاربران رو به یکی از سطوح دسترسی لینک کنه . در این صورت زمانی که کاربری با سطح دسترسی خاص یه درخواست رو برای ماژول خاص میده ابتدا با استفاده از اون جدول بررسی میشه که درخواست مجازه یا خیر .

داده های خصوصی نوع دیگری از authorization هست به طوری که کاربر A نباید قادر به تغییر اطلاعات کاربر B باشه . برای این اگر کاربر A با هر روشی (که معمولا از طریق لینک انجام میگیره) قصد تغییر اطلاعات کاربر B رو داشت باید در داخل کدها نوع کاربری رو از طریق نشست تعیین و بعد تشخیص بدیم که این درخواست مجاز هست یا خیر .

Brute Force Attack

یکی از مخاطرات امنیتی که می تواند برنامه شما را تحدید کند Brute Force Attack یا بررسی تمامی تعداد حالات ممکن برای تشخیص پسورد است. به طور مثال قفل شما به صورت عددی سه رقم باشد . خوب کل تعداد حالات ممکن برای حدس می شود ۱۰۰۰ رقم که اگر کامپیوتر ده ملیون پردازش رو در یک ثانیه انجام بده حداکثر در یک هزارم ثانیه میتونه رمز رو حدس بزنه .

نتیجه : برای جلوگیری از این خطر Brute Force Attack :

  • تعداد حالات ممکن رو برای پسوردتون زیاد کنید. به طور مثال هم تعداد و هم کاراکتر های مجاز رو برای این روش بیشتر کنید.
  • از کدهای کپتچا استفاده کنید تا روند کار کامپیوتر ها رو ضعیف تر کنید.

Dictionary Attack

در این روش به جای اینکه تمامی حالت های ممکن رو بررسی کنند  تعدادی از حالات پرتکرار رو برای پسورد ها امتحان می کنند. طبیعیه که برای این روش تشخیص ۱۰۰ درصد وجود نداره.

نتیجه :‌ برای جلوگیری از خطرات Dictionary Attack :

  • کاربران رو مجبور به استفاده از رمز های غیر قابل حدس کنیم
  • از کدهای کپتجا در برنامه مون استفاده کنیم تا روند کار کامپیوتر ها رو کند کنیم.

SQL Injection

تزریق کدهای SQL از طریق لینک یا فرم یا هر ورودی که کاربر داره باعث میشه هکر یه سری تغییرات رو در پایگاه داده بده یا اینکه یه سری اطلاعات رو از پایگاه داده بدست بیاره.

مثلا میتونه با یک ; در انتهای کد شما حالا کوئری خودش رو به اجرا در بیاره و مثلا تمامی فیلد های یک ستون از یک جدول رو به عبارت hacked تغییر بده. خیلی وقت ها کار خطرناک تر از این حالت خواهد بود . اگر داده های شما یه سری آمار حساس باشند و هکر طوری اون ها رو تغییر بده که قابل تشخیص برای شما نباشه.

نتیجه : برای جلوگیری از خطرات SQL Injection :

طبیعیه چون sql injection حالت های زیادی داره به طور صد در صد نمیشه جلوش رو گرفت ولی با رعایت یه سری قوانین خاص میشه خطر اون رو کم تر کرد:

  • داده های ورودی کاربر رو به طور مستقیم اعمال نکنید و اول اون رو اعتبار سنجی کنید و بعد اعمال کنید. (مثلا اگر ورودی عددی باید باشه چک کنید حتما داده نوع عددی وارد شده باشه)
  • داده های کاربر رو پاکسازی کنید. به طور مثال توابعی رو طراحی کنید (با استفاده از عبارات منظم) که بتونه کدهای sql رو تشخیص بده و از بین ببره (نمونه این توابع در هسته وردپرس به وفور یافت می شود) مثلا کاراکتر های خاص نظیر ‘ ,” رو میتونید عملکردشون رو غیر فعال کنید.
  • حدالمکان از ماژول های آماده استفاده کنید. به طور مثال در pdo از bindParam  و در mysqli از تابع mysqli_real_scape_string

برخی توابع پیشفرض مربوط به پاکسازی رشته ها در PHP عبارتست از :

addslashes : این تابع کاراکترا های کنترلی Double Quatation و Single Quatation رو در رشته با قرار دادن \ قبل از آن غیر فعال می کند

<?php
echo addslahses( 'my name is "SELECT * FROM USERS"'); //my name is \"SELECT * FROM USERS\"

htmlspecialchars : این تابع کاراکترهای کنترلی زیر رو با مقادیر encode شده اون تبدیل می کنه:

  • & (ampersand) ↔ &amp;
  • ” (double quote) ↔ &quot;
  • ‘ (single quote) ↔ &#039;
  • < (less than) ↔ &lt;
  • > (greater than) ↔ &gt;
<?php
$str = "This is some <b>bold</b> text.";
echo htmlspecialchars($str); //This is some &lt;b&gt;bold&lt;/b&gt; text.

htmlentities : این تابع هم مثل تابع قبل عمل می کنه با این تفاوت که کاراکتر هایی که تبدیل می کنه بیشتر از تابع htmlspecialchars است.

دقت داشته باشید که خروجی به درستی نمایش داده میشه ولی اگر در سورس برنامه ببینید کاراکتر ها encode شده اند.

html_entity_decode : این تابع رشته encode شده رو میگیره و به حالت سالم بر میگردونه دقیقا برعکسhtmlentities .

strip_tags : این تابع تگ های html و جاوا اسکریپت رو از رشته حذف می کنه.

<?php strip_tags($string,$allow); ?>

پارامتر های این تابع :

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

DOS (Denial Of Service)

dos (denial of service) یا خودداری از خدمات نوعی دیگر از حملات است که کاربر در یک لحظه حجم زیادی از درخواست را به سمت سرور ارسال می کند و در نهایت مانع از پاسخگویی سرور به سایر کاربران می شود.

نتیجه : برای جلوگیری از حملات DOS :

  • از کدهای کپتجا استفاده کنید تا مانع از عملکرد روبات ها در سیستم شوید.
  • ip کاربران را بررسی کنید و به هر ip تعداد معینی پردازش را اختصاص دهید.

spam هم نوعی از حملات DOS است که معمولا برای درج تبلیغات از طریق فرم ها انجام می شود.

XSS (Cross Site Scripting)

سرقت اطلاعات ذخیره شده در مرورگر کاربران (مثلا کوکی ها یا اطلاعات ذخیره شده فرم ها) از طریق اجرای کدهای جاوا اسکریپت در مرورگر شما و ارسال آن به سرور خود انجام می شود.

برای عدم تداخل (با css که مخفف cascading style sheet) عبارت Cross را با X نمایش می دهند که حرف X شبیه به علامت ضربدر می باشد که تداعی کننده تداخل است.

قربانی از دو طریق هدف حملات xss می شود:

  • کلیک کردن روی لینکی که برایش فرستاده شده.
  • لود یک صفحه که یک کد جاوااسکریپت توش تعبیه شده.

نتیجه : معمولا هکر ها این کدها رو از طریق فرم ها در وب سایت ها قرار می دهند . پس صاحبان وب سایت از فیلتر فرم های خودشون اطمینان حاصل کنند. برای فیلتر این کدها می توانیم از توابع php استفاده کنیم (تابع html_special_chars , strip_tags).

Cross-Site Request Forgery (CSRF)

cross site request forgery یا همان درخواست جعلی که هکر درخواستی را به سرور از طریق یکی از کاربران به وب سایت ما می فرستد. این درخواست می تواند از طریق GET یا POST باشد. (مثلا درخواست انتقال پول)

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

معمولا برای این گونه حملات از تصویر هم استفاده می شود . به گونه ای که سورس تصویر را برابر یک لینک قرار می دهند . پس قربانی با دیدن یک تصویر ناخودآگاه یک درخواست را می دهد.

این تصویر می تواند توسط یک لینک ارسال شده (مثلا از طریق ایمیل) به قربانی باشد یا یک اسکریپت که با بارگزاری یک صفحه وب نمایش داده شود.

مرورگر های مدرن تا حدودی سورس غیر معتبر تصاویر را شناسایی می کنند.

نتیجه : برای جلوگیری از حملات CSRF :

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

و اما در پایان :

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

مطالب مشابه

برنامه نویسی شی گرا در پی اچ پی

شی گرایی در php (قسمت یک)

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

عبارات منظم یا عبارات باقاعده

عبارات منظم RegularExpression

در این قسمت قصدداریم تا با یکی از مباحث پیشرفته یعنی عبارات منظم یا عبارات باقاعده (regular expression) آشنا بشیم....

کوکی ها و نشست ها و راه های ذخیره سازی داده د ر php

Cookie و Session در php

زمانی که بحث ذخیره اطلاعات که مطرح میشه ما امکاناتی برای ذخیره اطلاعاتمون داریم: پایگاه داده (DataBase) فایل ها...

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

2 دیدگاه برای امنیت و رمزنگاری در php

  1. سلام متن شما بسیار مفید و عالی بود و ازتون ممنونم که به اشتراک گذاشتید.
    سایت شما عالیه و پر از مطالب مفید.
    لطفا در صورت امکان در مورد mvc در php توضیح بدین. mvc یعنی چی دقیقا؟
    با تشکر

    • با سلام و احترام
      در رابطه با معماری های MVC و HMVC همچنین فریم ورک لاراول مقالاتی منتشر خواهد شد. با عضویت در کانال تلگرام ما می تونید از زمان انتشار مطالب آگاه بشد.
      اما به صورت کوتاه می تونیم بگیم که MVC یک معماری نرم افزار بر پایه شئ گرایی است. به زبان ساده تر یک روش یا نحوه ساخت نرم افزار می باشد که ما از آن در ساخت نرم افزار هایمان پیروی می کنیم و محدود به زبان خاصی نمی باشد و در بسیاری از زبان های برنامه نویسی نظیر PHP , ASP از آن استفاده می شود .

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *