• 1 رای - 5 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
امن کردن اطلاعات ورودی
#1
سلام
خوبید اساتید؟

یه سوال داشتم اینکه استفاده از filter_var هایی که خود php معرفی کرده برای امن کردن اطلاعات ورودی کافیه یه باید در کنارش از فیلتر هایی مثل preg_match
هم استفاده بشه؟
Cool
  پاسخ
تشکر شده توسط :
#2
1- تا حدودی تامین می کنه ولی کافی نیست... مخصوصاً اگر قراره با Unicode ها کار کنی و هندلشون کنی.
2- preg_match فیلتر نمیکنه، فقط چک می کنه! شما می خوای فقط چک کنی یا فقط فیلتر کنی؟ یا با چک کردن پیام بدی و در صورت تاییدشدن از چک، فیلترش هم بکنی؟ چون دو تا تابع غیر مرتبطن!
3- همچنین filter_var درواقع همون Regular expressions در پشت پرده(سورس موتور PHP) هستش... اگر نگاهی به تابع filter_var در سورس PHP بندازی، میبینی که با استفاده از Regular expressions ورودی رو هندل میکنه.
4- استفاده از filter_var ساده و صریح هستش و صرفه جویی در وقته. (مثل FILTER_VALIDATE_EMAIL) ولی نوشتن Regular expression کمی پیچیده تر و حرفه ای هستش.
5- توابع Regular expression اندکی سریعتر از filter_var هستن.
6- preg_match برای چک کردنه، اما filter_var برای فیلتر کردنه.
وبلاگ: Yousha.Blog.ir


 کد کمتر => خطای کمتر => قابل فهمتر => خوانایی بالاتر => نگهداری بهتر

  پاسخ
تشکر شده توسط : Alaa ayoubsys kasbookar
#3
نقل قول:- preg_match برای چک کردنه، اما filter_var برای فیلتر کردنه.
خیلی ممنون استاد شرمنده تقصیر من بود اینهمه به زحمت افتادید و نوشتید و جمل رو اشتباه نوشتم
پس نتیجه گرفتیم که استفاده از filter_var ها هم میتونه امنیت ورودیهامونو تامین کنه
خیلی خیلی ممنون
  پاسخ
تشکر شده توسط : Y.P.Y
#4
یه سوال دیگه فیلتر کردن به شکل زیر استاندارد هست؟
کد پی‌اچ‌پی:
filter_var($colorFILTER_SANITIZE_STRINGFILTER_FLAG_STRIP_LOW FILTER_FLAG_STRIP_HIGH); 
منظورم اینه با تغییر نسخه های php این کار صحیح هست؟ یا باید حتما از یکی از تنظیمات استفاده بشه مثل
کد پی‌اچ‌پی:
filter_var($_POST['test'], FILTER_SANITIZE_STRINGFILTER_FLAG_STRIP_LOW 
  پاسخ
تشکر شده توسط :
#5
اگر سوالت رو درست متوجه شده باشم، پس color عدد هستش و test رشته... درسته؟

مثال اولت:
کد پی‌اچ‌پی:
$color filter_var($colorFILTER_SANITIZE_NUMBER_INT); 
در صورتی که color عدد باشه! => پس خروجیش میشه اعداد + - => در غیر اینصورت خروجیش میشه FALSE
خلاصه شده سورس C همین فیلتر:
کد:
/* {{{ php_filter_number_int */
void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL)
{
    /* strip everything [^0-9+-] */
    const unsigned char allowed_list[] = "+-" DIGIT;


مثال دومت:
کد پی‌اچ‌پی:
$_POST['test'] = filter_var($_POST['test'], FILTER_SANITIZE_STRINGFILTER_FLAG_STRIP_LOW FILTER_FLAG_STRIP_HIGH
در صورتی که test رشته سالم باشه! => پس خروجیش میشه هرچیزی بجز", ', &, html tags, xml tags, scripting tags, <, >, ASCII chars -32, ASCII chars +127,\0 chars => در غیر اینصورت خروجیش میشه FALSE

نکته: FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH یعنی همه کاراکترهای برابر با مقدار عددی 32 تا 127 معتبر و سالم هستند، و بقیه باید حذف بش.
خلاصه شده سورس C همین فیلتر و آپشن هاش:
کد:
void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL)
{

    if (!(flags & FILTER_FLAG_NO_ENCODE_QUOTES)) {
        enc['\''] = enc['"'] = 1;
    }
    if (flags & FILTER_FLAG_ENCODE_AMP) {
        enc['&'] = 1;
    }
    if (flags & FILTER_FLAG_ENCODE_LOW) {
        memset(enc, 1, 32);
    }
    if (flags & FILTER_FLAG_ENCODE_HIGH) {
        memset(enc + 127, 1, sizeof(enc) - 127);
    }

    php_filter_encode_html(value, enc);

    /* strip tags, implicitly also removes \0 chars */
    new_len = php_strip_tags_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, NULL, 0, 1);


مقدار عددی(ASCII) کاراکتر ها:
[عکس: asciifull.gif]
[عکس: extend.gif]
وبلاگ: Yousha.Blog.ir


 کد کمتر => خطای کمتر => قابل فهمتر => خوانایی بالاتر => نگهداری بهتر

  پاسخ
تشکر شده توسط : kasbookar ayoubsys
#6
نقل قول:FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH: یعنی همه کاراکترهای برابر با مقدار عددی 32 تا 127 معتبر و سالم هستند، و بقیه باید حذف بش.

با این اوصاف با استفاده از کد تنظیمات بالا تمام حروفات فارسی هم فیلتر میشن و جایی براشون نیست

الان امتحان کردم وقتی از کد زیر استفاده میکنیم حروفات فارسی رو به کل فیلتر میکنه و در خروجی هیچی نشون نمیده
کد پی‌اچ‌پی:
filter_var($_POST['product_name'], FILTER_SANITIZE_STRINGFILTER_FLAG_STRIP_HIGH); 
اما با این کد حذف نمیکنه و میمونه حروف فارسی و نشون میده
کد پی‌اچ‌پی:
filter_var($_POST['product_name'], FILTER_SANITIZE_STRINGFILTER_FLAG_STRIP_LOW); 

حالا اینجا حتما بازه عدددی کاراکتری LOW & HIGH فرق میکنه یکی سخت گیر تره یکی نه
  پاسخ
تشکر شده توسط :
#7
نقل قول:حالا اینجا حتما بازه عدددی کاراکتری LOW & HIGH فرق میکنه یکی سخت گیر تره یکی نه
به سخت گیری آسون گیری نیست، به بازه کاراکترهایی هست که شاملشون میشه... در پایین توضیح میدم:

نقل قول:با این اوصاف با استفاده از کد تنظیمات FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH تمام حروفات فارسی هم فیلتر میشن و جایی براشون نیست
درسته
کاراکترهای بازه آپشن FILTER_FLAG_STRIP_LOW اکثراً تهی/NULL هستن... که این شامل newline هم میشه.
در صورتی که کاراکترهای بازه آپشن FILTER_FLAG_STRIP_HIGH اکثراً Unicode ها(فارسی هندی ژاپنی...) هستن -> که در بین این کاراکترها، کاراکترهای مخرب هم وجود داره! مثل 0xE0 که دو کاراکتر رو از آخر رشته حذف میکنه.
وبلاگ: Yousha.Blog.ir


 کد کمتر => خطای کمتر => قابل فهمتر => خوانایی بالاتر => نگهداری بهتر

  پاسخ
تشکر شده توسط : kasbookar ayoubsys
#8
پس یا باید از اینها استفاده نکنیم یا دور فارسی رو خط بکشیم
php راهی برای این فیلتر نداره؟ یا باید بجای این از preg_match , replace استفاده کنیم(مقایسه و جایگزین)
یا راه بهتری هم هست؟
  پاسخ
تشکر شده توسط :
#9
خیر اینطور نیست... نه در مورد filter_var و نه در مورد Regular exp ها
filter_var صرفاً برای امن کردن نیست، بلکه برای فیلتر کردن هستش. اما این فیلتر کردن خودش قسمت زیادی از امنیت رو مهیا میکنه. (نه همشو، ولی قسمت زیادیشو)
(مثلاً برای تایید ایمیل توسط FILTER_VALIDATE_EMAIL، ایمیل بر اساس قالب استاندارد RFC چک میشه و نه بر اساس قالب ضد XSS یا قالب ضد SQL Injection و غیره...)

اگر هم به نام این توابع و پارامتر هاشون دقت کنی نوشته Validate, Filter و نه Safe, Secure...

پس شما باید همیشه فیلتر سازی دیتا رو انجام بدی(حتی اگر مسله امنیت در میون نباشه) تا منطق برنامت درست پیش بره و خطا/exception ایجاد نکنه (حتی غیر عمد)
و برای مقابله با اون دسته از حملات، باید برای هرکدوم تدابیر جداگانه ای اتخاذ کنی. (اگر پروژت خیلی خیلی مهم و حساسه)

مثلاً:
در htmlentities حتاالمکان باید از ENT_QUOTES و encoding نوع UTF-8 استفاده بشه
حتماً از PDO استفاده بشه، اونم با با آپشن ATTR_EMULATE_PREPARES FALSE
حتاالمکان charset و names دیتابیس utf8 یا utf8mb4 باشه
در استفاده از سیستم قالب twig باید از تگ های {% autoescape 'TYPE' %} استفاده بشه
اگر قراره کاربر از HTML استفاده کنه، بهتره در پروژه از http://htmlpurifier.org استفاده بشه

https://github.com/paragonie/easydb - یه DAL خوب و تقربیاً safe
https://github.com/paragonie/anti-csrf - یه کتابخونه خوب ضد CSRF


اینم توضیحات یکسری توابع که توقع بیش از اندازه ازشون نداشته باشی:
addslashes() = فقط اسلش در کنار بک اسلش قرار میده
stripslashes() = فقط اسلش ها رو حذف میکنه
mysql_real_escape_string = فقط برای ایمن سازی مقدماتی رشته در هنگام insert شدن به دیتابیس استفاده میشه.
strip_tags() = فقط تگ های HTML رو حذف میکنه
htmlspecialchars() = فقط برای نمایش کد و تگ هستش بدون اینکه execute بشن. مثل همین تگ کد در انجمن ها
کد:
<b>
<hr>
<?php ?>
وبلاگ: Yousha.Blog.ir


 کد کمتر => خطای کمتر => قابل فهمتر => خوانایی بالاتر => نگهداری بهتر

  پاسخ
تشکر شده توسط : kasbookar ayoubsys
#10
http://php.net/manual/en/function.mb-check-encoding.php
^ برای چک کردن رشته از encoding خاص
http://php.net/manual/en/function.mb-con...coding.php
^ برای تبدیل رشته به encoding خاص (که میتونه بازه ای از کاراکترهای نامعتبر/خطرناک رو حذف کنه)


http://php.net/manual/en/function.iconv.php
^ برای تبدیل رشته به encoding خاص (که میتونه بازه ای از کاراکترهای نامعتبر/خطرناک رو حذف کنه)
بدون که تابع setlocale میتونه خروجیش رو عوض کنه
همچنین این تابع بازه متفاوتی در سیستم عامل های متفاوت داره و رفتارهای احمقانه ای هم داره! بجای رشته، null میده، بجای false/true خطا میده و... پس در موارد مشابه تابع mb-convert-encoding انتخاب بهتر و ایمن تریه.


کد:
<form accept-charset="UTF-8" action="#" method="post">
^ accept-charset (که میتونه تعدادی از کاراکترهای نامعتبر/خطرناک رو خنثی کنه)
اگر نذاری، در HTML 4 به قبل مقدار پیشفرضش Unknown هستش، در HTML 4 مقدار پیشفرضش 8859-1 هستش، در HTML 5 مقدار پیشفرضش UTF-8 هستش.


نقل قول:W3: The best way to deal with encoding issues in HTML forms is to serve all your pages in UTF-8. UTF-8 can represent the characters of the widest range of languages. Browsers send back form data in the same encoding as the page containing the form, so the user can fill in data in whatever language and script they need to.


کد پی‌اچ‌پی:
function isUTF8($input_string)
{
    
// http://www.w3.org/International/questions/qa-forms-utf-8.en.php
    
return preg_match('%^(?:
        [\x09\x0A\x0D\x20-\x7E]              # ASCII
        | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
        |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
        |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
        |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
        | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
        )*$%xs'
$input_string);



http://forum.iranphp.org/Thread-%D8%AA%D...B%8C-UTF-8
مال سال 89 هه Big Grin
وبلاگ: Yousha.Blog.ir


 کد کمتر => خطای کمتر => قابل فهمتر => خوانایی بالاتر => نگهداری بهتر

  پاسخ
تشکر شده توسط : kasbookar


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان