PDA

View Full Version : سوال: آیا این کد آپلود تصویر امنه ؟ با استفاده از GD



Weblove
شنبه 09 اسفند 1393, 17:51 عصر
سلام بر اساتید
با تحقیقاتی که بعمل آوردم و با استفاده از یه تاپیک توی همین انجمن که قدیمی بود به نتیجه رسیدم استفاده از توابع GD برای آپلود امنیت آپلود رو برقرار میکنه
چون تاپیک قدیمی بود و مسائل امنیتی باید بروز باشه تصمیم گرفتم یه تاپیک جدید ایجاد کنم اگر مسائل بروزی هست ارائه بشه
این کد رو من برای آپلود تصاویر JPG استفاده می کنم !
در واقع این اپلود نیست ، این تصویری که به سیستم ارسال میشه رو می خونه و از روش مینویسه
به نظر امنیتش برقراره ، اما گفتم از دوستان و اساتید سوال کنم ببینم مشکلی نداره ؟
پیشاپیش ممنون از وقتی که میگذارید


$picpfile = $_FILES['uploadimage']['tmp_name'];
$realsize = getimagesize($picpfile);
$image_p = imagecreatetruecolor($realsize[0], $realsize[1]);
$image = imagecreatefromjpeg($picpfile);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $realsize[0], $realsize[1], $width, $height);
imagejpeg($image_p,"./jpeg/".time()."_".rand(0,9999).".jpg", 100);

prans.info
شنبه 09 اسفند 1393, 18:50 عصر
سرعت GD رو با دستورات ساده برای چک فرمت و... مقایسه کردید ؟
بعدا شاید لازم باشه فایل دیگه ای (فرمت) هم قابل آپلود باشه و اون وقت باید کد چکرتون رو تغییر بدید
بهتره در حالت اولیه از توابع و دستورات معمول برای چک کرن فرمت و تایپ فایل استفاده کنید بعد هم اگه لازم بود از GD استفاده کنید .

Weblove
شنبه 09 اسفند 1393, 19:24 عصر
از GD استفاده کردم که هیچ فایلی از سمت کاربر روی هاست اپلود نشه
برای فرمت های دیگه هم GD رو میشه استفاده کنید

لطفا در مورد امنیتش بفرمایید
متشکرم

prans.info
شنبه 09 اسفند 1393, 21:20 عصر
تاجایی که من میدونم تابع imagecreatefromjpeg به جز تصویر چیز دیگه ای نمیگیره پس میتونه موثر باشه .
باز صبر کنید تا بقیه دوستان پاسخ بدند .
به هر حال توصیه می کنم تایپ و فرمت فایل رو چک کنند .

freeman99
یک شنبه 10 اسفند 1393, 10:27 صبح
آپلود فایل نکات امنیتی زیادی داره. من قبلا راجع به این موضوع تحقیق مفصلی کرده بودم، ولی یه اشتباهی کردم و جمع بندی و تولید مقاله بابتش نکردم، چون خیلی زود سر رشته از دستم در رفت و دیگه هم وقت و اولویت نداشتم که دوباره مرور کنم. توی یک پستی در سایت stackoverflow بود فکر کنم که یک طرفی مواردی رو جمع بندی و لیست کرده بود که برای داشتن یک سیستم آپلود با حداکثر امنیت باید یا بهتره همه رو رعایت و پیاده سازی کنیم. یکیش هم همین روش شما!
ولی زیاد هم نترسید. این روش استفاده از کتابخانه های تصویری برای اطمینان از اینکه محتوای غیر منتظره ای نمیتونه از سیستم عبور کنه بد نیست، که آقای شهرکی قبلا مطرح کرده بود، ولی من همون موقع هم به اینکه واقعا به هیچ صورتی نمیشه از این سیستم کدهای دلخواه رو عبور داد شک کردم و هنوزم شک دارم و نتونستم جواب قاطعی براش پیدا کنم چون مسئله بسیار تخصصی و پیچیده است. البته شما به همین نسبت میتونید مطمئن باشید که افراد کمی در دنیا هستن که این دانش و توانایی رو داشته باشن که، در صورت امکان، بتونن این روش رو دور بزن؛ هرچند اگر این کار ممکن باشه و یکی از این افراد مثلا یه برنامه ای برای این کار تولید و منتشر کنه اونوقت امنیت این روش مخدوش میشه چون دیگه هر script kiddie هم میتونه ازش استفاده کنه.
حالا قضیه اینه که منظور من از اینکه چطور میشه این سیستم رو دور زد چیه.
ببینید فرمتهایی مثل jpg از فشرده سازی استفاده میکنن. ما در یک فرمت bitmap که فشرده سازی نداره میتونیم عملا هر دیتایی رو ذخیره کنیم در عین حالی که از دید کتابخانه های تصویر یک تصویر استاندارد و بدون کوچکترین اشکالی هم باشه! درواقع من این کار رو قبلا با فرمت wbmp تست کردم و باید بگم اگر در برنامتون از این فرمت استفاده کنید (و درواقع هر فرمت bitmap دیگری)، کد فیلترینگ شما امنیت نداره و میشه ازش مثلا کدهای جاوااسکریپت یا PHP یا هر چیز دیگری رو عبور داد! حالا اینکه چطوری، خب باید طرز کار فرمت ها رو بدونید و درک کنید که اونوقت میفهمید که عملا هر دیتایی میتونه بخشی از یک فرمت bitmap باشه.
ولی بخش بسیار تخصصی تر و پیچیده تر کار وقتیه که پای فرمتهای پیچیده تر و دارای فشرده سازی مثل jpg و png و gif وسط میاد. اینجا کار بسیار پیچیده تر میشه چون شما باید کدهای خطرناک خودتون رو طوری طراحی کنید که در عین اینکه بعنوان دیتای فشرده شده این تصاویر معتبر باشن، کد خطرناک هم باشن!! برای اینکه بتونید این کار رو بکنید، باید به الگوریتم و جزییات فشرده سازی و درونیات کتابخانهء تصویر مورد استفاده احاطهء کامل داشته باشید و در سطح پایین کار کنید. یعنی یک دیتایی توی تصویر بذارید که بعد از اینکه توسط الگوریتم فشرده سازی کتابخانهء مورد نظر فشرده شد، به یک کد معنا دار javascript یا کد دیگری تبدیل بشه.
شاید فکر کنید این خیلی تخیلیه، ولی درواقع بنده با تحقیق در این مورد متوجه شدم که این مفهوم از قبل وجود داشته و به اطلاعاتی که همزمان در چند زبان/فرمت معتبر هستن Polyglot گفته میشه! ولی اطلاعات در این زمینه در وب بسیار کمه و من فقط یکی دو مقاله در این مورد پیدا کردم که این موضوع رو توضیح داده بودن یا اشاره کرده بودن، و همچنین حتی مثلا یک نمونه عکس gif هم یک طرفی درست کرده بود و گذاشته بود که در عین حالی که کد برنامه توش بود اما از نظر فرمت عکس هم کاملا بدون اشکال بود (دقت کنید که کدهای مورد نظر در متادیتای عکس نبودن و جزیی از دیتای اصلی خود تصویر بودن و بنابراین با حذف متادیتای تصویر نابود نمیشن)، ولی از طرف دیگر همون عکس رو اگر از کدی مشابه کد شما عبور میدادی اون کدهای خطرناک از بین میرفت! اما با این حال این هنوز ثابت نمیکنه که نمیشه کاری کرد که این سیستم رو دور زد. گفتم که این دیگه سواد و احاطهء خیلی بالا و مدتها کار خوره وار میخواد در زمینهء الگوریتم های فشرده سازی که ببینید آیا شدنی هست و کاری کنید که دیتایی که به تابع فشرده سازی وارد میشه بعد از اینکه فشرده شد به کدهای مورد نظر تبدیل بشه!
این کار یجورایی شبیه اینکه که مثلا بتونید کاری کنید که دیتای خاصی رو وقتی به الگوریتم هش md5 میدید، خروجی مورد نظر رو تولید کنه (مثلا خروجی هش بشه: abababababababababababababababab). البته فرقش اینه که یک الگوریتم هش مثل md5 چون برای مقاصد امنیتی ساخته شده در این زمینه بسیار مقاوم تره و احتمال زیاد حداقل تا 20 سال دیگه هم کسی نمیتونه چنین کاری بکنه، ولی درمورد الگوریتم های فشرده سازی طبیعتا نمیشه اینقدر مطمئن بود چون برای مقاصد امنیتی و مقاومت دربرابر اینطور چیزها ساخته نشدن!
اما همهء اینا که گفتم فعلا در حد تئوری هستن و از هکرهای عادی گمان نمیکنم کسی تونسته باشه تاحالا چنین کاری بکنه! هرچند زیاد هم نمیشه مطمئن بود!! در امنیت هیچوقت نمیشه زیاد مطمئن بود، مگر اینکه از روشهای علمی و اصولی تری به اطمینان بیشتری رسیده باشیم. شاید مثلا متخصصان NSA تونسته باشن به چنین چیزهایی دست پیدا کنن.
البته وجود کدهای خطرناک در عکس هم به خودی خودش خطری نداره. مثلا توی یک عکس اگر کد PHP باشه، ولی وب سرور درست کانفیگ شده باشه و پوشه ای که عکسها توش هست قابلیت اجرای PHP ازش گرفته شده باشه، دیگه چه باکی هست؟ تازه این مسئله معمولا وقتی اتفاق میفته که پسوند php از اسم تصویر فیلتر نشه، چون اگر پسوند php در نام عکس نباشه حتی اگر قابلیت اجرای php در اون پوشه وجود داشته باشه بازم بطور معمول خطری نداره (مگر اینکه وب سرور رو کانفیگ کرده باشید همهء فایلها یا همهء فایلها بجز فایلهای خاصی یا فایلها با پسوندهای غیراستاندارد دیگری رو بعنوان php اجرا کنه). یا مثلا کد جاوااسکریپت اگر توی عکسی باشه، خب اینم باز درواقع حفره و باگ و شیرین کاری مرورگر IE هست که در این زمینه مشکل ایجاد کرده، وگرنه مثلا چنین عکسی با مرورگر فایرفاکس هیچ خطری نداره چون فایرفاکس تصویر رو همیشه تصویر درنظر میگیره و کد جاوااسکریپت درون یک تصویر رو اصلا نمیبینه، چه برسه به اینکه بخواد اجراش کنه! اما باگ و حفره و طراحی غلط همیشه میتونه اتفاق بیفته، همونطور که در طراحی IE چنین اشتباهی کردن و این حفرهء امنیتی ایجاد شد، بنابراین بهتره که ما تاحدی که میتونیم و صرف میکنه، از ذخیره و انتقال چنین فایلهای دستکاری شده ای اجتناب کنیم.

حالا بعد از این همه توضیحات حتما گیج شدید و میگید آخرش نتیجه چی مختصر و مفید و تصمیم نهایی چی شد!
باید بگم نتیجهء نهایی اینکه این کد خاص شما فعلا در این حد مشکلی نداره، اما امنیت اون از نوع 100% اصولی و مطمئنی هم نیست، ولی برای کارهای عادی من و شما احتمالا زیاد هم هست و بهرحال فعلا نمیشه کار بیشتری هم کرد! پس اینو با خیال راحت استفاده کنید. البته درمورد فرمت های bitmap هشدار دادم که محافظتی ارائه نمیکنه، پس حواستون به این نکته باشه. حالا یا میتونید فرمتهای bitmap رو هیچوقت اجازه ندید، یا میتونید فایلهای bitmap رو به یک فرمت دارای فشرده سازی مثل png تبدیل و ذخیره کنید (اینطوری میشه اطمینان خیلی بیشتری بهش داشت). البته میتونید هم کلا بیخیال امنیت کلاینت بشید! ولی فکر نمیکنم زیاد فکر خوبی باشه، چون هنوز خیلی از ملت ممکنه از IE7/8 و این حرفها استفاده کنن (این مقاله رو ببینید: http://hamidreza-mz2.tk/?p=640).

بعدش هم بگم که این کد به تنهایی یک بخش کاره. بهتره درمورد بقیهء نکات امن سازی آپلود هم تحقیق بکنید. بحثی که من کردم فقط درمورد روش کار این کد خاص بود و هدفی که برآورده میکنه. اما اون بقیهء موارد هم چون دقیق یادم نیست نگفتم!
چون به هیچکدام از این روشها به تنهایی نمیشه کاملا مطمئن بود و اتکا کرد، پس چند روش رو با هم ترکیب میکنیم تا امنیت به حداکثر ممکن برسه، وگرنه ممکنه برای کاربرد خاص شما همین یک روش هم به تنهایی در عمل کافی باشه. بهرحال معمولا برنامه باید طوری طراحی بشه که اگر جای دیگر در شرایط دیگری استفاده شد یا در کانفیگی چیزی در برنامه یا سرور تغییری اعمال شد، امنیتش اینقدر شکننده و بر اساس فرض های نامطمئنی نباشه که براحتی و بدون اینکه متوجه بشیم دچار حفره بشه. مثلا شما الان فرمت bitmap ساپورت نمیکنی، ولی شاید بعدا حواست نباشه و به دلیلی این فرمت رو هم اضافه کنی، یا شاید کس دیگری که از کد و برنامهء شما استفاده خواهد کرد این کار رو بکنه.

golbafan
یک شنبه 10 اسفند 1393, 10:41 صبح
سلام کد شما بعلت استفاده از imagecopyresampled امنیت خوبی داره اما مشکل امنیتی که من میبینم اینه که موقع گرفتن فایل ، ولید بودن اون رو چک نکردید. (هکر) میتونه فایل غیر عکس رو هم با این روش به سرور شما تزریق کنه و البته شما اون رو بصورت عکس دریافت میکنید.
قبل از هر کاری برای چک کردن واقعی بودن فایل میتونید از کد زیر استفاده کنید:
اگر تابع به شما false برگردونه معلوم میشه فایل مشکل داره

$handle=imagecreatefromstring($data);

Weblove
یک شنبه 10 اسفند 1393, 14:56 عصر
ممنون از همه
جناب گلبافان
به نظرم نیاز نیست فرمت فایل بررسی بشه
چون فایلی روی هاست آپلود نمیشه ، فقط فایل ارسالی به اصطلاح write میشه