امنیت در برنامه نویسی php
همه ما آگاهی داریم که یکی از جنبههای حیاتی در برنامهها، امنیت آنها است. امنیت باید تضمین کند که اطلاعات حساس ما و کاربران ما به دست افراد ناخواسته نرود. حتی زمانی که هزینههای زیادی برای اجرا و نگهداری یک وبسایت صرف شده باشد، نگرانیهای ما بیشتر از همه به امنیت این پروژه مرتبط است، چگونگی حفاظت از آن در مقابل حملات مختلف، خطاهای برنامهنویسی و غیره. در این مقاله، ما قصد داریم چندین مورد از جنبههای امنیتی مرتبط با PHP را بررسی کنیم.
موارد امنیتی انکودینگ (Encoding)
در برنامهنویسی وب، مشکلات انکودینگ میتواند منجر به مشکلات امنیتی جدی شود. وقتی که اطلاعات ورودی از کاربران به نادرستی انکود شده یا دیکود نشوند، آسیب پذیریهایی مانند حملات از نوع injection و cross-site scripting (XSS) ممکن است پدیدار شوند. برای جلوگیری از این مشکلات، باید از تکنیکهایی مانند اسکیپ کردن و فیلترینگ دادهها استفاده کرد تا از نفوذ اطلاعات نادرست جلوگیری شود.
در مورد امنیت PHP، چندین مسئله وجود دارد که باید به آنها توجه شود. برخی از این موارد شامل انجام نکردن ورودیهای کاربران بدون فیلترینگ، استفاده از توابع قدیمی و آسیبپذیر، عدم بهروزرسانی PHP به آخرین نسخهها که دارای تغییرات امنیتی هستند، و نادیده گرفتن اصول امنیتی مانند اصول اصول جهتدهی و تمیز نگهداشتن کد. برای بهبود امنیت PHP، باید از تکنیکهای امنیتی مانند استفاده از PDO برای کار با پایگاه داده، استفاده از تابع password_hash برای رمزنگاری رمزها، و اعتبارسنجی دادههای ورودی استفاده کرد.
فیلتر کردن ورودیهای کاربران
برای فیلتر کردن ورودیهای کاربران و جلوگیری از حملات امنیتی، میتوانید از روشهای زیر استفاده کنید:
استفاده از فیلترینگ دادهها:
استفاده از توابع فیلترینگ دادهها مانند filter_input
و filter_var
در PHP برای اعتبارسنجی و فیلترینگ دادههای ورودی. محدود کردن نوع دادههای ورودی (مثلا، تنها عدد یا رشته) و حذف کاراکترهای غیر مجاز.
اسکیپ کردن دادههای ورودی:
اسکیپ کردن کاراکترهای خاص مانند نقل قول و علامت خواسته شده که میتوانند به عنوان بخش از حمله XSS مورد استفاده قرار گیرند.
اعتبارسنجی دادههای ورودی:
اعتبارسنجی دادههای ورودی بر اساس نوع داده مورد انتظار (مثلا، بررسی طول یک رشته یا اعتبارسنجی یک آدرس ایمیل).
استفاده از کتابخانههای امنیتی:
استفاده از کتابخانههای امنیتی آماده مانند OWASP ESAPI برای فیلترینگ ورودیها.
با اجرای این روشها و توجه به امنیت در هنگام توسعه، میتوانید از بسیاری از حملات امنیتی جلوگیری کنید و اطمینان حاصل کنید که ورودیهای کاربران به طرز صحیحی پردازش میشوند.
امنیت cookie ها در php
امنیت کوکیها در PHP بسیار حائز اهمیت است زیرا کوکیها میتوانند اطلاعات حساسی را ذخیره و انتقال دهند. برای افزایش امنیت کوکیها در PHP، میتوانید اقدامات زیر را انجام دهید:
به طور کاملتر در مورد امنیت کوکیها در PHP میتوانید به موارد زیر توجه کنید:
استفاده از HTTPS:
استفاده از اتصال امن HTTPS برای ارسال و دریافت کوکیها. HTTPS اطلاعات را از طریق رمزنگاری ایمن انتقال میدهد و از حملات Man-in-the-Middle جلوگیری میکند.
تنظیم پارامترهای کوکی:
Secure: تنظیم این پارامتر برای کوکیها فقط زمانی که اتصال امن HTTPS برقرار شده است، ارسال کوکیها اجازه داده میشود.
HttpOnly: این پارامتر جلوگیری میکند تا کوکیها از طریق اسکریپتهای جاوااسکریپت قابل دسترسی نباشند و از حملات XSS جلوگیری میکند.
استفاده از توابع امنیتی:
برای تنظیم کوکیها از توابع امنیتی مانند setcookie
استفاده کنید. این تابع امکانات امنیتی بیشتری نسبت به تنظیم مستقیم کوکیها ارائه میدهد.
رمزنگاری اطلاعات حساس:
اگر نیاز به ذخیره اطلاعات حساس در کوکیها دارید، از رمزنگاری مناسب استفاده کنید. برای مثال، میتوانید از توابع مانند base64_encode
و base64_decode
برای رمزنگاری و رمزگشایی دادهها استفاده کنید.
اعتبارسنجی دادهها:
هنگام استفاده از اطلاعات کوکیها، حتماً دادهها را اعتبارسنجی کنید تا از حملات نظیر تزریق کوکی جلوگیری شود. اعتبارسنجی دقیق نوع و مقدار دادهها میتواند از حملاتی مانند تزریق SQL یا تزریق کوکی جلوگیری کند.
نظارت بر انقضای کوکیها:
تنظیم زمان انقضای کوکیها به طور منطقی و متناسب با نیازهای سیستم تا از دادههای قدیمی و غیرضروری جلوگیری شود.
استفاده از سیاستهای امنیتی:
تعیین سیاستهای امنیتی مناسب برای مدیریت اطلاعات کوکی و دسترسی به آنها. این شامل تعیین سطوح دسترسی، زمانبندی انقضا و سایر موارد امنیتی مرتبط با کوکیها میشود.
با رعایت این موارد، میتوانید از امنیت کوکیها در PHP اطمینان حاصل کنید و از حفظ اطلاعات حساس کاربران خود اطمینان حاصل کنید.
آموزش هش کردن در php
برای هش کردن دادهها در PHP میتوانید از توابع هش کردن ارائه شده توسط PHP استفاده کنید. یکی از روشهای معمول برای هش کردن در PHP استفاده از توابع hash()
است. برای مثال، میتوانید از الگوریتم SHA-256 برای هش کردن یک رشته استفاده کنید. در زیر یک نمونه کد PHP برای هش کردن یک رشته با استفاده از SHA-256 آورده شده است:
<?php
// رشته مورد نظر برای هش کردن
$data = 'Hello, World!';
// هش کردن رشته با الگوریتم SHA-256
$hashed_data = hash('sha256', $data);
echo "متن اصلی: $data <br>";
echo "هش شده: $hashed_data";
?>
این کد، رشته “Hello, World!” را با استفاده از الگوریتم SHA-256 هش میکند و مقدار هش شده را نمایش میدهد.
برای استفاده از الگوریتمهای هش دیگر یا تنظیمات اضافی، میتوانید به مستندات PHP مراجعه کنید. مطمئن شوید که هنگام هش کردن اطلاعات حساس مانند رمزعبورها، از الگوریتمها و روشهای امن استفاده کرده و از توابعی مانند password_hash()
و password_verify()
برای مدیریت رمزعبورها استفاده کنید.
تابع password_hash() برای هش کردن رمزعبور
تابع password_hash()
در PHP برای ایجاد هش امن از رمزعبورها با استفاده از الگوریتمهای هش قوی مناسب برای ذخیره سازی و بررسی رمزعبورها استفاده میشود. این تابع به طور خودکار یک رشته هش شده به همراه “salt” ایجاد میکند که برای اطمینان از امنیت بیشتر استفاده میشود.
در زیر یک نمونه ساده از استفاده از password_hash()
برای هش کردن یک رمزعبور آمده است:
<?php
// رمزعبوری که باید هش شود
$password = 'mySecurePassword123';
// ایجاد هش امن از رمزعبور
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// نمایش رمزعبور و هش شده
echo "رمزعبور: $password <br>";
echo "هش شده: $hashed_password";
?>
در این مثال، تابع password_hash()
برای ایجاد هش امن از رمزعبور mySecurePassword123
با استفاده از الگوریتم پیشفرض و تنظیمات امنیتی پیشفرض فراخوانی شده است. نتیجه این تابع شامل هش شده رمزعبور و اطلاعات مربوط به salt آن است.
برای بررسی یک رمزعبور وارد شده توسط کاربر با هش آن، میتوانید از تابع password_verify()
استفاده کنید. این تابع به شما امکان میدهد بررسی کنید که آیا یک رمزعبور وارد شده توسط کاربر با هش آن مطابقت دارد یا خیر.
<?php
$hashed_password = '$2y$10$1S2s4b9ZrMpTmJ1Lcn2V2.1WjfZ6cFkT9M3ZPwN2s1i4v4piUf4p2'; // هش شده از رمزعبور
$user_input_password = 'mySecurePassword123'; // رمزعبور وارد شده توسط کاربر
// بررسی مطابقت رمزعبور وارد شده با هش شده
if (password_verify($user_input_password, $hashed_password)) {
echo 'رمزعبور مطابقت دارد!';
} else {
echo 'رمزعبور مطابقت ندارد!';
}
?>
با استفاده از توابع password_hash()
و password_verify()
، میتوانید رمزعبورها را به صورت امن هش کرده و بررسی کنید که آیا رمزعبور وارد شده توسط کاربر معتبر است یا خیر.
امنیت register_globals در php
register_globals
یک تنظیمات امنیتی در PHP بود که در نسخههای جدید PHP که از PHP 5.4 به بعد استفاده از آن توصیه نمیشود، از محیطهای عمومی برای تعریف متغیرها استفاده میکند. این تنظیمات در PHP به طور پیشفرض در نسخههای جدید غیرفعال است.
استفاده از register_globals
میتواند باعث آسیبپذیریهای امنیتی جدی شود، زیرا این امکان را به کاربر میدهد که از طریق پارامترهای URL یا فرمها متغیرها را در برنامه PHP تعریف کند. این موضوع میتواند به حملههای تزریق کد (مانند تزریق SQL) و دسترسی به اطلاعات حساس (مانند نام کاربری و رمزعبور) منجر شود.
برای افزایش امنیت، بهتر است از تنظیمات register_globals
که در PHP 5.4 و بعد از آن غیرفعال شده است، استفاده نکنید. به جای استفاده از register_globals
، میتوانید از متغیرهای محلی یا متغیرهای SuperGlobal (مانند $_POST
, $_GET
, $_REQUEST
) برای دسترسی به دادههای فرم استفاده کنید. این روش امنتر است و به شما امکان میدهد که کنترل بهتری بر روی دادههایی که برنامه شما دریافت میکند داشته باشید.
به طور خلاصه، استفاده از register_globals
به شدت توصیه نمیشود و برای افزایش امنیت برنامههای PHP خود، بهتر است از روشهای دیگری برای دسترسی به دادهها استفاده کنید.
برای غیرفعال کردن تنظیمات register_globals
در cPanel، شما میتوانید از قسمت تنظیمات PHP Selector در cPanel استفاده کنید. در ادامه توضیحاتی در مورد چگونگی انجام این کار آورده شده است:
ورود به cPanel:
ابتدا وارد cPanel خود شوید. برای این کار معمولاً میتوانید به آدرس https://نامسرورشما:۲۰۸۳
یا https://domain.com:2083
مراجعه کنید و وارد نام کاربری و رمز عبور cPanel خود شوید.
پیدا کردن تنظیمات PHP Selector:
بعد از ورود به cPanel، باید به دنبال بخش “Select PHP Version” یا “PHP Selector” بگردید. این بخش معمولاً در بخش “Software” یا “Software and Services” قرار دارد.
تغییر تنظیمات PHP:
وارد بخش PHP Selector شوید. در این بخش ممکن است گزینههای مختلفی برای تنظیمات PHP وجود داشته باشد.
در اینجا ممکن است یک گزینه برای تنظیمات PHP وجود داشته باشد که به شما امکان میدهد تنظیمات PHP را ویرایش کنید.
غیرفعال کردن register_globals
:
وارد تنظیمات PHP شوید و ممکن است بتوانید تنظیمات مختلف PHP را مشاهده کنید.
باید به دنبال گزینهای با نام مربوط به register_globals
بگردید و آن را از فعال به غیرفعال تغییر دهید. معمولاً این گزینه به صورت یک چک باکس یا یک منوی کشویی نمایش داده میشود.
پس از انجام تغییرات مورد نظر، باید تغییرات را ذخیره کنید.
ذخیره تغییرات:
بعد از غیرفعال کردن register_globals
، باید تغییرات را ذخیره کنید تا تنظیمات جدید اعمال شود.
با انجام این مراحل، شما میتوانید تنظیمات register_globals
را در cPanel خود غیرفعال کنید و امنیت برنامههای PHP خود را افزایش دهید.
گزارشگیری خطا با استفاده از فایل php.ini
برای ویرایش فایل php.ini
به منظور فعال کردن گزارشدهی خطاها در PHP، شما میتوانید مراحل زیر را دنبال کنید. این مراحل برای سرورهایی که امکان دسترسی به فایل php.ini
را دارند مناسب است:
پیدا کردن فایل php.ini
:
ابتدا باید فایل php.ini
را پیدا کنید. این فایل ممکن است در محلهای مختلف بر اساس نصب و تنظیمات سرور شما قرار داشته باشد. معمولاً مسیرهایی مثل /etc/php/7.4/php.ini
یا /etc/php/7.4/cli/php.ini
(برای نسخه PHP 7.4 به عنوان مثال) برای فایل php.ini
استفاده میشود.
باز کردن فایل php.ini
:
از طریق یک ویرایشگر متنی مانند nano
, vim
, یا ویرایشگر متنی گرافیکی، فایل php.ini
را باز کنید.
تنظیم گزارش خطاها:
برای فعال کردن گزارش دهی خطاها در PHP، باید تنظیمات مربوط به error_reporting
را ویرایش کنید. برای نمونه، میتوانید خط زیر را به فایل php.ini
اضافه کنید:error_reporting = E_ALL
فعال کردن گزارش خطاها:
برای فعال کردن گزارش خطاها، باید تنظیمات display_errors
و log_errors
را تنظیم کنید.display_errors = On log_errors = On
تعیین محل ذخیره خطاها:
برای تعیین محل ذخیره خطاها، میتوانید از تنظیمات error_log
استفاده کنید:error_log = /path/to/error_log
ذخیره و خروج:
ذخیره تغییرات اعمال شده در فایل php.ini
و بستن ویرایشگر متنی.
بازنشانی سرویس PHP:
برای اعمال تغییرات، باید سرویس PHP را مجدداً راهاندازی کنید. این کار ممکن است با دستوراتی مانند sudo service php7.4-fpm restart
یا sudo systemctl restart php-fpm
(برای سیستمهای مبتنی بر systemd) انجام پذیرد.
با انجام این مراحل، شما تنظیمات مربوط به گزارش دهی خطاها در PHP را در فایل php.ini
اعمال کرده و PHP را به گزارش خطاها مجهز نمودهاید.
دستورات کاربردی برای افزایش امنیت هنگام برنامه نویسی php
برای افزایش امنیت هنگام برنامهنویسی PHP، میتوانید از دستورات زیر برای اعمال تنظیمات امنیتی مختلف استفاده کنید:
استفاده از PDO (PHP Data Objects):
استفاده از PDO به جای توابع MySQL مانند mysql_query
یا mysqli_query
امکان اجرای کوئریهای امنتر و پیشگیری از حملات SQL Injection را فراهم میکند.
$pdo = new PDO('mysql:host=localhost;dbname=database', 'username', 'password');
استفاده از استانداردهای امنیتی CSRF (Cross-Site Request Forgery):
برای جلوگیری از حملات CSRF، میتوانید از توکنهای CSRF استفاده کنید.
// ایجاد توکن CSRF
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
// بررسی توکن CSRF در فرم
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
// توکن نامعتبر است
exit('Invalid CSRF Token!');
}
}
فیلتر کردن و اعتبارسنجی ورودیها:
استفاده از توابع مانند filter_var
برای فیلتر کردن ورودیهای کاربر و htmlspecialchars
برای اعتبارسنجی و خروجیسازی دادههای ورودی از حملات XSS محافظت میکند.
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
$name = htmlspecialchars($_POST['name'], ENT_QUOTES);
استفاده از HTTPS:
برای افزایش امنیت، اطمینان حاصل کنید که از اتصال HTTPS استفاده میکنید تا ارتباطات بین مرورگر و سرور رمزشده باشند.
اجتناب از اطلاعات محرمانه در کد PHP:
از اطلاعات محرمانه مانند رمز عبور و کلیدهای API در کدهای PHP خود خودداری کنید. بهتر است از محیط متغیرهای تنظیم شده سرور یا فایلهای تنظیم شده خارجی برای ذخیره این اطلاعات استفاده کنید.
به روزرسانی نسخه PHP:
اطمینان حاصل کنید که از آخرین نسخه PHP استفاده میکنید تا از بهبودهای امنیتی جدید بهرهمند شوید.
تنظیم فایل php.ini
برای افزایش امنیت:
تنظیمات امنیتی مانند display_errors = Off
, expose_php = Off
, allow_url_include = Off
و … در فایل php.ini
را تنظیم کنید.
این تنظیمات و روشها میتوانند به افزایش امنیت برنامههای PHP شما کمک کنند. اما بهتر است همواره با دستورات و روشهای مربوط به امنیت آشنا باشید و از بهترین شیوهها برای محافظت از برنامههای خود استفاده کنید.
حل مشکل امنیتی SQL Injection
برای رفع مشکل امنیتی SQL Injection در برنامههای PHP، میتوانید از روشهای زیر برای پیشگیری از این نوع حملات استفاده کنید:
استفاده از Prepared Statements:
بهجای استفاده از رشتههای SQL برای اجرای کوئریها، از Prepared Statements (یا Parameterized Queries) استفاده کنید. این روش اجازه میدهد تا پارامترهای ورودی جدا از کوئری SQL قرار گیرند و از این راه از اجرای کد مخرب جلوگیری میشود. مثال:
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute(['username' => $username]);
استفاده از ORM (Object-Relational Mapping):
استفاده از ORM مانند Eloquent در Laravel یا Doctrine در Symfony میتواند از حملات SQL Injection جلوگیری کند، زیرا این ابزارها به طور خودکار پارامترها را escape و کوئریهای امن تولید میکنند.
فیلتر کردن ورودیها:
- قبل از استفاده از دادههای کاربر، آنها را بررسی و فیلتر کنید. از توابع مانند
filter_var
وmysqli_real_escape_string
برای فیلتر کردن و escape کردن دادههای ورودی استفاده کنید. مثال:
$username = mysqli_real_escape_string($conn, $_POST['username']);
استفاده از Stored Procedures:
- استفاده از Stored Procedures در پایگاه داده به جای اجرای کوئریهای مستقیم نیز میتواند از SQL Injection جلوگیری کند.
نقشهای کاربری و دسترسیها:
- محدود کردن دسترسی به کاربران به تنها آن دادهها و عملیاتی که واقعاً نیاز دارند میتواند از حملات SQL Injection جلوگیری کند.
بهروزرسانی نرمافزارها:
- اطمینان حاصل کنید که نرمافزارهای مربوطه مانند PHP، MySQL و frameworkهایی که استفاده میکنید بهروز هستند تا از بهترین امکانات امنیتی بهرهمند شوید.
تنظیمات امنیتی دادهها:
- از تنظیمات امنیتی مانند
PDO::ATTR_EMULATE_PREPARES
وPDO::ATTR_ERRMODE
برای PDO استفاده کنید تا از امکانات امنیتی بیشتری برخوردار شوید.
با اعمال این روشها و توابع مربوطه، میتوانید از حملات SQL Injection در برنامههای PHP خود جلوگیری کنید و امنیت سیستم خود را افزایش دهید.
نگهدای از Directory list در php
برای محافظت از لیست دایرکتوری (Directory Listing) در PHP، یعنی جلوگیری از نمایش فهرست فایلها و پوشههای موجود در یک دایرکتوری به صورت عمومی، میتوانید از روشهای زیر استفاده کنید:
ایجاد یک فایل index.php یا index.html:
بهتر است برای هر دایرکتوری که نمیخواهید فهرست آن نشان داده شود، یک فایل index.php یا index.html ایجاد کنید. این کار باعث میشود که وقتی کاربران به آن دایرکتوری دسترسی پیدا کنند، صفحهای خاص به جای فهرست فایلها نمایش داده شود.
تنظیم فایل .htaccess
:
اگر از سرور Apache استفاده میکنید، میتوانید با ایجاد یک فایل .htaccess
در دایرکتوری مورد نظر، اجازهنامههای دسترسی به آن دایرکتوری را تنظیم کنید و جلوی Directory Listing را بگیرید. مثال:
Options -Indexes
استفاده از فایل index.php
برای انتقال کاربران:
در صورتی که نمیخواهید کاربران به فهرست دایرکتوری دسترسی داشته باشند، میتوانید با استفاده از فایل index.php
و توابع PHP این امکان را مختص به خود کنید و آنها را به صفحه دیگری هدایت کنید. مثال:
<?php header("Location: /"); ?>
استفاده از .htaccess
برای انتقال به صفحه خاص:
میتوانید از فایل .htaccess
برای تنظیم خودکار انتقال کاربران به یک صفحه خاص به جای نمایش فهرست دایرکتوری استفاده کنید. مثال:
DirectoryIndex index.php
استفاده از تابع header
در PHP:
با استفاده از تابع header
در PHP، میتوانید کاربران را به یک صفحه دلخواه هدایت کنید به جای نمایش فهرست دایرکتوری. مثال:
<?php header("Location: /"); ?>
با اعمال این روشها، میتوانید از نمایش فهرست دایرکتوری در PHP جلوگیری کرده و اطلاعات دایرکتوری خود را محافظت کنید.
جمع بندی:
در مقاله امنیت PHP، توجه به نکات اصلی امری حیاتی است. حتی خطاهای کوچک میتوانند برای شما و کاربران پیچیدگیهای زیادی ایجاد کنند. توصیه ما و بسیاری از توسعهدهندگان این است که امنیت را جدی بگیرید، زیرا نادیده گرفتن این موضوع میتواند به فاجعه منجر شود. اطلاعات شما ارزشمند هستند؛
کاربران ممکن است با همان اطلاعات ورود (نام کاربری و رمز عبور) در وبسایتهای دیگر ثبتنام کرده باشند و این میتواند باعث دسترسی آسان هکرها شود. استفاده از فریمورکها میتواند این نگرانیها را برطرف کند، اما حساسیت و دقت در کدنویسی PHP خالص نیز ضروری است. حفظ امنیت پروژههای خود از اهمیت بالایی برخوردار است، زیرا هکرها از ضعفهای شما به نفع خود استفاده میکنند.