كنترل های Validation در ASP.NET

بررسی و ارزيابی صحت اطلاعات ورودی توسط كاربران ، يكی از عمليات بسيار مهم در برنامه های كامپيوتری خصوصا" برنامه های وب با توجه به ماهيت معماری آنها می باشد . پياده كنندگان برنامه های وب می بايست پس از درج داده ورودی توسط كاربر و قبل از ارسال آن به لايه های ديگر ، آنها را ارزيابی و صرفا" پس از تائيد ، پردازش های مورد نياز را بر روی آنها انجام دهند . اعتقاد عملی به سياست فوق باعث پيشگيری تعداد زيادی از حملات در برنامه های‌ وب می گردد . در
سه‌شنبه، 8 بهمن 1387
تخمین زمان مطالعه:
موارد بیشتر برای شما
كنترل های Validation در ASP.NET
كنترل های Validation در ASP.NET
كنترل های Validation در ASP.NET

بررسی و ارزيابی صحت اطلاعات ورودی توسط كاربران ، يكی از عمليات بسيار مهم در برنامه های كامپيوتری خصوصا" برنامه های وب با توجه به ماهيت معماری آنها می باشد . پياده كنندگان برنامه های وب می بايست پس از درج داده ورودی توسط كاربر و قبل از ارسال آن به لايه های ديگر ، آنها را ارزيابی و صرفا" پس از تائيد ، پردازش های مورد نياز را بر روی آنها انجام دهند . اعتقاد عملی به سياست فوق باعث پيشگيری تعداد زيادی از حملات در برنامه های‌ وب می گردد . در صورت عدم رعايت موارد اشاره شده ، شرايط لازم به منظور سوء استفاده از پتانسيل فوق فراهم و مهاجمان می توانند با بهره برداری از نقاط ضعف موجود ، حملات خود را برنامه ريزی نمايند .
در اين مقاله به بررسی امكانات ارائه شده در ASP.NET به منظور ارزيابی صحت داده ورودی خواهيم پرداخت . آشنائی و بكارگيری روش های مناسب به منظور بررسی صحت داده ورودی يكی از عمليات مهم در جهت ايمن سازی برنامه های وب نيز می باشد . پس با انگيزه و دقت مضاعف كار را دنبال می نمائيم .

ضرورت و ماهيت كنترل های Validation

زمانی كه از يك TextBox برای درج داده بر روی‌ يك فرم استفاده می گردد ،‌ همواره اين احتمال وجود خواهد داشت كه كاربران اطلاعات را متناسب با انتظار يك برنامه وارد نمايند . به عنوان مثال ،‌ فرض كنيد كه در يك فرم وب از دو TextBox برای درج داده عددی توسط كاربران استفاده شده است و در ادامه می بايست اطلاعات ورودی در اختيار يك روتين جهت انجام پردازش های مورد نياز ( به عنوان نمونه ، انجام عمليات محاسباتی بر روی داده های ورودی ) قرار داده شود . در صورتی كه كاربران داده را در محدوده مجاز وارد ننمايند و يا ورودی از نوع عددی نباشد ، روتين مورد نظر در انجام پردازش های خود با مشكل مواجه خواهد شد . بنابراين ، می بايست همواره قبل از اين كه داده ورودی در اختيار روتين های مورد نظر جهت انجام پردازش های مشخص شده قرار داده شود ، آنها را بررسی و در صورت رعايت مجموعه سياست های تعريف شده ، امكان استفاده از آنها را برای اسكريپت ها فراهم نمود .
به منظور ارزيابی داده ورودی توسط كاربران با توجه به داده مورد نياز اسكريپت ها ،‌ از روش های متعددی می توان استفاده نمود . متداولترين نياز ، وجود يك مقدار ورودی است . در چنين مواردی ، انتظار داريم قبل از اين كه يك اسكريپت بتواند پردازش های مورد نياز را بر روی داده ورودی انجام دهد، در TextBox مقداری درج شده باشد. ماهيت داده ورودی در اين مقطع مهم نمی باشد و مهم اين است كه داده ئی توسط كاربر در مكان مورد نظر وارد شده باشد . در برخی موارد لازم است كه داده ورودی از يك نوع خاص باشد ( به عنوان نمونه يك مقدار عددی ) تا بتوان آن را در اختيار روتين های مورد نظر به منظور انجام پردازش های محاسباتی قرار داد . در برخی موارد ديگر ، لازم است كه داده ورودی در يك محدوده خاص باشد و داده درج شده خارج از محدوده مورد نظر ، غيرمعتبر گردد .
برای بررسی و ارزيابی صحت داده در ASP.NET مجموعه ای از كنترل های validation ارائه شده است . از كنترل های فوق می توان به منظور بررسی و تست عدم درج داده ، مقايسه داده ورودی با يك مقدار خاص ، بررسی وجود مقادير در يك محدوده خاص و ساير فرم های داده استفاده نمود تا اين اطمينان ايجاد گردد كه داده مناسب و معتبر در اختيار اسكريپت ها و به منظور انجام پردازش ها قرار داده می شود .
كنترل های validation در ارتباط مستقيم با كنترل TextBox بوده و تست و ارزيابی خود را بطور اتوماتيك و پس از كليك بر روی كنترل هائی نظير Button ، LinkButton و ImageButton انجام خواهند داد . در صورتی كه ماحصل بررسی يك كنترل validation توام با موفقيت نباشد ، validator يك پيام خطاء را نمايش و به كاربران اعلام می نمايد كه داده ورودی فاقد شرايط لازم برای استفاده در برنامه می باشد .
در ادامه به بررسی كنترل های فوق خواهيم پرداخت .

كنترل <asp:RequiredFieldValidator>

متداولترين نوع ارزيابی داده ورودی ، بررسی آن به منظور اطمينان از درج داده توسط كاربر است . كنترل <asp:RequiredFieldValidator> ، مسئوليت بررسی داده ورودی در يك Textbox را برعهده گرفته و در صورت عدم درج داده توسط كاربر ، يك پيام خطاء را نمايش خواهد داد . در چنين مواردی ، روتين هائی كه می بايست پس از كليك بر روی دكمه موجود از داده درج شده در TextBox استفاده نمايند ، فرصت انجام چنين كاری را به دليل عدم درج داده توسط كاربر پيدا نخواهند كرد .

شكل عمومی

شكل عمومی كنترل فوق به صورت زير است :

<asp:RequiredFieldValidatorid="id" Runat="Server"
   ControlToValidate="controlID"
   Display="Dynamic|None|Static"
   ErrorMessage="string"
   SetFocusOnError="False|True"
   ValidationGroup="name"
/>

توضيحات

• از يك id صرفا" زمانی استفاده می شود كه قرار است به كنترل از طريق اسكريپپ مراجعه گردد .
• به خصلت ControlToValidate ، مقدار id كنترل textBox كه مسئوليت بررسی آن به كنترل RequiredFieldValidator واگذار شده است ،‌نسبت داده می شود.
• خصلت ErrorMessage ، پيام مورد نظر در صورت بروز خطاء را مشخص می نمايد .
• خصلت SetFocusOnErrorMessage ، يك blinking cursor را در كنترل TextBox مربوطه به منظور تسهيل در امر درج داده جديد قرار می دهد .
• خصلت ValidationGroup يك گروه از كنترل های TextBox را كه مجموعه ای از تست های بررسی روی آنها اعمال خواهد شد ، مشخص می نمايد (در مواردی كه دكمه های متفاوت می توانند باعث فعال شدن تست های مختلفی گردند ) .
• خصلت Display : كنترل RequiredFieldValidator ، يك فضای افقی را متناسب با طول رشته مربوط به پيام خطاء اشغال خواهد كرد . در اغلب موارد ، پيام خطاء در كنار TextBox مربوطه نمايش داده می شود . مكان فوق بر روی صفحه همواره نشان داده خواهد شد ( ولو اين كه خطائی اتفاق نيافتد ) . در صورتی كه مقدار خصلت Display معادل Dynamic در نظر گرفته شود ، مكانی برای نمايش پيام خطاء رزو نخواهد شد و بطور پويا و همزمان با بروز خطاء ايجاد می گردد .
مثال
در اين مثال زمانی كه كاربر بر روی button كليك نمود ، كنترل RequiredFieldValidator بطور اتوماتيك عمليات بررسی و ارزيابی داده ورودی در TextBox را آغاز می نمايد ( قبل از اين كه روتين Get_Data فراخوانده شود ) . در صورتی كه TextBox خالی باشد ،‌ يك پيام خطاء نمايش داده شده و cursor مجددا" در TextBox قرار خواهد گرفت . در صورتی كه در TextBox داده ئی توسط كاربر درج گردد ، تست ارزيابی با موفقيت انجام و روتين مربوط فراخوانده شده و مقدار ورودی را در خروجی نمايش خواهد داد . در اين مثال ، مقدار خصلت Display كنترل RequiredFieldValidator ،‌ معادل Dynamic در نظر گرفته شده است ، بنابراين در صورت عدم توليد يك پيام خطاء ، مكانی بر روی صفحه برای نمايش آن در نظر گرفته نخواهد شد . بدين ترتيب به كنترل label اجازه داده می شود كه در كنار TextBox نمايش داده شده و از فضای مشابه پيام خطاء استفاده نمايد ( استفاده مشترك از يك مكان بر روی فرم وب به منظور نمايش پيام خطاء و يا داده ورودی توسط كاربر ) .

<SCRIPT Runat="Server">

    Sub Get_Data (Src As Object, Args As EventArgs)
       Output.Text = "You entered '" & MyTextBox.Text & "'"
    End Sub

</SCRIPT>

<form Runat="Server">

<asp:TextBox id="MyTextBox" Runat="Server"/>
<asp:Button Text="Submit" OnClick="Get_Data" Runat="Server"/>
<asp:RequiredFieldValidator Runat="Server"
   ControlToValidate="MyTextBox"
   ErrorMessage="Please enter a data value"
   Display="Dynamic"
   SetFocusOnError="True"/>
<asp:Label id="Output" Runat="Server"/>

</form>

كنترل <asp:RangeValidator>

كنترل فوق مسئوليت بررسی و ارزيابی داده ورودی در يك TextBox را برعهده گرفته و ماموريت آن حصول اطمينان از اين موضوع است كه داده درج شده در محدوده مورد نظر است . اين محدوده توسط دو خصلت MinimumValue و MaximumValue مشخص می گردد . فرآيند فوق می تواند در ارتباط با نوع های متفاوت داده نظير Date ، اعداد صحيح ، اعداد اعشاری و يا رشته ( مقدار پيش فرض ) اعمال گردد .

شكل عمومی

شكل عمومی كنترل فوق به صورت زير است :

<asp:RangeValidatorid="id" Runat="Server"
   ControlToValidate="controlID"
   Display="Dynamic|None|Static"
   ErrorMessage="string"
   MaximumValue="value"
   MinimumValue="value"
   SetFocusOnError="False|True"
   Type="Currency|Date|Double|Integer|String"
   ValidationGroup="name"
/>

توضيحات

• از يك id صرفا" زمانی استفاده می شود كه قرار است به كنترل از طريق اسكريپپ مراجعه گردد .
• خصلت ErrorMessage ، پيام مورد نظر در صورت بروز خطاء را مشخص می نمايد .
• خصلت SetFocusOnErrorMessage ، يك blinking cursor را در كنترل TextBox مربوطه به منظور تسهيل در امر درج داده جديد قرار می دهد .
• خصلت ValidationGroup يك گروه از كنترل های TextBox را كه مجموعه ای از تست های بررسی روی آنها اعمال خواهد شد ، مشخص می نمايد (در مواردی كه دكمه های متفاوت می توانند باعث فعال شدن تست های مختلفی گردند ) .
• خصلت Display : كنترل RangeValidator ، يك فضای افقی را متناسب با طول رشته مربوط به پيام خطاء اشغال خواهد كرد . در اغلب موارد ، پيام خطاء در كنار TextBox مربوطه نمايش داده می شود . مكان فوق بر روی صفحه همواره نشان داده خواهد شد ( ولو اين كه خطائی اتفاق نيافتد ) . در صورتی كه مقدار خصلت Display معادل Dynamic در نظر گرفته شود ، مكانی برای نمايش پيام خطاء رزو نخواهد شد و بطور پويا و همزمان با بروز خطاء ايجاد می گردد .
• خصلت Type : در صورتی كه نوع داده ورودی مشخص نگردد ،‌ نوع آن به صورت پيش فرض string در نظر گرفته خواهد شد . يك TextBox خالی ، به عنوان يك نوع داده معتبر ارزيابی خواهد شد . بنابراين ، لازم است كه به همراه كنترل RangeValidator از يك كنترل RequiredFieldValidator نيز استفاده گردد تا اين اطمينان حاصل شود كه با عدم درج داده در TextBox مربوطه با آْن به عنوان يك داده معتبر برخورد نخواهد شد .
• خصلت های MinimumValue و MaximumValue ، حداقل و حداكثر محدوده مجاز برای داده ورودی را مشخص می نمايند .
مثال
در اين مثال به منظور ارزيابی و تست داده ورودی در يك TextBox از دو كنترل RangeValidator و RequiredFieldValidator استفاده شده است . بنابراين می بايست حتما" در TextBox مقداری درج گردد . با توجه به اين كه مقدار خصلت Type معادل integer و مقادير خصلت های MinimumValue و MaximumValue به ترتيب صفر و نه در نظر گرفته شده اند ،‌داده ورودی می بايست عددی بين صفر تا نه باشد .

<SCRIPT Runat="Server">

   Sub Get_Data (Src As Object, Args As EventArgs)
      Output.Text = "You entered '" & MyTextBox.Text & "'"
   End Sub

</SCRIPT>

<form Runat="Server">

Enter a value between 0 and 9:<br/>
<asp:TextBox id="MyTextBox" Runat="Server"/>
<asp:Button Text="Submit" OnClick="Get_Data" Runat="Server"/>
<asp:RangeValidatorRunat="Server"
   ControlToValidate="MyTextBox"
   Type="Integer"
   MinimumValue="0"
   MaximumValue="9"
   ErrorMessage="Please enter an integer in the range 0 to 9"
   Display="Dynamic"
   SetFocusOnError="True"/>
<asp:RequiredFieldValidator Runat="Server"
    ControlToValidate="MyTextBox"
    ErrorMessage="Please enter a data value"
    Display="Dynamic"
    SetFocusOnError="True"/>
<asp:Label id="Output" Runat="Server"/>

</form>

كنترل <asp:CompareValidator>

كنترل فوق مسئوليت بررسی‌ مقدار درج شده در يك TextBox را برعهده دارد . بدين منظور داده ورودی با يك مقدار خاص و يا مقدار يك كنترل موجود بر روی فرم مقايسه می گردد . نوع داده درج شده در TextBox می تواند از نوع Currency ، Date ، اعشاری ، صحيح و يا رشته ( مقدار پيش فرض ) باشد .

شكل عمومی

شكل عمومی كنترل فوق به صورت زير است :

<asp:CompareValidatorid="id" Runat="Server"
ControlToCompare="controlID"
ControlToValidate="controlID"
Display="Dynamic|None|Static"
ErrorMessage="string"
Operator="Equal|NotEqual|GreaterThan|GreaterThanEqual|LessThan
                  |LessThanEqual|DataTypeCheck"
SetFocusOnError="False|True"
Type="Currency|Date|Double|Integer|String"
ValidationGroup="name"
ValueToCompare="value"
/>

توضيحات

• از يك id صرفا" زمانی استفاده می شود كه قرار است به كنترل از طريق اسكريپپ مراجعه گردد .
• به خصلت ControlToValidate ، مقدار id كنترل textBox كه مسئوليت بررسی آن به كنترل <asp:CompareValidator> واگذار شده است ،‌نسبت داده می شود.
• خصلت ErrorMessage ، پيام مورد نظر در صورت بروز خطاء را مشخص می نمايد .
• خصلت SetFocusOnErrorMessage ، يك blinking cursor را در كنترل TextBox مربوطه به منظور تسهيل در امر درج داده جديد قرار می دهد .
• خصلت ValidationGroup يك گروه از كنترل های TextBox را كه مجموعه ای از تست های بررسی روی آنها اعمال خواهد شد ، مشخص می نمايد (در مواردی كه دكمه های متفاوت می توانند باعث فعال شدن تست های مختلفی گردند ) .
• خصلت Display : كنترل <asp:CompareValidator> ، يك فضای افقی را متناسب با طول رشته مربوط به پيام خطاء اشغال خواهد كرد . در اغلب موارد ، پيام خطاء در كنار TextBox مربوطه نمايش داده می شود . مكان فوق بر روی صفحه همواره نشان داده خواهد شد ( ولو اين كه خطائی اتفاق نيافتد ) . در صورتی كه مقدار خصلت Display معادل Dynamic در نظر گرفته شود ، مكانی برای نمايش پيام خطاء رزو نخواهد شد و بطور پويا و همزمان با بروز خطاء ايجاد می گردد .
• مقدار ورودی می تواند با يك مقدار مشخص شده توسط خصلت ValueToCompare و يا مقدار يك كنترل ديگر موجود در صفحه ( مشخص شده توسط خصلت ControlToCompare ) ، مقايسه گردد . به صورت پيش فرض ، عمليات مقايسه برای "برابری " انجام خواهد شد . در صورت نياز می توان از ساير عملگرهای مقايسه ای كه توسط خصلت Operator مشخص می گردند ، استفاده نمود . عمليات مقايسه بر اساس نوع داده درج شده در Textbox كه توسط خصلت Type مشخص می گردد ، انجام خواهد شد .
• خصلت Type : در صورتی كه نوع داده ورودی مشخص نگردد ،‌ نوع آن به صورت پيش فرض string در نظر گرفته خواهد شد . يك TextBox خالی ، به عنوان يك نوع داده معتبر ارزيابی خواهد شد . بنابراين ، لازم است كه به همراه كنترل <asp:CompareValidator> از يك كنترل RequiredFieldValidator نيز استفاده گردد تا اين اطمينان حاصل شود كه با عدم درج داده در TextBox مربوطه با آْن به عنوان يك داده معتبر برخورد نخواهد شد .
مثال
در اين مثال ، كاربر می بايست يك عدد مثبت را وارد نمايد و در صورتی كه مقدار ورودی منفی باشد يك پيام خطاء نمايش داده می شود . به همراه كنترل CompareValidator از يك كنترل RequiredFieldValidator نيز استفاده شده است تا عدم درج داده ( خالی‌بودن ) به عنوان يك داده معتبر ارزيابی نگردد .
مقدار ورودی می بايست از نوع اعشاری (Type=Double ) و بزرگتر از (Operator=GreaterThan ) صفر (ValueToCompare=0 ) باشد تا به عنوان يك داده معتبر ارزيابی گردد .

<SCRIPT Runat="Server">

Sub Get_Data (Src As Object, Args As EventArgs)
    Output.Text = "You entered '" & MyTextBox.Text & "'"
End Sub

</SCRIPT>

<form Runat="Server">

 Enter a positive number:<br/>
<asp:TextBox id="MyTextBox" Runat="Server"/>
<asp:Button Text="Submit" OnClick="Get_Data" Runat="Server"/>
<asp:CompareValidatorRunat="Server"
   ControlToValidate="MyTextBox"
   ValueToCompare="0"
   Type="Double"
   Operator="GreaterThan"
   ErrorMessage="Please enter a number greater than 0"
   Display="Dynamic"
   SetFocusOnError="True"/>
<asp:RequiredFieldValidator Runat="Server"
   ControlToValidate="MyTextBox"
   ErrorMessage="Please enter a data value"
   Display="Dynamic"
   SetFocusOnError="True"/>
<asp:Label id="Output" Runat="Server"/>

</form>

كنترل <asp:CustomValidator>

در زمان بررسی و ارزيابی داده ورودی ممكن است به مواردی برخورد نمائيم كه با تركيب يك RequiredFieldValidator ، RangeValidator و يا CompareValidator خواسته ما تامين نگردد. در چنين مواردی می توان از كنترل <asp:CustomValidator> به منظور انجام تست های اضافه استفاده نمود .

شكل عمومی

شكل عمومی كنترل فوق به صورت زير است :

<asp:CustomValidatorid="id" Runat="Server"
ControlToValidate="controlID"
Display="Dynamic|None|Static"
ErrorMessage="string"
SetFocusOnError="False|True"
ValidationGroup="name"
OnServerValidate="subprogram"
/>

توضيحات

• خصلت های كنترل <asp:CustomValidator> مشابه ساير كنترل های validation می باشند با اين تفاوت كه از خصلت OnServerValidate به منظور فراخوانی يك برنامه فرعی برای بررسی و ارزيابی داده ورودی نيز استفاده می گردد .
• يك TextBox خالی به عنوان يك داده معتبر در نظر گرفته خواهد شد . بنابراين می بايست به همراه كنترل CustomValidator از يك كنترل RequiredFieldValidator نيز استفاده گردد تا عدم درج داده به عنوان يك داده معتبر ارزيابی نگردد .
• برنامه فرعی صدا زده شده دارای آرگومان های خاص ServerValidateArgs می باشد . در صورتی كه بررسی و ارزيابی صحت داده ورودی توام با موفقيت نباشد ، مقدار خصلت IsValid معادل false خواهد شد . از آرگومان Value ، به عنوان مرجعی به منظور مراجعه به مقدار TextBox ( كنترل مشخص شده توسط خصلت ControlToValidate ) استفاده می گردد .
• خصلت ErrorMessage ، پيام مورد نظر در صورت بروز خطاء را مشخص می نمايد .
• خصلت SetFocusOnErrorMessage ، يك blinking cursor را در كنترل TextBox مربوطه به منظور تسهيل در امر درج داده جديد قرار می دهد .
• خصلت ValidationGroup يك گروه از كنترل های TextBox را كه مجموعه ای از تست های بررسی روی آنها اعمال خواهد شد ، مشخص می نمايد (در مواردی كه دكمه های متفاوت می توانند باعث فعال شدن تست های مختلفی گردند ) .
• خصلت Display : كنترل <asp:CustomValidator> ، يك فضای افقی را متناسب با طول رشته مربوط به پيام خطاء اشغال خواهد كرد . در اغلب موارد ، پيام خطاء در كنار TextBox مربوطه نمايش داده می شود . مكان فوق بر روی صفحه همواره نشان داده خواهد شد ( ولو اين كه خطائی اتفاق نيافتد ) . در صورتی كه مقدار خصلت Display معادل Dynamic در نظر گرفته شود ، مكانی برای نمايش پيام خطاء رزو نخواهد شد و بطور پويا و همزمان با بروز خطاء ايجاد می گردد .
مثال
در اين مثال به منظور ارزيابی و تست داده ورودی در يك TextBox از دو كنترل CustomValidator و RequiredFieldValidator استفاده شده است . داده ورودی می بايست يك عدد صحيح بين صفر تا نود و نه باشد .
پس از كليك بر روی دكمه Submit ، روتين Get_Data فعال و قبل از هر چيز عمليات بررسی و ارزيابی صحت داده ورودی انجام خواهد شد . كنترل RequiredFieldValidator در ابتدا بررسی لازم در خصوص درج داده در TextBox را انجام و در ادامه روتين Validate_TextBox توسط خصلت OnServerValidate كنترل CustomValidator فراخوانده می شود . روتين فوق ، تست های لازم را بر روی داده ورودی انجام خواهد داد ( برای مراجعه به داده ورودی از Args.Value استفاده شده است ) . در صورتی كه هر يك از تست های انجام شده توام با موفقيت نباشد ، خصلت Args.Isvalid مقدار false را خواهد گرفت ( داده ورودی می بايست يك عدد مثبت بين صفر تا نود و نه باشد ) .
پس از انجام فرآيند بررسی داده ورودی ، روتين Get_Data ، اجرا خواهد شد . روتين فوق در ابتدا و پس از كليك بر روی دكمه button فراخوانده می گردد و اجرای آن تا زمانی كه عمليات بررسی و ارزيابی داده ورودی به اتمام نرسيده باشد ، به تاخير خواهد افتاد . پردازش های انجام شده در روتين Get_Data مشروط به انجام موفقيت آميز تست ارزيابی و صحت داده است . بنابراين ، همه چيز وابسته به شرط Page.IsValid شده است و در صورتی كه Args.IsValid معادل false شده باشد ، مقدار Page.IsValid نيز false خواهد شد.

<SCRIPT Runat="Server">

 Sub Validate_TextBox (Src As Object, Args As ServerValidateEventArgs)

  If Not IsNumeric(Args.Value) Then
      MyValidator.ErrorMessage = "Please enter a number"
      Args.IsValid = False
    Else
    If Not Args.Value Mod 1 = 0 Then
       MyValidator.ErrorMessage = "Please enter an integer"
       Args.IsValid = False
   End If
   If Args.Value < 0 Then
      MyValidator.ErrorMessage = "Please enter a positive integer"
      Args.IsValid = False
   End If
   If Args.Value > 99 Then
     MyValidator.ErrorMessage = "Please enter a positive integer between 0 and 99"
     Args.IsValid = False
   End If
 End If

End Sub

Sub Get_Data(Src As Object, Args As EventArgs)

If Page.IsValid Then
   Output.Text = "You entered '" & MyTextBox.Text & "'"
End If

End Sub

</SCRIPT>

<form Runat="Server">

Enter a positive integer:<br/>
<asp:TextBox id="MyTextBox" Runat="Server"/>
<asp:Button Text="Submit" OnClick="Get_Data" Runat="Server"/>
<asp:CustomValidator id="MyValidator" Runat="Server"
   ControlToValidate="MyTextBox"
   Display="Dynamic"
   SetFocusOnError="True"
   OnServerValidate="Validate_TextBox"/>
<asp:RequiredFieldValidator Runat="Server"
   ControlToValidate="MyTextBox"
   ErrorMessage="Please enter a data value"
   Display="Dynamic"
   SetFocusOnError="True"/>
<asp:Label id="Output" Runat="Server"/>

</form>

گروه های validation

در زمان پياده سازی فرم های ورود اطلاعات به مواردی برخورد خواهيم كرد كه لازم است از چندين TextBox به منظور دريافت داده ورودی جهت انجام پردازش های مورد نياز در يك اسكريپت ، استفاده گردد .همچنين ، ممكن است در مواردی لازم باشد كه از چندين button در يك فرم ورود اطلاعات استفاده گردد و متناسب با اين كه كدام button توسط كاربران فعال شده است ، بررسی و صحت داده ورودی تعداد خاصی از كنترل های موجود بر روی فرم ورود اطلاعات ( مستقل از ساير كنترل ها ) ، انجام شود . در چنين مواردی می بايست تمامی كنترل هائی را كه می خواهيم پس از كليك بر روی يك button خاص ، validate شوند را عضوء يك گروه نمود و نام آن گروه را برای button مورد نظر نيز مشخص نمود . بدين ترتيب ، پس از كليك بر روی button مورد نظر صرفا" آندسته از كنترل هائی كه عضوء گروه هم نام با گروه معرفی شده به همراه button می باشند ، بررسی و ارزيابی خواهند شد .
مثال
در فرم ورود اطلاعات زير از چندين كنترل ( چهار كنترل TextBox ) استفاده شده است كه تمامی آنها عضوء يك گروه validation می باشند . پس از كليك بر روی دكمه "ارسال اطلاعات " ، صرفا" آندسته از كنترل هائی كه كنترل های validation آنها عضوء گروه مشخص شده می باشند ، validate خواهند شد .
فرم ورود اطلاعات : استفاده از چهار كنترل TextBox كه تمامی آنها عضوء يك گروه Validation می باشند

<SCRIPT Runat="Server">

Sub Validate_Email (Src As Object, Args As ServerValidateEventArgs)

  If InStr(Args.Value, "@") = 0 Then
      EmailValidator.ErrorMessage = "لطفا يك آدرس پست الكترونيكی صحيح را واردنمائيد"
      Args.IsValid = False
  End If

End Sub

Sub Get_Data (Src As Object, Args As EventArgs)

  If Page.IsValid Then
     Output.Text = "You entered valid data"
  End If

End Sub

</SCRIPT>

<form Runat="Server">

<h3>فرم ورو اطلاعات</h3>

<table border="0" cellpadding="2">
<tr>
<td>نام:</td>
<td><asp:TextBox id="FirstName" Runat="Server"/></td>
<td><asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="FirstName"
        ValidationGroup="Group1"
        ErrorMessage="لطفا  نام خود را واردنمائيد"
        Display="Dynamic"/></td>
</tr>
<tr>
<td>نامخانوادگی:</td>
<td><asp:TextBox id="LastName" Runat="Server"/></td>
<td><asp:RequiredFieldValidator Runat="Server"
         ControlToValidate="LastName"
         ValidationGroup="Group1"
         ErrorMessage="لطفا  نام خانوادگیخود را وارد نمائيد"
         Display="Dynamic"/></td>
</tr>
<tr>
<td>سن:</td>
<td><asp:TextBox id="Age" Width="50" Runat="Server"/></td>
<td><asp:RangeValidator Runat="Server"
         ControlToValidate="Age"
         ValidationGroup="Group1"
         Type="Integer"
          MinimumValue="15"
          MaximumValue="99"
          ErrorMessage="لطفا" يك عدد بين پانزده تا نود و نه را وارد نمائيد"
          Display="Dynamic"/>
<asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="Age"
        ValidationGroup="Group1"
        ErrorMessage="لطفا  سن خود را واردنمائيد  "
        Display="Dynamic"/></td>
</tr>
<tr>
<td>آدرسپست الكترونيكی:</td>
<td><asp:TextBox id="Email" Runat="Server"/></td>
<td><asp:CustomValidator id="EmailValidator" Runat="Server"
         ControlToValidate="Email"
         ValidationGroup="Group1"
         Display="Dynamic"
         OnServerValidate="Validate_Email"/>
<asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="Email"
        ValidationGroup="Group1"
         ErrorMessage="لطفا  آدرس پستالكترونيكی خود را وارد نمائيد"
         Display="Dynamic"/></td>
</tr>
</table>
<br/>
<asp:Button Text="ارسال اطلاعاتValidationGroup="Group1"
        OnClick="Get_Data" Runat="Server"/>
<asp:Label id="Output" Runat="Server"/><br/>

</form>

به دكمه "ارسال اطلاعات " ، يك نام گروه validation نسبت داده شده است تا پس از كليك بر روی آن ، كنترل هائی كه كنترل های validation آنها عضوء گروهی با همين نام می باشند ، بررسی و ارزيابی گردند . در صورتی كه از كنترل های validation ديگر بر روی فرم استفاده شده است كه عضوء گروه validation نمی باشند ، پس از كليك بر روی دكمه "ارسال اطلاعات " ، ارزيابی نخواهند شد .
پس از كليك بر روی هر button موجود بر روی يك فرم ، صرفا" آندسته از كنترل هائی بررسی و ارزيابی خواهند شد كه تشكيل يك گروه را می دهند و از يك نام مشابه برای گروه استفاده می نمايند كه همانند نام نسبت داده شده به button مورد نظر است .

كنترل <asp:ValidationSummary>

با استفاده از كنترل <asp:ValidationSummary> ، پيام های خطاء جداگانه توسط يك كنترل توليد و با يكديگر نمايش داده می شوند. كنترل فوق ، همچنين قادر به توليد گزارش پيام های خطاء محدود به مجموعه ای خاص از كنترل ها می باشد .

شكل عمومی

شكل عمومی كنترل فوق به صورت زير است :

 

<asp:ValidationSummaryid="id" Runat="Server"
DisplayMode="BulletList|List|SingleParagraph"
HeaderText="string"
ShowMessageBox="False|True"
ShowSummary="False|True"
ValidationGroup="name"
/>

توضيحات

• خصلت DisplayMode ، نحوه ( فرمت ) نمايش پيام های خطاء را مشخص می نمايد كه به صورت پيش فرض يك ليست bulleted در نظر گرفته می شود .
• مكان نمايش گزارش پيام های خطاء در محلی است كه كنترل ValidatiomSummary استفاده شده است .
• با استفاده از خصلت ShowMessageBox و نسبت دادن مقدار True به آن ، يك پيام pop-up نمايش داده خواهد شد . بدين ترتيب ، خروجی كنترل ValidationSummary در يك PoP-Up نمايش داده می شود .
• در صورتی كه خلاصه گزارش خطاء مرتبط با يك گروه validation خاص می باشد ، می بايست نام آن گروه به خصلت ValidationGroup نسبت داده شود .
مثال
مثال زير ، بازنويسی مثال قبل است . با اين تفاوت كه در مقابل نمايش جداگانه پيام های خطاء ، از يك كنترل ValidationSummary استفاده شده است .

استفاده از كنترل ValidationSummary

<SCRIPT Runat="Server">

Sub Validate_Email (Src As Object, Args As ServerValidateEventArgs)

  If InStr(Args.Value, "@") = 0 Then
      EmailValidator.ErrorMessage = "لطفا يك آدرس پست الكترونيكی صحيح را وارد نمائيد"
      Args.IsValid = False
  End If

End Sub

Sub Get_Data (Src As Object, Args As EventArgs)

 If Page.IsValid Then
      Output.Text = "You entered valid data"
 End If

End Sub

</SCRIPT>

<form Runat="Server">

<h3>فرم ورو اطلاعات</h3>

<table border="0" cellpadding="2">
<tr>
<td>نام:</td>
<td><asp:TextBox id="FirstName" Runat="Server"/></td>
<td><asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="FirstName"
        ValidationGroup="Group1"
        ErrorMessage=" نام"
        Display="None"/></td>
</tr>
<tr>
<td>نامخانوادگی:</td>
<td><asp:TextBox id="LastName" Runat="Server"/></td>
<td><asp:RequiredFieldValidator Runat="Server"
         ControlToValidate="LastName"
         ValidationGroup="Group1"
         ErrorMessage=" نام خانوادگی"
       Display="None"/></td>
</tr>
<tr>
<td>سن:</td>
<td><asp:TextBox id="Age" Width="50" Runat="Server"/></td>
<td><asp:RangeValidator Runat="Server"
         ControlToValidate="Age"
         ValidationGroup="Group1"
         Type="Integer"
          MinimumValue="15"
          MaximumValue="99"
          ErrorMessage="يكعدد بين پانزده تا نود و نه  "
        Display="None"/>
<asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="Age"
        ValidationGroup="Group1"
        ErrorMessage=" سن   "
      Display="None"/></td>
</tr>
<tr>
<td>آدرس پستالكترونيكی:</td>
<td><asp:TextBox id="Email" Runat="Server"/></td>
<td><asp:CustomValidator id="EmailValidator" Runat="Server"
         ControlToValidate="Email"
         ValidationGroup="Group1"
         Display="None"/>
         OnServerValidate="Validate_Email"/>
<asp:RequiredFieldValidator Runat="Server"
        ControlToValidate="Email"
        ValidationGroup="Group1"
         ErrorMessage="  آدرس پست الكترونيكی  "
        Display="None"/></td>
</tr>
</table>
<br/>
<asp:Button Text="Submit" ValidationGroup="Group1"
         OnClick="Get_Data" Runat="Server"/>
<asp:Label id="Output" Runat="Server"/><br/>

<asp:ValidationSummary Runat="Server"
     ValidationGroup=
"Group1"
     DisplayMode=
"BulletList"
     HeaderText=
" لطفا اطلاعات زير را وارد نمائيد"
     ShowSummary=
"True"
     ShowMessageBox=
"False"/>

</form>

تهديدات امنيتی در صورت عدم ارزيابی داده ورودی

برنامه های وب ، داده مورد نياز خود را از طريق درخواست های مبتنی بر پروتكل HTTP دريافت می نمايند ( در برخی موارد ممكن است داده مورد نياز يك برنامه وب از طريق يك فايل تامين گردد). با توجه به ماهيت پروتكل فوق ، مهاجمان می توانند هر بخشی از يك درخواست HTTP نظير url ، querystring ، هدر ، كوكی ها ، فيلدهای موجود بر روی فرم و فيلدهای مخفی را تحريف تا ضمن ناديده گرفتن مكانيزم های امنيتی بكارگرفته شده در يك سايت ، آن را با مشكلات امنتيی متعددی مواجه نمايند. حملات forced browsing, command insertion, cross site scripting, buffer overflows, format string attacks و SQL injection نمونه هائی در اين زمينه می باشند .
تعداد زيادی از برنامه های وب صرفا" از مكانيزم های سمت سرويس گيرنده به منظور بررسی و ارزيابی داده ورودی استفاده می نمايند . مهاجمان با استفاده از روش های متفاوتی می توانند مكانيزم های استفاده شده به منظور ارزيابی داده ورودی را ناديده گرفته و برنامه های وب را در مقابل داده ورودی مخرب خلع سلاح نمايند . مهاجمان ، بدين منظور می توانند با استفاده از ابزارهائی نظير telnet درخواست های HTTP را توليد نمايند . بديهی است در چنين مواردی نبايد انتظار داشت آنان واكنش هائی را كه مد نظر پياده كنندگان برنامه های وب در سمت سرويس گيرنده است ،‌ انجام دهند . با اين كه بررسی و ارزيابی داده ورودی در سمت سرويس گيرنده يك ايده عالی است و می تواند به عنوان يك اقدام مناسب در جهت افزايش كارآئی برنامه های وب تلقی گردد ولی قطعا" رويكرد فوق دارای مزيت امنيتی خاصی نخواهد بود .
به منظور ارزيابی داده ورودی می بايست از روش های سمت سرويس دهنده استفاده گردد تا يك لايه دفاعی مناسب به منظور پيشگيری از درج داده مخرب توسط مهاجمان ايجاد گردد . پس از تحقق خواسته فوق ، می توان با دقت اقدام به بهينه سازی روش های استفاده شده به منظور بررسی و ارزيابی داده ورودی در سمت سرويس گيرنده نيز نمود تا ترافيك غيرضروری بر روی سرويس دهنده به حداقل مقدار ممكن برسد .

بررسی يك نمونه

در برخی موارد از داده ورودی در يك TextBox به منظور ايجاد يك query در ارتباط با يك بانك اطلاعاتی استفاده می گردد . روش فوق ، ممكن است مسائل و مشكلات امنيتی متعددی را به دنبال داشته باشد ( از عدم اجرای اسكريپت ها گرفته تا بروز اشكال در بانك اطلاعاتی ) . مجددا" لازم است به اين نكته مهم اشاره گردد كه كنترل های validation ، به منزله اولين لايه دفاعی در مقابل درج داده مخرب محسوب می گردند و اين اطمينان را ايجاد می نمايند كه صرفا" داده معتبر در اختيار ساير لايه های يك برنامه خصوصا" لايه داده آن قرار داده خواهد شد .
مهاجمان می توانند از طريق TextBox استفاده شده بر روی يك فرم ،‌ كدهای مخربی را به سيستم وارد نمايند كه حذف تمامی بانك اطلاعاتی را به دنبال داشته باشد . با اين كه همواره فرض پياده كنندگان برنامه های وب بر اين است كه از TextBox برای درج داده در سيستم استفاده خواهد شد ، ولی واقعيت اين است كه ممكن است از آنها برای درج كد نيز استفاده گردد . SQL injection يك نمونه از تهديدات موجود در اين زمينه است .

SQL Injection

فرض كنيد از يك TextBox برای درج داده بر روی يك فرم استفاده شده باشد و پس از درج داده توسط كاربر ، از آن به منظور بازيابی ركوردهائی خاص از يك بانك اطلاعاتی استفاده می گردد . بدين منظور ، از دستور SELECT به صورت زير استفاده شده است :

 SQLString = "SELECT * FROM MyTable WHERE MyKey = '" & MyTextBox.Text & "'"

دستور SELECT ، به صورت پويا از مقدار درج شده در TextBox استفاده می نمايد . ظاهرا" همه چيز درست است و مشكل خاصی وجود نخواهد داشت ولی فرض كنيد كاربری كد SQL زير را در TextBox وارد نمايد :
پس از درج داده فوق در TextBox ، وضعيت query نوشته شده در برنامه به صورت زير خواهد بود :

 SELECT * FROM MyTable WHERE MyKey = ' ' ; DROP DATABASE MyDatabase

در چنين مواردی ، عبارت SQL شامل دو دستور مجزاء می گردد كه اولين دستور آن با توجه به ماهيت داده ورودی مقدار null خواهد بود و عملا" ركوردی را برنمی گرداند و دومين عبارت SQL ، باعث حذف يك بانك اطلاعاتی خواهد شد . بدين ترتيب يك SQL injection محقق می گردد و كد مخرب با داده مورد انتظار در عبارت SQL جايگزين می شود. با اين كه در يك بانك اطلاعاتی اكسس ، نمی توان چندين عبارت SQL را در يك خط استفاده نمود ولی برخی از سيستم های مديريت بانك های اطلاعاتی قادر به اجراء كد فوق خواهند بود .
پياده كنندگان برنامه های وب می توانند از كنترل های validation به منظور بلاك نمودن اينچنين كدهائی استفاده نمايند . بدين منظور می توان طول رشته ورودی ، نوع داده ورودی و يا وجود داده ورودی در يك محدوده خاص را بررسی نمود . تست های فوق در مواردی كه داده ورودی از نوع string و با طول نامشخص باشند ، كارساز نبوده و نمی توان از كنترل های اشاره شده در جهت ايجاد يك سطح حفاظتی مناسب استفاده نمود .

راه حل چيست ؟

بهترين روش برای حفاظت در مقابل ورود كدهای مخرب به سيستم ، استفاده از عبارات SQL به صورت پارامتريك در مقابل بكارگيری مستقيم داده ورودی است . پارامترها ، مكان لازم برای نگهداری مقادير داده را فراهم نموده و اين اطمينان را ايجاد می نمايند كه از مقادير ورودی مستقيما" در كد استفاده نخواهد شد .
در كد زير از يك عبارت SELECT به منظور بازيابی ركوردهائی خاص از جدول Books در بانك اطلاعاتی BooksDB استفاده شده است . عبارت SQL به عنوان خصلت SelectCommand كنترل منبع داده AccessDataSource ( با " id="BookSource ) در نظر گرفته شده است .

 Sub Get_Record (Src As Object, Args As EventArgs)

  Dim SQLString As String
  SQLString = "SELECT BookID, BookTitle, BookPrice FROM Books" & _
                     "WHERE BookID = @BookID"
  BookSource.SelectCommand = SQLString

End Sub

يك پارامتر با استفاده از نام خود كه به دنبال يك كاراكتر "@" می آيد ( در اين مثال BookID @ ) ، مشخص می گردد و يك مرجع به داده ورودی است كه در عبارت SELECT و به منظور بازيابی ركوردهای مورد نظر استفاده می گردد . فرض كنيد ، كاربر داده زير را در TextBox وارد نمايد :

  Book ID :      

مقدار ورودی در TextBox ، به عنوان مقدار پارامتر BookID @ در عبارت SELECT در نظر گرفته می شود . در چنين مواردی ، می بايست با صراحت مقدار درج شده در TextBox را با پارامتر فوق مرتبط نمود . زمانی كه از كنترل AccessDataSource به منظور بازيابی داده از يك بانك اطلاعاتی استفاده می گردد ، برای مشخص كردن پارامترهای مورد نياز در يك عبارت SELECT ، می بايست از بخش <SelectParameters> در كنترل استفاده گردد . در اين بخش می توان از يك و يا چندين كنترل <asp:ControlParameter> استفاده نمود . با استفاده از كنترل <asp:ControlParameter> ، می بايست يك نام را برای پارامتر در نظر گرفت .همچنين ، لازم است كنترلی كه قرار است مقدار آن به عنوان پارامتر در نظر گرفته شود نيز مشخص گردد.
كد زير نحوه استفاده از پارامتر BookID @ در كنترل AccessDataSource را نشان می دهد .

 Book ID:
  <asp:TextBox id="BookIDInput" Runat="Server"/>
  <asp:Button Text="Find" OnClick="Get_Record" Runat="Server"/>

  <asp:AccessDataSource id="MySource" Runat="Server" DataFile="../DB/BooksDB.mdb">
     <SelectParameters>
         <asp:ControlParameter Name="BookID" ControlID="BookIDInput" PropertyName="Text"/>
     </SelectParameters>
</asp:AccessDataSource>

توضيحات :

• كنترل <asp:ControlParameter> از سه خصلت به منظور ايجاد ارتباط با كنترلی كه داده مورد نياز را تامين خواهد كرد ، استفاده می نمايد .
• خصلت Name ، نام در نظر گرفته شده برای پارامتر را كه از آن در عبارت SELECT استفاده خواهد شد را مشخص می نمايد .
• خصلت ControlID ، شناسه (id ) كنترلی است كه داده مورد نياز برای پارامتر را مشخص می نمايد .
• PropertyName ، خصلت كنترلی است كه از مقدار آن به عنوان مرجع استفاده می گردد ( در اين مثال خصلت Text مربوط به كنترل TextBox ) .
• در مثال فوق از يك پارامتر در عبارت SELECT استفاده شده است ، بنابراين به يك كنترل <asp:ControlParameter> نياز می باشد. در صورتی كه لازم است از چندين پارامتر استفاده شود ، می بايست برای هر يك از آنها از يك كنترل <asp:ControlParameter> استفاده گردد .

سادگی كد نويسی

با پارامتر درج شده در يك عبارت SELECT به عنوان يك مقدار داده literal برخورد می شود . بنابراين ، بر خلاف زمانی كه از رشته های متصل شده به هم به منظور بكارگيری يك عبارت SQL استفاده می گردد ، احتمال درج داده مخرب بطرز مشهودی كاهش خواهد يافت . استفاده از پارامتر در عبارات SQL ، كاهش پيچيدگی كدينگ عبارات SQL را نيز به دنبال خواهد داشت .
كد زير يك نمونه عبارت SQL را نشان می دهد كه در آن از يك رشته متصل شده به هم استفاده شده است :

 SQLString = "SELECT * FROM Books WHERE " & _
         "BookType = '" & TypeTextBox.Text & "' AND " & _
         "BookPrice > " & PriceTextBox.Text & " AND " & _
         "BookQty <= " & QtyTextBox.Text & " AND " & _
         "BookTitle LIKE '%" & TitleTextBox.Text & "%'"

كد فوق را می توان با عبارت زير جايگزين نمود :

 SQLString = SELECT * FROM Books WHERE " & _
        "BookType = @BookType AND BookPrice > @BookPrice AND " & _
        "BookQty <= @BookQty AND BookTitle LIKE @BookQty"

درون كنترل AcessDataSource ، می بايست از يك بخش SelectParameters به منظور معرفی كنترل هائی كه مقدار مورد نياز هر يك از پارامترها را تامين می نمايند ، استفاده گردد .


 



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