dindarloo

حسین دیندارلو

برنامه نویس و طراح وب
خانه درباره من سرویس ها خدمات نرم افزاری وبلاگ

فیلتر کردن عبارات در فرم ایمیل php

فیلتر کردن عباراتبلاک کردن ایمیل های حاوی عبارات خاص با فیلتر کردن عبارات خاص

در مطلب جلوگیری از تزریق هدر ایمیل در مورد حفره ی امنیتی email header injection در فرم های php گفتم. حال میخواهم بگویم چگونه ایمیل های حاوی عبارات Bcc و Cc و Content-Type را فیلتر کنیم تا ایمیل های حاوی این عبارات بلاک شود و از گزند تزریق هدر ایمیل در امان بمانیم.

راه حلی که میخواهم بگویم ورودی کاربر را برای عبارات مشکوک بررسی می کند و اگر عبارت مشکوکی پیدا شود متغیری برابر با true می شود ، سپس از این متغیر برای جلوگیری از ارسال ایمیل استفاده می شود.

دستورات شرطی php برای اجرای یک کد روی آزمایش های true و false تکیه دارند بنابر این برای فیلتر کردن عبارات مشکوک در فرم php باید یک متغیر بولین ایجاد کنیم که در صورت پیدا شدن عبارت مشکوک برابر با true شود و در غیر این صورت به صورت پیشفرض برابر با false باشد.

چگونه عبارات مشکوک را در فرم جستجو می کنیم ؟ این شناسایی با استفاده از یک الگوی جستجو یا عبارات منظم regular expression انجام می شود.

ابتدا متغیر را ایجاد می کنیم و برابر با false قرار می دهیم ، همچین عبارات مشکوک را تعیین می کنیم.

// متغیر بولین پیشفرض
$suspect = false;
// عبارت هایی که باید فیلتر شوند
$pattern = '/Content-Type:|Bcc:|Cc:/i';

رشته ی نسبت داده شده به $pattern چیست ؟ این یک رشته است برای انجام یک جستجوی غیر حساس به بزرگی و کوچکی حروف برای عبارت های زیر :

  • Content-Type
  • Bcc
  • Cc

این رشته ی متنی با یک فرمت خاص با نام عبارت منظم سازگار با پرل ( Perl-compatible Regular Ecpression )نوشته شده است. مخففش می شود PCRE

در این فرمت الگوی جستجو درون یک جفت اسلش / / معمولی قرار می گیرد و i بعد از اسلش آخر یعنی به بزرگی و کوچکی حروف حساس نباش

اکنون می توانیم از PCRE ذخیره شده در $pattern برای فیلتر کردن هر ورودی مشکوک در آرایه ی سوپر گلوبال $_POST استفاده کنیم. طبق مطالبی که پیش تر از این نوشته بودم و فرمی که روی آن آزمایش می کردیم $_POST حاوی یک رشته بود اما در آینده قصد دارم عناصر چند انتخابی مانند چک باکس را به فرم اضافه کنم که خود آن ها آرایه هستند ، پس هم باید در آرایه ی درون آرایه عبارات مشکوک را جستجو کنیم ، هم درون یک رشته.

بدین منظور یک تابع دلخواه میسازیم به نام isSuspect() و درون فایل پردازشگر ایمیل قرار می دهیم که در بالای صفحه اینکلود می کنیم.

// تابع بررسی کننده ی عبارات مشکوک
function isSuspect($val, $pattern, &$suspect) {
    // اگر مورد آرایه بود روی هر عنصر تکرار انجام شود
    // و دوباره به همان تابع ارجاع بده این خاصیت به خاطر امپرسند قبل از آرگومان سوم صورت می گیرد
    if (is_array($val)) {
        foreach ($val as $item) {
            // استفاده از خود تابع درون تابع یعنی تابع بازگشتی
            isSuspect($item, $pattern, $suspect);
        }
    } else {
        // اگر یک مورد مشکوک پیدا شد متغیر بولین برابر با ترو شود
        if (preg_match($pattern, $val)) {
            $suspect = true;
        }
    }
}

توضیح درمورد کد بالا :

نکته ی مهمی در کد بالا وجود دارد و آن آرگومان سوم است که دارای یک & امپرسند است. این بدین معنی است که هر تغییری در متغیر آرگومان سوم تابع یعنی $suspect ایجاد شد در تمام اسکریپت اعمال شود. این تکنیک با نام تحویل دادن به وسیله ی ارجاع passing by refrence شناخته می شود.

امکان دیگر این تابع چیزیست به نام تابع بازگشتی recursive function که تا وقتی که یک مقدار خاص توسط تابع پیدا شود که بتوان با regex مقایسه کرد این تابع به فراخوانی خود ادامه می دهد و وقتی یک مورد منطبق پیدا شود true برگردانده می شود.

تابع بازگشتی را به طور خلاصه می توان تابعی که خود را صدا می زند نامید و اغلب در مواقعی که با یک آرایه سر و کار داریم استفاده می شود. وقتی از تابعی درون خود تابع استفاده می کنیم از این خاصیت استفاده کرده ایم.

تابع را تعریف کردیم تمام. حال باید روی $_Post اجرایش کنیم تا بررسی اش کند

// آرایه و زیر آرایه ها را برای عبارات مشکوک بررسی کن
isSuspect($_POST, $pattern, $suspect);

نکته : این بار جلوی $suspect امپرسند وجود ندارد ، & تنها وقتی مورد نیاز بود که تابع را تعریف می کردیم.

اگر عبارت مشکوک پیدا شد $suspect برابر با true می شود کد پردازشگر سوپرگلوبال $_POST را درون یک دستور شرطی قرار می دهیم که وقتی پردازش شودکه مورد مشکوکی وجود نداشت.

اینجا کد پردازشگر ایمیل که خالی نبودن و اجباری بودن فیلد ها را چک میکرد درون یک دستور شرطی قرار می دهم.

if (!$suspect) {
    foreach ($_POST as $key => $value) {
		// هر فضای خالی را از ابتدا و انتهای مقادیر آرایه پاک میکنیم و آن را به یک متغیر نسبت می دهیم
		$temp = is_array($value) ? $value : trim($value);
		// اگر خالی و مورد نیاز بود به آرایه ی $missing اضافه شود
		// به صورت دینامیک یک متغیر متغیری ( متغیر بر حسب مقدار متغیر ) تعیین کرده و مقدارش را برابر با یک رشته ی خالی قرار می دهیم
		if (empty($temp) && in_array($key, $required)) {
			$missing[] = $key;
			${$key} = '';
		} elseif (in_array($key, $expected)) {
			// اگر کلید در مقادیر پیشفرض وجود دارد یک متغیر ب مبنای نام کلید به صورت دینامیک ایجاد کرده و مقدار $temp به آن نسبت داده می شود
			${$key} = $temp;
		}
	}
}

در اینجا توضیحی در مورد کد بالا بغیر از خط اول نمی دهم چون بقیه کد ها مربوط به آموزش پردازش فرم php است.

در خط اول گفتیم اگر $suspect برابر با true نبود فرم پردازش شود.

حال یک پیغام خطا هم در بالای صفحه ی فرم ایجاد می کنیم

<h2>فرم تامس</h2>
        <?php if ($_POST && $suspect) { ?>
            <p class="warning">متن خطای تزریق هدر ایمیل</p>
        <?php } elseif ($missing || $errors) { ?>
            <p class="warning">متن خطای خالی بودن فیلد ها</p>
        <?php } ?>

در اینجا بررسی می شود که آیا _$POST حاوی مقدار است یا نه ، این یعنی فرم ارسال شده یا نه و همزمان بررسی می کند آیا $suspect برابر با true است یا نه یعنی مشکوک است یا نه.

dindarloo
حسین دیندارلو
بزرگ ترین سرمایه گذاری ، سرمایه گذاری روی خودم بوده و هیچی اندازه ی خودم نتونسته حالم رو واقعا خوب کنه. حتی شادترین لحظه هایی که توسط دیگران به ارمغان آورده شده نمی ارزه به لحظه ای حال خوب که خودم ساخته باشم.

یک دیدگاه

  1. محمد گفت:

    مفید بود جوان

دیدگاه‌ها بسته شده‌اند.