آره نکتهء خوبی بود، ولی بازم بنظر من تفسیر PHP از اساس مشکل داره و وجود === دلیل کافی برای نادیده گرفتنش نمیشه.
== هم بالاخره منطق و محدودیت بیشتری نیاز داره.
راستی خوب بود به این نکته هم در گزارشی که دادی اشاره میکردی.
Printable View
آره نکتهء خوبی بود، ولی بازم بنظر من تفسیر PHP از اساس مشکل داره و وجود === دلیل کافی برای نادیده گرفتنش نمیشه.
== هم بالاخره منطق و محدودیت بیشتری نیاز داره.
راستی خوب بود به این نکته هم در گزارشی که دادی اشاره میکردی.
چرا PHP هنگام تبدیل یه سری اولیت ها مدنظر قرار میده و آیا این اولیت ها درست هست یا نه؟
مثلا در مثال زیر میاد و رشته hello رو به عدد تبدیل میکنه (که میشه 0) و بعد با مقدار 0 مقایسه میکنه و شرط درست میشه؟
$a = 0;
if($a == 'hello'){
echo 'hello';
}
else{
echo 'error';
}
// output : hello
حالا چرا نمیاد عدد رو رشته کنه و بعد مقایسه رو انجام بده؟ این چه منطقیه که باید رشته اول تبدیل بشه و بعد عدد؟ اصلا عدد رو تبدیل میکنه یا ...؟
$a = 0;
settype($a, 'string');
if($a == 'hello'){
echo 'hello';
}
else{
echo 'error';
}
// output : error
چون این متغیره که داره مورد ارزیابی قرار میگیره نه مقدار. پس باید مقدار به نوع عدد تبدیل بشه و بعد، عمل مقایسه انجام بشه. بهرحال مسئله اینجا ترتیب تبدیل نیست. مسئله اینه که اینجا اصلاً تبدیل نوع صحیح نیست و نباید انجام بشه.
<?php
//u should know, we can specify sort column(s) by column number in a query.
$sort_columns=Array(2, 3, 5);
//the most safe validation method: white list! seems completely safe! not?
$user_input='2';
if(!in_array($user_input, $sort_columns)) echo "'$user_input': <span style='color: red'>illegal sort column!</span>";
else echo "'$user_input': <span style='color: green'>input validated.</span>";
echo '<div> </div>';
$user_input='7';
if(!in_array($user_input, $sort_columns)) echo "'$user_input': <span style='color: red'>illegal sort column!</span>";
else echo "'$user_input': <span style='color: green'>input validated.</span>";
echo '<div> </div>';
$user_input='sql injection';
if(!in_array($user_input, $sort_columns)) echo "'$user_input': <span style='color: red'>illegal sort column!</span>";
else echo "'$user_input': <span style='color: green'>input validated.</span>";
//so far, everything seems ok/expected!
//but see what type juggling can do for us (indeed for hackers!)...
echo '<div> </div>';
$user_input='2 sql injection';
if(!in_array($user_input, $sort_columns)) echo "'$user_input': <span style='color: red'>illegal sort column!</span>";
else echo "'$user_input': <span style='color: green'>input validated.</span>";
$query="select * from table order by $user_input ...";
//of course, there r many other cases that type juggling can help us in writing more secure and reliable (bug free) programs!!
//and not only that, type juggling helps us write programs much more fast and easily too. but i leave it up to u to show some examples about that matter.
//lol
?>
من گزارشش رو پیدا نمیکنم.نقل قول:
اینم متن گزارشیه که فرستادم
کجاست؟ جوابش چی شد؟
بعدم گفتم که اینطور چیزها بهتره یا اصلا لازمه در محیط بازتر و عمومی تری روش بحث و تبادل نظر آزاد صورت بگیره.
اینکه فقط بخونن و خودشون بتونن نظر بدن و حکم رو هم بزنن روش که نشد!
-----------------
ویرایش: آهان با گوگل پیداش کردم: https://bugs.php.net/bug.php?id=66361
بنظر من اگر بخوایم برنامهء بدون باگ و امنی بنویسیم، اصلا در بیشتر یا حتی تمام جاهای دیگر هم بجای == باید از === استفاده کنیم (یا ترفندهای دیگری بزنیم بهرصورت یا چکهای اضافی و غیره). چون بهرصورت با این رفتاری که PHP در تبدیل و تفسیر سرخود رشته ها به عدد داره آدم خیلی سخت میتونه مطمئن باشه جایی باگ یا حفرهء امنیتی به همین دلیل بوجود نیامده باشه.نقل قول:
in_array پارامتر سوم رو باید true بکنی تا دیگه loose comparison اتفاق نیفته.
موضوع اینه که اینقدر در این تبدیلات افراط کردن و سرخود عمل کردن که از تعادل امنیتی و انتظار و احتمالات بیشتر در برنامه ها هم تاحد زیادی فاصله گرفته.
آخه عزیزم کاربرد تبدیل '3dllldddd ddff ---ddd' به عدد 3 بصورت ضمنی چیه مثلا؟ چقدره کاربرد و فایدهء چنین چیزهایی در برنامه نویسی؟نقل قول:
کاربرد همین که گفتم بود دیگه. کد نویسی کمتر. مسئله امنیتی منظورم نیست. به هر حال اگر هواست نباشه می تونه دچار مسئله امنیتی بشه ولی کاربردش هم اینه که نیازی به تبدیل نداره.
تبدیل '3' به عدد 3 درسته خیلی کاربرد داره و مفیده، ولی رشته هایی که صرفا عددی نیستن کجاها مثلا اینقدر نیاز هست که به زور به عدد تبدیل بشن؟ کجا کاربر یجا رشته ای محتوی چیزهای دیگر غیر از عدد هم وارد میکنه بعد شما میخوای یه عدد از توش بکشی بیرون؟ کجای برنامت خودت همچین مقدارهایی داری که میخوای تبدیل به عدد کنی؟
یه جاهایی هم نیاز باشه موارد خاص و معدودی هست به علت خاصی میخوای اون کار رو بکنی خب با توابع صریح مخصوص میتونی این کار رو بکنی. اینطوری کدت امن تر و خواناتر هم هست و خودت ببینی یا دیگرن نگاه کنن تاحد زیادی قابل حدسه که انتظار چنین رشته های ترکیبی ای رو (هم) داشتی.
اینا اومدن یک رفتار و کاری رو که در شرایط و موارد خاص و معدودی کاربرد داره تعمیم دادن و پیشفرض تبدیلات توی کدهای روتین گذاشتن، خب خیلی کار اشتباهیه!
تازه حتی همون توابع صریح که واسه اینطور موارد هست، اگر نگیم در تمام ولی در اکثر زبانهای دیگر (حداقل اونایی که بنده شخصا دیدم) باز رفتار دقیقتر و امن تری از خودشون نشون میدن و یک رشته ای مثل 'hello' رو که توش هیچ عددی نیست تبدیل به عدد 0 نمیکنن!
باز اینم خودش مشکل داره. شاید قرار بوده کاربر یجا عدد وارد کنه اشتباه گرفته یه چیز اشتباهی وارد کرده اونوقت با اونی که آگاهانه عدد 0 رو وارد کرده یکی فرض میشه؟
خیلی زحمت کشیدن این رو که همه میدونستن پس بخاطر چی مجبور شدن حذفش کنن!نقل قول:
حالا تو داری میگی که اصلا قبول نمی کردن ولی اونجور که من مثلا از کتاب php power programming که توسط خود توسعه دهنده های اصلی php نوشته شده رجیستر گلوبالز رو یک ویژگی که باعث مشکل امنیتی میشه می دونستن
منظور من اینه که بصورت صریح اعتراف نکردن که یک طراحی از اولش هم اشتباه بوده؛ و بنظر نمیاد هنوزم ذهنیت و این تفکر سطحی و بچه گانه خودشون دربارهء طراحی feature های زبان رو زیاد تغییر داده باشن.
اصولا چنین چیزی رو هیچ متخصصی از همون اول هم طراحی نمیکنه، چون بقدر کافی مشخصه که روی اصول نیست؛ اصلا نیازی نبود اینقدر تجربه بشه و در عمل خسارت ببار بیاره تا تازه بتونن واقعیت موجود رو ببینن. اونم تازه اعتراف به این نیست که از اول ذهنیت اشتباهی داشتن و طراحی اشتباه انجام دادن. یعنی اعتراف نکردن که در این زمینه ناشی بودن! واقعا این یک طراحی ناشیانه ای بود. مسئله ای نبود که کس دیگری جز ناشی ها احتمال قابل توجهی داشته باشه که مرتکب بشه.
خب شانس آوردی.نقل قول:
راستی حالا که این مسئله پیش اومده یه review روی بعضی از کدها انداختم (البته من همیشه دیدگاه loose comparison رو داشتم و همیشه با این دید کد نوشتم ولی حقیقتا روی مثالی که گفته بودی هیچ وقت بهش برنخوردم) و دیدم که همه ورودی هایی که از کاربر می گیرم رو از فیلترها و validator ها عبور میدم
من از white list به همین فرم بعضی جاها استفاده کردم. البته خوشبختانه بجای شماره ستون از اسم ستون استفاده کردم که باعث میشه این مشکل پیش نیاد. ولی بهرحال بدیهی هست که اگر در موردی میخواستم از شماره ستون استفاده کنم متوجه این موضوع نمیشدم و احتمالش خیلی زیاد بود که مشابه همین کد حفره دار رو بنویسم و طبیعی هم بود که چون این رفتار غیرمنتظره است با چنان نمونهء خاصی از ورودی کاربر تستش نمیکردم به احتمال زیاد (همون چندتای قبلیش رو تست میکردم مطمئن میشدم که کدم درست کار میکنه).
حتی اگرم اون موقع نسبت به این مسئله آگاهی الان رو داشتم، بازم احتمالش کم نیست که آدم از زیر دستش در بره.
خیلی برنامه ها و خیلی افراد ممکنه چنین خطاهایی داشته باشن. لزومی هم نداره فقط به این شکل و در این موارد مثل switch و white list باشه. ممکنه به خیلی شکلها و در خیلی جاهای دیگر هم وجود داشته باشه.
اونطوری که کد من اصلا کار نمیکنه. چون من ستونها بصورت عددی توی آرایه گذاشتم. ورودیهای کاربر همیشه نوع رشته ای دارن.نقل قول:
in_array پارامتر سوم رو باید true بکنی تا دیگه loose comparison اتفاق نیفته.
کاری که میتونم بکنم اینه که بجای $sort_columns=Array(2, 3, 5) بنویسم $sort_columns=Array('2', '3', '5').
تا قبل از اینکه با PHP کار کنم این بنظرم بدیهی و بدون تردید بود که در تمام زبانهای برنامه نویسی، محیط درونی برنامه محیطی امن محسوب میشه و کسی نمیتونه توش نفوذ کنه مگر از طریق کدها و منطق خود برنامه نویس؛ یعنی مثلا فقط متغییرهایی که برنامه نویس خودش تعریف کرده در برنامه بوجود میان و فقط مقدارهایی رو دارن که خود برنامه در اونها قرار داده.
و فکر میکنم نیاز به این امنیت لازم باشه.
مثل اینکه شما میخواید خونه بسازید خب باید حداقل زمین زیرش محکم باشه یا نه؟
اگر قرار باشه زمین هم زمین نباشه و معلوم نباشه فردا تبدیل به ماست میشه یا یجاش یهو یه درخت درمیاد یجای دیگش نشست میکنه گود میشه، دیگه نمیشه به سبکی که الان ساختمون درست میکنیم ساختمون درست کرد و کار ساختمان سازی روی چنین زمینی خیلی سخت تر میشه به گمانم.
آره خلاصه من تا اون موقع اینطور فکر میکردم و خیالم راحت بود.
تا اینکه چشممون به جمال PHP روشن شد و قضیهء رجیسترگلوبالز!
یهو فهمیدم ای داد بیداد کاربر از اون سر اینترنت با تایپ چند کاراکتر به راحتی بدون هیچ چیز دیگه ای میاد داخل محیط درونی برنامهء من و انگار که اونم داره برنامهء من رو مینویسه یا تغییرش میده هر متغییری رو که میخواد توش ایجاد میکنه!! چه میخواد متغییرهای جدیدی باشه چه متغییرهایی که در برنامهء خودت استفاده کردی و چه متغییرهایی که PHP خودش قبل از شروع اجرای برنامت ست میکنه.
آدم یاد داستانهای جن و پری میفته.
انگار از آسمون هم ممکنه یه چیزی یهو بیفته پایین!
انگار کاربر هم مستقیما همون وسط برنامه و کدهای شماست و میتونه چیزی واردش کنه!!
واقعا من همون موقع نخندیدم، بلکه بسیار عصبانی شدم از این مصیبت بزرگی که به برنامه نویسان و برنامه نویسی وارد کردن با این کارشون.
خداییش عصبانی شدم.
چرا؟ چون تا اون وقت ما حداقل یک فرض و اطمینان در این مورد داشتیم که البته بدیهی هم بنظر میامد و اینطوری نیازی نبود نگران این باشیم که این مسئله رو هم تحت کنترل و نظارت دائمی داشته باشیم و حواس و تمرکزمون رو صرفش کنیم. خب نیازی هم نبود! مثل اینکه شما شب که میخوای بخوابی درب و پنجرهء خونت باید قفل باشه، نه اینکه نتونی قفل کنی و باز بمونه و بعد بگن خب حالا بجاش دزدگیر و تله و این حرفا بذار یا درهای داخلی داخل خونت بذار خودت که دزد اومد داخل نتونه کاری بکنه!!
من میگم دزد اصلا نباید بتونه از دروازه رد بشه، دلیلی نداره، نه اینکه راحت بیاد داخل و بعد در داخل شما بخوای گیرش بندازی یا جلوش رو بگیری با ساختن دربهای داخلی اضافی و قفل و دزدگیر و تله و اینطور چیزها!
ولی طراحان PHP اینطور دلیلی داشتن واسه خودشون: بخاطر راحتی شما شهروندان گرامی ما درها رو باز میذاریم تا افرادی که به خونهء شما میان تا پشت درب اتاق خواب شما بیان و بعد اونجا شما باید حواستون باشه که اگر آشنا و فرد درستی بود اون رو راه بدید، ولی اگر دزدی چیزی بود خودتون باید حواستون باشه و دربهای داخلی گذاشته باشید و قفل کرده باشید که طرف نتونه بیاد داخل و آسیبی به شما برسونه!
موضوع اینه که اون راحتی رو نخواستم بابا. راحتی اینکه بدون اجازه و عمل صریح خودت دروازه های ورودی بسته باشن و توی خونت بتونی آزادانه و بی خیال و بدون ترس اینور و اونور بری و مدام نیاز نباشه حواست جمع باشه و پشت سرت درها رو قفل کنی، از راحتی اونکه چند قدم تا دم درب خروجی منزل تشریف ببرید و ببینید کی اومده آیا آشناست یا دزده، خیلی مهمتر و بیشتره.
محیط داخلی برنامه مثل خونهء برنامه نویس میمونه که باید توش راحت و امن باشه. تا خودش چیزی رو به داخل راه نداده چیزی نیاد داخل و تغییری نکنه. نه اینکه نیاز باشه مدام شش دانگ حواسم توی خونهء خودم هم جمع باشه مثلا یه گلدان دیدم داخل خونه در یک مکانی شک کنم و برم بررسیش کنم ببینم واقعا اون رو خودم خریدم و خودم اونجا گذاشتم یا نه! لابد باید روی همهء اشیاء یک برچسب هلوگرام و پلمپ بزنم تا کس دیگری نتونه بدون متوجه شدن من اونا رو تغییر بده یا جعلی جاشون بذاره!!
این تاپیک خیلی جالبه. خروجی اشتباه به خاطر کم دقتی در کد باعث شده به PHP ایراد بگیرند!!
شاید بی ربط باشه اما پیشنهاد میکنم یک مطالعه ای راجع به ارزیابی مدار کوتاه هم داشته باشید. دو روز دیگه تاپیک نزنید بگید شرط switch و if من کار نمیکنه. PHP مشکل داره !! :D
کم دقتی در کد؟
چیزی که در PHP شما بهش میگید کم دقتی در کد چطور در بقیهء زبانهای مشابه موجب این خروجی اشتباه نمیشه و نیازی به این دقت نیست؟
مسئله اینست که PHP اومده تفسیر و ساختاری رو پیاده کرده که نیاز برنامه نویس به آگاهی و دقت رو بالا برده، بدون اینکه کاربردهای زیاد و مفید کافی داشته باشه که بتونن این افزایش نیاز به دقت و صرف وقت و انرژی بیشتر رو توجیه کنن.
داستانی که درمورد رجیسترگلوبالز هم رخ داد چیز مشابهی بود. این رو که دیگه فقط من نمیگم و تجربهء قبلی بود و خودشون هم معترف شدن که مشکل امنیتی ایجاد میکنن و مجبور به حذفش هم شدن!
طراحی تا طراحی فرق میکنه. یوقت شما به خیال خودت یک feature در زبان میذاری و یک طراحی اشتباه انجام میدی که دست آخر معلوم میشه طراحی مناسبی نبوده و بیشتر از اونکه فایده داشته باشه منجر به خسارت میشه.
وگرنه بله اگر برنامه نویسان آگاهی و دقت بی نقصی داشته باشن، مشکلی پیش نمیاد. ولی مسئله اینه که آگاهی و تمرکز و دقت برنامه نویس هزینه بر است و تازه انسانها هرچقدر هم که دقت کنن و وقت و مایه بذارن بازهم از غفلت و خطا مصون نیستن و نمیتونن 100% تضمین کنن که چیزی از زیر دستشون در نرفته یا متوجه همه چیز بودن؛ حتی بهترین برنامه نویسان (تاحالا کدوم برنامه نویسی در تاریخ اومده که از بروز باگ در برنامه هاش مصون بوده؟). بخاطر همین هرچقدر زبان طوری طراحی شده باشه که نیاز به این آگاهی به مسائل فنی و جزییات سطح پایین کمتر باشه و موقع برنامه نویس نیاز به پرداختن و توجه و تمهید کردن برای جزییات کمتری باشه، اون زبان زبان بهتری بحساب میاد. حداقل در زبانهای سطح بالا که اینطوره! اصولا یک هدف اصلی زبانهای سطح بالا همینه که برنامه نویسی رو راحتتر و سریعتر کنن و بقولی میگن که برنامه نویس تا حد ممکن فقط روی منطق و الگوریتم اصلی برنامهء خودش متمرکز بشه. هرچی هم این تمرکز سطح بالاتر باشه بهتره طبیعتا. یعنی اینطور میشه برنامه ها رو سریعتر و راحتتر درست کرد.
شما توی حیاط خونهء خودت همینطوری مین نمیذاری روی زمین بعد بگی خب باید آگاه بود و دقت کرد!
شاید برای گذاشتن اون مین ها توجیهی هم داشته باشی برای خودت. مثلا بگی برای دزدها کار میذارم!! ولی باید ببینی نسبت به هزینه و ریسکی که داره می ارزه یا نه! آیا در مجموع و در کل زمانها، دلیل و سند بقدر کافی روشن و محکمی وجود داره که بیشتر از اونچه که هزینه و خسارت ببار بیاره سودمند خواهد بود یا خیر.
متوجه اصل بحث نشدی مثل اینکه. احتمالا همینطور سرسری فقط یه عنوان و دو سه تا خط این تاپیک رو خوندی بعد اومدی این اظهار نظر بی ربط رو کردی.
واقعا خودت عجب دقت و اصولی داری ها :چشمک:
خوب شد به ما هم یاد دادی که مشکل از کم دقتی خودمون بوده و باید بیشتر دقت کنیم.
من نمیگم برنامه نویس نباید آگاهی و دقت داشته باشه.
میگم چرا PHP اومده یه چیزهایی سرخود درست کرده که موارد و میزان نیاز به این آگاهی و دقت رو بالا برده، بدون اینکه کاربرد و سود کافی درش بنظر بیاد که بتونه این هزینه رو توجیه کنه.
زبان برنامه نویسی باید تاحد ممکن طبق انتظار و منطق کار کنه و میزان احتمال کاربرد و وقوع موارد رو درنظر بگیره در طراحی. حتی باید عامل خطای انسانی رو هم بحساب بیاره.
اگر چندتا زبان دیگر هم بودن که در این موارد خاص همینطور عمل میکردن آدم میگفت خب بقیه هم به همین طراحی رسیدن. اما حتی یکی هم کسی نتونست معرفی کنه. فقط PHP هست که اینقدر توی این مسئلهء تبدیل های خودکار افراط کرده.
وقتی عامل و باعثِ اینکه خروجی اشتباه حاصل میشه شما باشی. یعنی دقیقاً کم دقتی شما. این همه سفسطه هم لازم نیست.
زمانی خیلی افراد درمورد رجیسترگلوبالز هم همین استدلال شما رو داشتن.
میگفتن خب برنامه نویس باید آگاه باشه و دقت کنه!
منم میگم بله شما اگر مدام دقت کامل داشته باشی و با این آگاهی و احتیاط کدنویسی کنی، رجیسترگلوبالز مشکل امنیتی ایجاد نمیکرد.
این درست.
کسی این رو رد نمیکنه.
روشن است.
اما این نیاز به آگاهی و دقت و احتیاط و تمهیدات خاص، هزینه ای هست که به برنامه نویس تحمیل میشه، و ریسک خطای انسانی رو بالا میبره.
و همهء اینا بخاطر چی؟
بخاطر اینکه برنامه نویس دلش خوش باشه که میتونه بجای چیزی مثل $_POST['username'] بنویسه $username.
این همه هزینه و ریسک بخاطر همین!
بنظر شما می ارزه؟
بنظر من کد روش اول خوانایی بیشتری هم داره و بصورت صریح و با دید اول مشخص میشه که این username داره از سمت کاربر از یک درخواست POST از یک فرم سابمیت شده میاد (و این برای دقت، خوانایی، و self document بودن کد خیلی خوبه - فقط با دیدن یک متغییر میتونی متوجه این همه جزییات بشی). ضمنا ممکن بود فیلد مورد نظر چیزی به روشنی username نباشه و مثلا یک اطلاعات دیگری باشه که در خود برنامه هم ممکنه برنامه نویس خودش تعریف کرده یا از جای دیگری مثل دیتابیس آورده باشه؛ بنابراین امکان تفکیک بصری و سریع و راحت این موارد از هم، به خوانایی و جلوگیری از خطای انسانی و راحتی و سرعت برنامه نویسی کمک میکنه.
اما طراحان PHP اومدن بخاطر دو خط کد کمتر نوشتن، ریسک امنیتی ایجاد کردن، نیاز به دقت بیشتر، و افزایش امکان باگ در اثر خطای انسانی.
برنامه نویسان PHP فقط یک جنبهء سطحی از کدنویسی رو مد نظر قرار دادن: تایپ چند کاراکتر کمتر!
و متغییری که معلوم نیست دیتاش از POST اومده یا GET یا کوکی!!
و به این میگن یک طراحی اشتباه اونم از نوع کاملا ناشیانه!
شک داری؟
تجربه و گذشت زمان هم این مسئله رو ثابت کرد، وگرنه مجبور نمیشدن چنین feature عمومی ای رو بعد از مدتها جا افتادگی حذف کنن.
اگر این یک طراحی اشتباه و یک feature ای که در عمل بیش از اونچه که مفید باشه خسارت ببار میاورد نبود، پس چی بود، چرا مجبور به حذفش شدن؟ پس برای چی از اول طراحی شد؟ چرا بهتر دیدن که نباشه؟ اونم با از بین بردن Backward compatibility و طرفداران زیادی که داشت. فکر کنم طرفدارانش هم آدمهایی با طرز تفکر و استدلال شما بودن :چشمک:
ولی من روز اول که فهمیدم رجیسترگلوبالز چیه حالم ازش بهم خورد! گفتم وه بابا این عجب چیز ابلهانه ایه!! کدوم نادانی چنین چیزی رو طراحی کرده!! عمرا توی هیچ زبان دیگری همچین چیزی طراحی نکردن و نمیکنن!
امروزه میبینیم که اسامی اشیاء و متدها در زبانهای برنامه نویسی در کل کوتاه نشده و بلکه طولانی تر هم شده. چون خوانایی و وضوح و دقت بصری کدها مهمتر از تایپ چند کاراکتر کمتره. بخصوص که ادیتورهای برنامه نویسی با ویژگیهای autocomplete و این حرفها میتونن این نیاز به تایپ رو از بین ببرن.
پس متوجه منظور من چیه دوست عزیز!
لطفا دوباره حرف بی ربط نزن.
اول بحث رو کامل و دقیق بخون و روشن شو ببین منظور چیه دقیقا مشکل سر چیه، بعد اظهار نظر کن.
کم آوردی خودت رو میزنی به اون راه؟
بقدر کافی توضیح دادم.
استدلال ها هم روشن و محکم هستند.
حرف حساب نداری دیگه حرف بیخود نزن.
دیگران میخونن و قضاوت میکنن.
شما جواب منطقی داری مطرح کن.
مثلا بگو همون رجیسترگلوبالز اگر مشکل از دقت برنامه نویسان بوده که باعث حفره های امنیتی میشده، پس چرا حذفش کردن؟ و چیزی که طراحی میکنن و خیلی از برنامه نویسان و برنامه ها بهش اتکا میکنن، بعد حذفش میکنن، طراحی اشتباه نبوده؟
لابد میگی بازم مشکل از بیشتر مردم دنیاست که دقت کافی ندارن :قهقهه:
بله اینطوری بخوای نگاه کنی پس هر طوری طراحی کنن هرچقدر که برنامه نویسی امن رو پیچیده و سخت کنن، مشکل از طراحی زبان نیست و از برنامه نویسان است!!
حرف بی ربطی نیست. رجیستر گلوبالز یک باگ امنیتی بود و بهش اعتراف کردند. من هم مثل شما قبول دارم. اما چه دلیلی داره به هر مشکلی که میرسیم بزنیم خود زبان رو مورد حمله قرار بدیم.
خوشبختانه تبدیل نوع دستی در PHP به خوبی پشتیبانی میشه. برای بررسی هم از === استفاده میشه.
اگر فکر میکنی اینها ایرادات PHP هستن پس به سبک قدیم پیش برید. به سخت گیری زبان هایی مثل C++. قبل از هرکاری خودتون تبدیل نوع انجام بدید تا از صحت خروجی مطمئن باشید. وقتی هم از یکی از ویژگی های زبان PHP که تبدیل انواع خودکار هست بهره میبرید این صحبتها جاش نیست.
این چیزهایی که شما اشاره میکنید باگ نیستند. کم دقتی برنامه نویس به شمار میرن. خیلی بیشتر از این موردی که اشاره کردی از طریق ارزیابی مدار کوتاه سوتی های وحشتناکی داده شده که اصلاً ربطی به باگ در زبان برنامه نویسی نیست. به طراحی اون زبان برمیگرده.
بحث رو کامل و دقیق نخوندی.
من با موارد خیلی خاصی کار داشتم، مواردی که فقط در PHP اینطور طراحی شدن و کار میکنن و نه در هیچ زبان سطح بالا و سطح پایین و هم خانواده و غیر هم خانوادهء دیگری. مواردی که عملا در برنامه نویسی کاربردهای خیلی محدودی دارن و بعکس در موارد بیشتری مورد انتظار برنامه نویس و مطابق با منطق برنامه نیستن.
وگرنه تبدیل نوع خودکار در زبانهای دیگر هم هست و مفیده. ولی تبدیل خودکار اونها در یک حد تعادل بهینه میان امنیت و راحتی و با درنظر گرفتن میزان کاربرد و احتمال در عموم برنامه ها طرحی شده.
معمولا هم زبانها رو سعی میکنن تاحد امکان سازگار و شبیه هم طراحی کنن. چون این هم از نظر سهولت و سرعت یادگیری و هم از نظرهای کاربردی (مثلا تبادل و تبدیل کد و دیتا بین زبانها) و هم از نظر جلوگیری از قاطی کردن و خطای انسانی در برنامه نویسی، مفیده.
PHP اومده تمام این موارد رو زیرپا گذاشته، بازم بخاطر یک مقدار کد نوشتن کمتر، اونم این بار برای مواردی که در برنامه نویسی واقعی کاربردشون خیلی کمه.
من از چیزهایی مثل true شدن hello==0 صحبت میکنم. چیزی که در هیچ زبان دیگری نمونش رو نمی بینید. و چیزی که احتمال اینکه در برنامه کاربرد مفید داشته باشه خیلی کمه.
رجیستر گلوبالز باگ نبود.نقل قول:
رجیستر گلوبالز یک باگ امنیتی بود و بهش اعتراف کردند.
بلکه در درجهء اول طراحی اشتباه بود.
باگ بطور معمول به چیزی میگن که بطور تصادفی و با ناآگاهی و از زیر دست در رفتن در برنامه ها بوجود میاد.
اما رجیسترگلوبالز یک ساختار طراحی و یک feature بود که نسبت بهش آگاهی داشتن.
مثال رجیسترگلوبالز رو هم برای این آوردم که بگم هرجوری که زبان رو طراحی میکنن لزوما صحیح نیست. ممکنه در طراحی اشتباه بشه.
اگر رجیسترگلوبالز خودش باگ بود، پس چطور میشه با صرف دقت و کار کافی باوجودش برنامه های بدون باگ و حفره نوشت؟
من به هر مشکلی گیر ندادم.نقل قول:
اما چه دلیلی داره به هر مشکلی که میرسیم بزنیم خود زبان رو مورد حمله قرار بدیم
مواردی که مطرح کردم موارد خیلی خاص و استثنایی هستن.
مواردی که در هیچ زبان دیگری نظیرشون دیده نشده و مورد انتظار نیست.
برای مشکل داشتن طراحی اونا هم دلیل آوردم.
حق با شماست. منظور من نتیجه ش بود که به عنوان یک باگ امنیتی ازش یاد شد.نقل قول:
رجیستر گلوبالز باگ نبود.
راجع به سایر صحبت هات باید بگم شما Documentation های PHP رو به خوبی مطالعه نکردید. باز هم ایراد از شماست. در مستندات دقیقاً این موارد ذکر شده ;)
ضمنا این مسائل و موارد خاص و گیر دادن به طراحی رو فقط بنده مطرح نکردم.
بطور مثال در این مقاله هم به این قضیه و یکسری ویژگیهای دیگر PHP بعنوان طراحی بد اشاره شده: http://me.veekun.com/blog/2012/04/09...of-bad-design/
من این همه روضه میخونم باز تو میگی لیلی زن بود یا مرد!
عزیزم بحث روی این نیست.
بحث ربطی به دقت و کد من بعنوان یک نمونهء منفرد نداره.
بحث کلی هست دربارهء طراحی زبان.
اینکه معیارش چیه و آیا این موارد رفتار خاص در PHP که در هیچ زبان دیگری نظیرش دیده نشده، طراحی درست و مفیدی هستند یا خیر.
رجیسترگلوبالز هم مستندات روشن داشت و مطالب راجع به روش پرهیز از باگ و حفره بخاطر اون هم در نت پر بود. ولی با این حال یک طراحی اشتباه بود و در عمل بیشتر خسارت ببار میاورد تا اینکه سود داشته باشه.
پس اینکه بگید مستنداتش هست و نخوندی، لزوما چیزی رو ثابت نمیکنه. بحث ما دربارهء این نیست که مستندات هست یا نیست و برنامه نویس مرتکب خطا شده یا نه. بحث اینه که چرا باید چیزی طوری طراحی بشه که امکان خطای برنامه نویس رو بالا ببره؟ چه توجیه و چه سودی داره که این هزینه و ریسک رو پوشش بده؟ آیا ارزشش رو داره؟ چرا باید چیزی طوری طراحی بشه که نیاز باشه برنامه نویسان چیزهای بیشتری یاد بگیرن و در موقع برنامه نویسی دقت بیشتری بکنن؟
در این مورد بنظر من هم حق با eshpilen هست. مسئله اینه که بجز PHP زبانهای Loose Type دیگه هم داریم ولی هیچکدوم در این مورد خاص، اینطوری عمل نکردن. من چند روز پیش داشتم با راسموس درباره این مسئله صحبت میکردم و این مورد رو هم بهش گفتم که حتی اگه بخوایم Loose Type عمل کنیم، اون چیزی که برنامه نویس تو کد زیر انتظار داره:
$a = 0;
switch($a) {
case 'hello':
echo 'hello';
break;
case 'bye':
echo 'goodbye';
break;
default:
echo 'error';
break;
}
// output : hello
اینه که چون caseها از نوع string هستن، a$ تبدیل به string بشه و مقایسه انجام بشه (چون متغیره) نه اینکه ثابتهای case رو بیاد تبدیل نوع کنه! نمیشه که به یکی بگیم اگه فلانی گفت سلام، بهش پولو بده و اگه گفت خداحافظ، فرار کن و اونوقت اون طرف بهش بگه چطوری؟ اونم پولو بده و بیاد بگه فکر کردم منظورش سلامه!
مهندس اصلا یه جور استدلال دیگر هم میتونیم بکنیم. البته این یک استدلال خاص و موردی هست و بحث کلی این تاپیک درمورد اشتباه بودن کلی این طراحی بجای خودش باقیست.
من میگم اصلا وقتی یک متغییر رو با یک رشتهء hardcode شده در برنامه مقایسه میکنیم، این متغییر هست که باید به رشته تبدیل و مقایسه بشه، نه اینکه اون رشته به زور به نوع متغییره تبدیل بشه!
چون ما خودمون رشته رو صریحا اون شکلی نوشتیم. پس اگر نوشتیم 'hello' مشخصه که منظورمون 0 نبوده، وگرنه میتونستیم بجاش بنویسیم 0.
ولی PHP طوری عمل میکنه که بجای hello اگر goodbye هم نوشته باشیم، باز فرقی نمیکنه!!
حتی اگر ما نوشته بودیم '0hello'، بازم PHP نباید اون رو تبدیل به 0 میکرد، چون دلیلی نداشت اونطور بنویسیم! اگر منظور ما صفر بود پس چرا نوشتیم '0hello'؟
خل که نبودیم!
PHP اینقدر رفتارش متناقض و غیرمنطقیه که میاد اون چیزی که برنامه نویس بطور صریح در برنامه نوشته رو به زور تبدیل میکنه به چیز دیگری که برنامه نویس صریحا مشخص نکرده! بنظر من این منطق مشکل داره! باید بعکس باشه.
دقیقاً. من هم همین مسئله رو گفتم. متغیر اسمش روشه و اونه که باید تغییر کنه نه مقادیر ثابت و Hard code شده.
البته تبدیل چیزی مثل '3' یا حتی ' 3 ' به عدد مشکلی نداره و در زبانهای دیگر هم انجام میشه.
مثلا در همون جاوااسکریپت هم تست کنید، white space رو نادیده میگیره.
این رفتار حداقل توجیه شده تر هست و خطرش هم خیلی کمتره. مثلا نمیشه از این طریق حفرهء sql injection ایجاد بشه یا بهرحال ورودیهای خطرناکی به داخل برنامه بیان.