آسیب پذیری های امنیتی در PHP و چگونگی جلوگیری از آن‌ها

ترجمه و تالیف : عرفان حشمتی
تاریخ انتشار : 21 مرداد 99
خواندن در 4 دقیقه
دسته بندی ها : پی اچ پی

امنیت در PHP

هنگام نوشتن کد پی اچ پی بسیار مهم است که آسیب پذیری های امنیتی زیر را در نظر داشته باشید تا از نوشتن کد ناامن خودداری کنید.

انواع آسیب پذیری ها

موارد زیر آسیب پذیری های متداولی هستند که هنگام نوشتن کدهای پی اچ پی با آن‌ها روبه‌رو می‌شوید. ما موشکافانه‌تر آن‌ها مورد بررسی قرار می‌دهیم.

  • Cross Site Request Forgery یک آسیب پذیری ایجاد شده توسط برنامه نویسان که در برنامه‌های مختلف بررسی نمی‌کنند درخواست از کجا فرستاده شده است. این حمله به کاربر این اجازه را می‌دهد تا در سطح بالاتری به برنامه دسترسی پیدا کند.
  • Cross Site Scripting یک آسیب پذیری ایجاد شده توسط برنامه نویسان به این صورت که قبل از دادن ورودی به مرورگر، از ورود به سیستم جلوگیری نمی‌شود (به عنوان مثال هنگام نظر دادن در یک وبلاگ). معمولا برای اجرای جاوااسکریپت مخرب در مرورگر برای انجام حملات مانند سرقت کوکی‌های جلسه از جمله اقدامات مخرب دیگر برای به دست آوردن دسترسی‌های بالاتر در برنامه استفاده می‌شود.
  • Local File Inclusion یک آسیب پذیری در برنامه ایجاد شده توسط برنامه نویس که نیاز به وارد کردن فایلی را توسط کاربر دارد و قبل از دسترسی به فایل درخواستی، ورودی را ضد نفوذ نمی‌کند و این نتیجه را می‌گیرد که فایل در جایی که نباید باشد، وجود دارد.
  • Remote File Inclusion یک آسیب پذیری در برنامه ایجاد شده توسط برنامه نویس که نیاز به وارد کردن فایلی را توسط کاربر دارد و قبل از دسترسی به فایل درخواستی، ورودی را ضد نفوذ نمی‌کند و این نتیجه را می‌گیرد که یک فایل از یک سرور از راه دور اجرا می‌شود و متعلق به جایی است که نباید باشد.
  • Session Hijacking یک آسیب پذیری ناشی از دسترسی یک مهاجم به شناسه جلسه کاربر است و امکان استفاده از حساب کاربران را می‌دهد که توسط هکر جعل شده است. این مورد اغلب برای دستیابی به حساب کاربری مدیر استفاده می‌شود.
  • Session Identifier Acquirement یک آسیب پذیری است که باعث می‌شود یک مهاجم بتواند شناسه جلسه کاربر را حدس بزند یا از آسیب پذیری های موجود در برنامه خود یا مرورگر کاربر برای به دست آوردن شناسه جلسه استفاده کند.
  • SQL Injection یک آسیب پذیری در برنامه ایجاد شده توسط برنامه نویسان که از وارد شدن کوئری غیرمجاز به پایگاه داده جلوگیری نمی‌شود. این امر باعث می‌شود که مهاجم به طور کامل به پایگاه داده دسترسی داشته باشد، حتی پیش از آنکه بتواند داده وارد کند. با این نوع دسترسی، هکر می‌تواند کارهای بسیار بدی انجام دهد.

حال بگذارید جزئیات بیشتری از آسیب پذیری های رایج را بررسی کنیم.

Session Hijacking

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

دفاع در برابر حملات Session Hijacking در PHP

برای دفاع در برابر این گونه حملات، باید مرورگر کاربر و اطلاعات مکان فعلی را در برابر اطلاعات ذخیره شده در جلسه بررسی کنید. در زیر مثالی از پیاده سازی ارائه شده است که می‌تواند به کاهش اثرات حمله ربودن جلسه کمک کند. این آدرس IP، نماینده کاربر را بررسی می‌کند و اگر جلسه منقضی شود، جلسه قبل از شروع مجدد از بین می‌رود.

<?php
session_start();

// Does IP Address match?
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['ipaddress'])
{
session_unset();
session_destroy();
}

// Does user agent match?
if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['useragent'])
{
  session_unset();
  session_destroy();
}

// Is the last access over an hour ago?
if (time() > ($_SESSION['lastaccess'] + 3600))
{
  session_unset();
  session_destroy();
}
else
{
  $_SESSION['lastaccess'] = time();
}

Cross Site Scripting

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

مثال برای حمله Cross Site Scripting

یک وبلاگ به کاربران اجازه می‌دهد تا نظرات خود را با تگ‌های HTML استایل‌دهی کنند، اما اسکریپت قدرتمند این وبلاگ، به کاربر اجازه اجرای تگ‌های <script> جاوااسکریپت را در صفحه نمی‌دهد. یک مهاجم می‌تواند از این کار به نفع خود برای اجرای جاوااسکریپت مخرب در مرورگر استفاده کند. آن‌ها می‌توانند کاربران را به بدافزارها، سرقت کوکی‌های جلسه و موارد دیگر آلوده کنند.

<script>
  alert('Cross Site Scripting!');
</script>

دفاع در برابر حملات Cross Site Scripting در PHP

در پی اچ پی دو تابع اصلی وجود دارد. یکی htmlspecialchars() و دیگری strip_tags() که برای محافظت در برابر این‌گونه حملات ایجاد شده‌اند.

تابع (htmlspecialchars($string مانع از اجرای یک رشته HTML می‌شود و آن را به صورت متن ساده در مرورگر وب نمایش می‌دهد.

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
echo htmlspecialchars($usercomment);

 تابع دیگر این است (strip_tags($string, $allowedtags که تمام تگ‌های HTML به جز تگ‌هایی که در لیست سفید قرار دارند را حذف می‌کند. باید توجه داشت که هنگام استفاده از این تابع بسیار مراقب باشید، زیرا این تابع این امکان را به کاربر نمی‌دهد تا از جاوااسکریپت به عنوان لینک استفاده کند، شما باید آن را خودتان از بین ببرید.

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
$allowedtags = "<p><a><h1><h2><h3>";
echo strip_tags($usercomment, $allowedtags);

تنظیم سربرگ X-XSS-Protection

در PHP می‌توانید X-XSS-Protection Header را ارسال کنید که به مرورگرها می‌گوید که حمله متقابل Cross Site Scripting را ترتیب دهند و صفحه را از بارگیری مسدود کنند. این کار باعث نمی‌شود که تمام حملات Cross Site Scripting فقط منعکس شده باشند و باید در ترکیب با روش‌های دیگر استفاده شوند.

<?php
header("X-XSS-Protection: 1; mode=block");

 نوشتن تابع sanitization به صورت دستی، گزینه دیگری است. اگر می‌خواهید کنترل بیشتری روی این تابع داشته باشید، باید روی تابع HTML Sanitization تسلط کافی داشته باشید. این موضوع برای مبتدیان توصیه نمی‌شود، زیرا یک اشتباه کوچک باعث می‌شود وبسایت‌تان آسیب پذیر شود.

دفاع از وبسایت در برابر حملات Cross Site Scripting با استفاده از یک سیاست امنیتی محتوا

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

یک خط مشی امنیتی محتوا را به عنوان یک هدر HTTP تنظیم کنید

متداول‌ترین روش تنظیم یک خط مشی امنیت محتوا، تنظیم مستقیم آن در هدر HTTP است. این امر می‌تواند توسط وب سرور با ویرایش پیکربندی آن یا ارسال آن از طریق PHP انجام شود.

<?php
header("content-security-policy: default-src 'self'; img-src https://*; child-src 'none';");

یک خط مشی امنیتی محتوا را به عنوان تگ‌های متا تنظیم کنید

می‌توانید خط مشی امنیت محتوای خود را در HTML وارد کنید و بر اساس صفحه تنظیم کنید. این روش شما را مجبور می‌کند که هر صفحه را تنظیم کنید. در غیر این صورت ویژگی‌های این روش را از دست می‌دهید.

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-s

SQL Injection

یک آسیب پذیری در برنامه ایجاد شده توسط برنامه نویسان که از وارد شدن کوئری غیرمجاز به پایگاه داده جلوگیری نمی‌شود. این امر باعث می‌شود که مهاجم به طور کامل به پایگاه داده دسترسی داشته باشد، حتی پیش از آنکه بتواند داده وارد کند. با این نوع دسترسی، هکر می‌تواند کارهای بسیار بدی انجام دهد.

مثال حمله SQL Injection

اسکریپت زیر یک دستور SQL برای دریافت ایمیل کاربر با شناسه است. با این وجود ورودی مسدود نمی‌شود و باعث آسیب پذیری در برابر SQL Injection می‌شود.

<?php
$input = $_GET['id'];
$dbserver = "localhost";
$dbuser = "camper";
$dbpass = "supersecretcampsitepassword";
$dbname = "freecodecamp";

$conn = new mysqli($dbserver, $dbuser, $dbpass, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT email FROM users WHERE id =" . $input;

$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["email"];
    }
} else {
    echo "no results";
}

$conn->close();
SELECT email FROM users WHERE id = `$input`;

بنابراین در بالا، ورودی تایپ کست نشده است (یعنی کست ورودی با int پس وارد کردن عدد مجاز است). همچنین به کسی اجازه حمله SQL Injection را نمی‌دهد. برای مثال آدرس URL getemailbyuserid.php?id=1 به شما این امکان را می‌دهد تا با کمی تلاش، کوئری‌های SQL دلخواه را اجرا کنید.

دفاع از وبسایت در برابر حملات SQL Injection در PHP

چند روش برای دفاع از وبسایت شما در برابر حملات SQL Injection وجود دارد. این روش‌ها شامل Whitelisting،Type Casting و Character Escaping است.

Whitelisting: رویکرد لیست سفید در مواردی استفاده می‌شود که فقط چند ورودی مورد انتظار است. می‌توانید هر ورودی مورد انتظار را در یک PHP Switch لیست کنید و سپس یک پیش فرض برای ورودی نامعتبر داشته باشید. نیازی نیست که در مورد مسئله بازیابی نوع یا دور زدن فرار کاراکتر نگران باشید اما ورودی مجاز به شدت محدود است. این یک گزینه باقی‌مانده است، به مثال زیر مراجعه کنید.

<?php
switch ($input) {
  case "1":
    //db query 1
    break;
  case "2":
    //db query 2
    break;
  default:
    // invalid input return error
}

Type Casting: روش تایپ کستینگ معمولا برای یک برنامه با ورودی عددی استفاده می‌شود. به سادگی ورودی را به ($input (int و فقط یک مقدار عددی مجاز دارد.

Character Escaping: رویکرد فرار کاراکتر باعث جلوگیری از حمله به کاراکترهایی مانند نقل‌قول‌ها و برش‌های زده شده توسط کاربر می‌شود. اگر از MySQL Server و کتابخانه MySQLi برای دسترسی به پایگاه داده خود استفاده می‌کنید، تابع (mysqli_real_escape_string($conn, $string دو آرگومان دارد. اتصال MySQLi و رشته را در بر می‌گیرد و به درستی از ورودی کاربر فرار می‌کنید تا یک حمله تزریق sql را مسدود کنید. تابعی که شما استفاده می‌کنید بستگی به نوع بانک اطلاعاتی و کتابخانه php شما دارد. برای اطلاعات بیشتر در مورد فرار از ورودی کاربر، مستندات کتابخانه php را بررسی کنید.

منبع

گردآوری و تالیف عرفان حشمتی
آفلاین
user-avatar

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

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید