
ریپورتاژ آگهی
,یادگیری زبان برنامه نویسی پی اچ پی در صورتی می تواند به یک کار لذت بخش تبدیل شود که کمی هوشمندی به خرج دهید و از ترفندهای میانبر استفاده نمایید. این مطلب مربوط به همین موضوع است.
در ادامه ۱۰ تکنیک عالی آورده شده که توسعه دهندگان PHP باید یاد بگیرند و هنگام برنامه نویسی از آنها استفاده کنند. این نکات مهارت هایتان را بهبود می دهد و همچنین واکنش گرایی و شفافیت کدتان را افزایش داده و کارایی آن را بهینه تر می کند. بهترین سایت های پربازدید ایرانی از همین زبان برنامه نویسی برای توسعه کار خود استفاده کرده اند.
۱- از برگه تقلب برای SQL Injection استفاده کنید
هر توسعه دهنده وب باید به خوبی با شیوه های امنیتی آشنا باشد و باید برنامه ها را با این شیوه های امنیتی درون ذهنش طراحی کند. قانون اولیه این است که هرگز به داده های دریافت شده از جای دیگر اعتماد نکنید. قانون دیگر اسکیپ (escape) داده ها قبل از ارسال به جای دیگری است. ترکیب این دو قانون برای ایجاد اصول امنیتی پایه می تواند بدین صورت ساده شوند: فیلتر ورودی، اسکیپ خروجی (FIEO).
علت اصلی حمله تزریق به پایگاه داده، اسکیپ کردن داده های خروجی است. به خصوص وقتی رخ می دهد که وجه تمایز بین قالب پرس و جو SQL و داده های استفاده شده توسط پرس و جو به دقت حفظ نمی شود. این حمله در برنامه های PHP که پرس و جوها با روش زیر ساخته می شوند، رایج است:
<?php
$query = “SELECT *
FROM users
WHERE name = ‘{$_GET[‘name’]}'”;
?>
در این حالت مقدار متغیر
$_GET[‘name’]
توسط کاربر، منبعی دیگر، تعیین می شود که نه فیلتر شده و نه اسکیپ.
اسکیپ شدن داده ها در پی اچ پی باعث می شود تا قالب اصلی آنها در یک متن جدید حفظ شود. تأکید بر اسکیپ داده های خروجی تذکری است برای اینکه در خارج از برنامه باید داده ها اسکیپ شده استفاده شوند چراکه در غیر این صورت ممکن است به صورت اشتباه تفسیر شوند. در مقابل آن فیلتر کردن داده ها این اطمینان را به ما می دهد که داده ها قبل از استفاده اعتبارسنجی شده اند. تأکید بر فیلتر ورودی بیانگر این است که منبع داده های خارج از برنامه باید فیلتر شود زیرا نمی توان به آنها اعتماد کرد.
با فرض اینکه از MySQL استفاده می کنیم، می توان آسیب پذیری حمله تزریق به SQL را با اسکیپ اسم توسط تابع ()mysql_real_escape_string کاهش داد. حتی اگر اسم فیلتر هم شود یک لایه امنیتی بیشتری به وجود می آید. (اجرای چندین لایه امنیتی ” دفاع در عمق” نامیده می شود و یک روش امنیتی بسیار خوب است.) در مثال زیر برای افرایش شفافیت کد از قراردادهای نامگذاری استفاده شده و در آن فیلتر ورودی و اسکیپ خروجی داده ها نشان داده می شود:
<?php
// Initialize arrays for filtered and escaped data, respectively.
$clean = array();
$sql = array();
// Filter the name. (For simplicity, we require alphabetic names.)
if (ctype_alpha($_GET[‘name’])) {
$clean[‘name’] = $_GET[‘name’];
} else {
// The name is invalid. Do something here.
}
// Escape the name.
$sql[‘name’] = mysql_real_escape_string($clean[‘name’]);
// Construct the query.
$query = “SELECT *
FROM users
WHERE name = ‘{$sql[‘name’]}'”;
?>
گرچه استفاده از قراردادهای نامگذاری حتی با وجود اینکه چیزی فیلتر شده یا نه و یا اسکیپ شده یا نه، می تواند به شما کمک کند اما استفاده از عبارت های آماده، روش بسیار بهتری است. خوشبختانه با استفاده از PDO توسعه دهندگان PHP یک API جهانی برای دسترسی به داده ها دارند که از عبارت های آماده پشتیبانی می کند حتی اگر پایگاه داده اصولی نباشد.
به یاد داشته باشید آسیب پذیری های حمله تزریق به SQL زمانی وجود دارد که تمایز بین قالب یک پرس و جو SQL و داده های استفاده شده توسط آن پرس و جو به دقت حفظ نشود. با استفاده از عبارت های آماده می توانید این مسئولیت را با ایجاد قالب پرس و جو و داده در مراحل جداگانه به سمت بانک اطلاعاتی هل دهید:
<?php
// Provide the query format.
$query = $db->prepare(‘SELECT *
FROM users
WHERE name = :name’);
// Provide the query data and execute the query.
$query->execute(array(‘name’ => $clean[‘name’]));
?>
صفحه http://php.net/pdo اطلاعات و نمونه های بیشتری را ارائه می دهد. عبارت های آماده قوی ترین موارد حفاظتی را برای مقابله با حمله تزریق به SQL پیشنهاد می دهند.
۲- تفاوت بین عملگرهای مقایسه ای را بشناسید
این نکته خوبی است اما مثال عملی برای آن وجود ندارد تا نشان دهد چه زمانی یک مقایسه غیر دقیق می تواند مشکلاتی ایجاد کند.
اگر ازتابع ()strpos برای تعیین وجود یک زیر رشته در یک رشته استفاده می کنید نتایج می تواند گمراه کننده باشد: (تابع ()strpos در صورت عدم یافتن زیر رشته مقدار FALSE برمی گرداند)
<?php
$authors = ‘Chris & Sean’;
if (strpos($authors, ‘Chris’)) {
echo ‘Chris is an author.’;
} else {
echo ‘Chris is not an author.’;
}
?>
در مثال بالا از آنجا که زیر رشتهChris در همان ابتدای رشته Chris & Sean قرار دارد، تابع ()strpos مقدار صحیح ۰ را برمیگرداند و این مقدار نشان دهنده موقعیت شروع زیررشته در رشته است. از آنجا که نتیجه عبارت شرطی به صورت مقدار بولین تعیین می شود، مقدار صحیح ۰ به عنوان FALSE ارزیابی شده و شرط شکست می خورد. به عبارت دیگر به جای رشته ‘Chris is an author.’ رشته ‘Chris is not an author.’ چاپ می شود!