ممنون از sharif عزیز به خاطر این مطلبی که عنوان کردن چرا که رعایت نکات امنیتی از مهم ترین مسائل توی کدهای php هست ( وب به خودی خود یه حفره امنیتی بزرگ به حساب میاد، اگه قرار باشه ما توی کدهامون مسائل امنیتی رو رعایت نکنیم دیگه بدتر )
در رابطه با مطلب فوق هم توی توضیحات مربوط به قسمت magic_quotes_gpc یه اشتباهی وجود داره :
اما این به تنظیمات PHP شما هم بستگی داره. با غیر فعال کردن magic_quotes_gpc در PHP.ini میتونید addslashes رو برای تمامی مقدارهای گرفته شده از GET و POST یا کوکی ها به صورت خودکار اعمال کنید.
که صحیحش این هست که با فعال کردن تابع فوق ، addslash برای تمامی مقادیر
GET و POST یا کوکی ها به صورت خودکار اعمال میشه .
مثالی هم که در ادامه زده شده صحیح هست و گویای همین مسئله :
PHP:
if (get_magic_quotes_gpc()){
$_GET = array_map('stripslashes', $_GET);
$_POST = array_map('stripslashes', $_POST);
$_COOKIE = array_map('stripslashes', $_COOKIE);
}
در واقع کد فوق این رو میگه که اگر مقدار تابع مورد نظر true باشه ( خروجی تابع فوق زمانی که مقدار get_magic_quotes_gpc در فایل پیکربندی on باشه ، true خواهد بود ) پس بهتر هست که slash های مقدار گرفته شده رو با تابع stripslashes حذف کنیم . چون در ادامه قرار هست با تابع addslashes به مقدار گرفته شده ، slash اضافه کنیم چرا که اگه این کار انجام نشه در واقع ما به مقدارمون 2 بار backslash اضافه کردیم . البته این ایرادی نیست ( البته در این مواقع ) چون ما میخوایم که در هر صورت query خودمون رو نا مفهوم کنیم برای mysql اما مواقعی که مثلا خودمون به عنوان admin از پایگاه خروجی بگیریم و یا صفحه ای داشته باشیم که بخواد خروجی ای از بانک رو به کاربر نشون بده که دارای کاراکتر خاص باشه ، اونوقت هست که به مشکل برمیخوریم. مثال برای مقدار
O'reilly
PHP:
<?php
echo get_magic_quotes_gpc(); // 1
echo $_POST['lastname']; // O\'reilly
echo addslashes($_POST['lastname']); // O\\\'reilly
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
echo $lastname; // O\'reilly
$sql = "INSERT INTO lastnames (lastname) VALUES ('$lastname')";
?>
اما در مورد qury injrction ....
بالای 90 درصد نسخه های مختلف php که از get_magic_quotes_gpc برای رخ ندادن این وضعیت پشتیبانی میکنن همیشه به طور پیش فرض مقدار اون رو on قرار میدن. یعنی خود موتور php برای کاراکترهای خاص که برای پایگاه داده مفهوم خاصی داره قبلش یه backslash اضافه میکنه تا query برای sql نامفهوم بشه و اون رو اجرا نکنه اما بهتر که خودمون در کدها چنین قابلیتی رو اضافه کنیم ( به دلایلی ) .
اگر بخوایم از تابع addslshes استفاده کنیم همون طور که دوستمون sharif توضیح داد باید قبلش چک کنیم که get_magic_quotes_gpc فعال هست یا نه که اگر نبود addslash انجام بدیم. اما اگر میخوایم که تحت هر شرایطی از تابع addslashes استفاده کنیم پس بهتره بعد از چک کردن اگر مقدار مقدار on بود ابتدا stripslashes رو صدا بزنیم و بعد addslashesh که این هم توی پست قبلی کامل توضیح داده شد .
اما چیزی که هست اینکه این تابع Addslashes در کل برای این هست که اگر یک زمانی شما خواستین مقادیر حاصل از فرمی رو یا خروجی حاصل از پایگاهتون رو که کاراکترهای خاص مثل ' یا '' دارن توی صفحه چاپ کنید به مشکل بر نخورید . برای همین از این تابع استفاده میکنیم که php خودش قبل از کاراکترهای خاص یه backslash اضافه کنه تا مشکلی برای پردازش اونها پیش نیاد ( برای php نه mysql )
تابعی که در php برای این کار ایجاد شده و خود manuel php هم سفارش میکنه ، تابع mysql_real_escape_string هست که این تابع هم همون کار ف ی ل ت ر کردن کاراکترهای خاص رو انجام میده اما قبلش یادتون باشه که چک کنید اگر مقدار get_magic_quotes_gpc ، on بود دیگه دوباره کاری نشه .
من از خود manuel سایت php استفاده میکنم که دقیق و بسیط هست :
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.
اینهم مثالش که با پارامترهای ورودی اون آشا بشین :
PHP:
<?php
if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) {
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
if(!is_resource($link)) {
echo "Failed to connect to the server\n";
// ... log the error properly
} else {
// Reverse magic_quotes_gpc effects on those vars if ON.
if(get_magic_quotes_gpc()) {
$product_name = stripslashes($_POST['product_name']);
$product_description = stripslashes($_POST['product_description']);
} else {
$product_name = $_POST['product_name'];
$product_description = $_POST['product_description'];
}
// Make a safe query
$query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', '%d')",
mysql_real_escape_string($product_name, $link),
mysql_real_escape_string($product_description, $link),
$_POST['user_id']);
mysql_query($query, $link);
if (mysql_affected_rows($link) > 0) {
echo "Product inserted\n";
}
}
} else {
echo "Fill the form properly\n";
}
?>