التحقق من صحة المدخلات وترميز المخرجات
التحقق من صحة المدخلات (Input Validation) يفحص كل قيمة تدخل التطبيق مقابل قواعد حقلها، ويرفض ما لا يطابقها، على الخادم وقبل استخدام القيمة. أما ترميز المخرجات (Output Encoding) فيحوّل القيمة المخزَّنة إلى الصورة الآمنة للمكان الذي تُكتب فيه، بحيث يعاملها المتصفح أو محلّل العناوين أو قاعدة البيانات بياناتٍ لا شيفرة: في صفحة HTML تصبح < هي <، وفي العنوان تصبح المسافة %20، وتصل القيمة إلى قاعدة البيانات معاملاً في الاستعلام.
مثال: عميل اسمه O'Brien & Sons مدخل صالح لا ينبغي لأي قاعدة أن ترفضه. ولا تصبح الفاصلة العليا وعلامة العطف خطيرتين إلا عند المخرج، إذا جُمعت الصفحة أو الاستعلام من نصوص ملصقة. فالتحقق يقرر ما يدخل، والترميز يقرر كيف يُكتب. ويحتاج التطبيق إلى كليهما، ويفحص المختبِر كليهما.
لماذا يهم
يشترك الحقن (Injection) والبرمجة النصية عبر المواقع (XSS)، اللذان يختبرهما الدرسان التاليان بالتفصيل، في سبب جذري واحد: قيمة من الخارج تصل إلى مفسّر مثل قاعدة بيانات أو صدفة أوامر (shell) أو متصفح فتُنفَّذ شيفرةً. والحقن إحدى فئات OWASP Top 10:2025 ويشمل XSS، والضابطان اللذان يمنعانه هما هذان تحديداً: تحقق مما يدخل، ورمّز ما يخرج. وتكفي نقطة دخول واحدة بلا فحص أو مخرج واحد بلا ترميز.
وهذه أرض خصبة للمختبِر، لأن العيوب تختبئ في الفجوات بين الطبقات: نموذج يتحقق وواجهة برمجية لا تتحقق، وصفحة قائمة ترمّز وتصدير لا يرمّز. ولا تصل الاختبارات الوظيفية بقيمها المرتبة إلى تلك الفجوات. أما بضع علامات مميّزة غير ضارة (markers) تحملها من كل نقطة دخول إلى كل مكان تظهر فيه القيمة فتكشفها في دقائق، بلا أدوات هجوم، على أنظمة مصرّح لك باختبارها.
التحقق من صحة المدخلات: قواعد قائمة السماح مفروضة على الخادم
تطلب ورقة OWASP المرجعية للتحقق من المدخلات (Input Validation Cheat Sheet) فحصين لكل قيمة: بنيتها (syntax)، أي النوع والصيغة المتوقعان: النوع والطول والنطاق والصيغة والانتماء إلى مجموعة ثابتة، ودلالتها (semantics)، أي هل القيمة منطقية للعملية المطلوبة: تاريخ الزيارة ليس في الماضي، والكمية لا تتجاوز المخزون. ويسمّيهما المختبِرون عادةً التحقق النحوي والتحقق الدلالي. وتُكتب القواعد قوائمَ سماح (allow-lists): حدّد المقبول وارفض كل ما عداه. فقائمة الحظر (block-list أو deny-list) للنصوص الممنوعة ناقصة دائماً، لأن القيمة الخطيرة تُكتب بطرق أكثر مما تستوعبه أي قائمة، وهي ترفض بيانات سليمة: فحظر الفاصلة العليا يرفض O'Brien من دون أن يجعل أي استعلام آمناً. وتعدّ الورقة قوائم الحظر و«تنظيف» المدخلات من مزالقها الشائعة. وللنص الحر قائمة سماح أيضاً لكنها أوسع: ترميز محارف (character encoding) واحد متفق عليه بين المكوّنات، ورفض المدخلات المشوّهة، والإبقاء على علامات الترقيم وأنظمة الكتابة المشروعة، وحد أقصى للطول، وحيث تُقارَن القيم، تطبيع Unicode واحد (normalisation) يُطبَّق قبل التحقق والتخزين (كي تكون é المكتوبة محرفاً واحداً أو e مع علامة تشكيل القيمةَ نفسها).
أما فحوص المتصفح مثل required وmaxlength والنمط فهي تغذية راجعة لا ضابط: كما في درس اختبار نماذج الويب، يستطيع أي أحد تعديل الصفحة أو إرسال الطلب من دونها. والورقة صريحة: تحقّق على الخادم حتى حين يفحص المتصفح الحقول نفسها، وتحقّق أيضاً من البيانات الآتية من الواجهات البرمجية الداخلية وتغذيات الشركاء وطوابير الرسائل. والنموذج ليس إلا نقطة دخول واحدة: فواجهة JSON التي يستدعيها تطبيق الجوال، والاستيراد الجماعي، وسلسلة الاستعلام، وترويسة مثل Accept-Language، وملف تعريف الارتباط، وخطاف الويب (webhook) كلها تُدخل قيماً من الخارج. ويثبت المختبِر أن كل مسار يفرض كل قاعدة.
- اكتب كل قاعدة بصيغة قابلة للاختبار:
^ORD-[0-9]{5}$لرقم الطلب، أيORD-ثم خمسة أرقام بالضبط (فالمرساتان^و$تفرضان مطابقة القيمة كلها كما تطلب الورقة، ومن دونهما يقبل النمط أيضاًxx ORD-12345 <b>)؛ وعدد صحيح من 1 إلى 20 للكمية؛ وقيمة واحدة من القائمة المخزَّنة للدولة؛ ولاسم الشركة من 2 إلى 80 حرفاً من حروف Unicode والأرقام والمسافات و' - & .، فتبقى الفاصلة العليا وعلامة العطف مشروعتين. - انسخ طلب النموذج من لوحة Network بصيغة cURL، وغيّر حقلاً واحداً إلى قيمة ترفضها الصفحة، وأرسله بحساب اختبار، وتوقّع استجابة
4xxتسمّي الحقل والقاعدة، ولا شيء مخزَّناً، ولا تتبّع مكدّس (stack trace) ولا SQL في الرسالة. - أرسل المجموعة نفسها عبر الواجهة البرمجية والاستيراد: 81 حرفاً، وكمية 0 و21، ودولة
ZZ، والطلب أدناه الذي يجتاز فيهcompanyوnotesقاعدتيهما بينما يفشلquantityوcountry. وأي مسار يقبل ما يرفضه النموذج مشكلة تستحق الإبلاغ (finding). - انتبه للإصلاح الصامت: الخادم الذي يقصّ 81 حرفاً إلى 80 أو يحذف
<من دون رسالة يغيّر بيانات المستخدم. أبلغ عنه ما لم يسمح المتطلب به.
POST /api/customers HTTP/1.1
Host: crm.test.example
Content-Type: application/json
{"company": "O'Brien & Sons", "quantity": 21, "country": "ZZ",
"notes": "Discount < 10% until <b>Ramadan</b>"}
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json
{"errors": [{"field": "quantity", "rule": "integer 1-20"},
{"field": "country", "rule": "not a known country code"}]}جرّبها: أداة اختبار Regex جرّبها: مولّد الاختبارات السلبية جرّبها: مولّد مجموعات الأحرف الخاصة
ترميز المخرجات: قيمة واحدة وترميز واحد لكل سياق
يجري الترميز لحظة الإخراج، في الشيفرة التي تكتب القيمة في صفحة أو رابط أو سكربت أو استعلام، ويعتمد على المكان الذي تستقر فيه القيمة. وتعطي ورقة OWASP المرجعية للوقاية من XSS (Cross Site Scripting Prevention Cheat Sheet) كل سياق في HTML قواعده الخاصة: محتوى العناصر، وقيم السمات، وJavaScript، وCSS، والعناوين. ولقاعدة البيانات مقابلها: الاستعلام ذو المعاملات (parameterised query) يرسل القيمة منفصلة عن عبارة SQL، فلا تحلّلها قاعدة البيانات أبداً بوصفها SQL؛ وتعدّ ورقة الوقاية من الحقن (Injection Prevention Cheat Sheet) تهريب المدخلات (escaping) ملاذاً أخيراً. والقيمة المخزَّنة لا تتغير أبداً، أما القيمة المرمَّزة لسياق خاطئ فتبقى غير آمنة، لأن كيانات HTML داخل عنوان أو سلسلة سكربت لا تعني شيئاً هناك.
- محتوى عنصر HTML: تصبح
&هي&، و<هي<، و>هي>، و"هي"، و'هي'(و'و'تمثّلان المحرف نفسه)، فتعرض الصفحة المحارف كما كُتبت. - سمة HTML: الكيانات نفسها داخل سمة محاطة بعلامتي اقتباس مثل
titleأوvalue؛ فالسمة غير المقتبسة يمكن الخروج منها بمسافة وبمحارف أخرى كثيرة. أما سمة الحدث مثلonclickفسياق سكربت: يفكّ المتصفح الكيانات قبل تشغيل السكربت، فلا تحمي شيئاً هناك. - معامل العنوان (URL): ترميز النسبة المئوية (percent-encoding)، فتصبح المسافة
%20و&هي%26، وفي الترميز الصارم وفق RFC 3986 تصبح'هي%27(وكثير من أدوات الترميز تترك الفاصلة العليا كما هي)؛ ومن دون ترميز تبدأ&في الاسم معاملاً ثانياً. ثم يُرمَّز العنوان المكتوب فيhrefترميزَ سمة أيضاً. - JavaScript وJSON: تهريب السلاسل بمرمِّز من مكتبة تخضع للصيانة لا بتهريب علامات الاقتباس يدوياً، فتصبح
"هي\"و\هي\\، و<هي\u003cحين تكون البيانات داخل صفحة HTML، كي لا تستطيع القيمة إغلاق السكربت. والأسلم: أبقِ القيمة خارج السكربت، في سمةdata-مثلاً تُقرأ عبرdataset، واكتبها في الصفحة بـtextContentلا بـinnerHTMLأبداً. - SQL: استعلام ذو معاملات أو عبارة مُعدّة مسبقاً (prepared statement) يُبقي
O'Brienبياناتٍ من دون المساس بالنص.
القيمة المخزَّنة O'Brien & Sons
HTML content O'Brien & Sons
HTML attribute title="O'Brien & Sons"
URL parameter ?q=O%27Brien%20%26%20Sons
JSON / JavaScript {"company": "O'Brien & Sons"} (لا شيء يحتاج إلى تهريب هنا)
SQL WHERE company = ? (القيمة مربوطة معاملاً)
محرف واحد في ثلاثة سياقات: < -> < (HTML) %3C (URL) \u003c (script)جرّبها: مرمّز كيانات HTML جرّبها: مرمّز URL جرّبها: تهريب / إلغاء تهريب JSON
لماذا كلاهما: التحقق عند الباب والترميز عند كل مخرج
لا يغني أي من الضابطين عن الآخر. فالتحقق لا يستطيع رفض O'Brien أو Al-Harbi & Sons أو ملاحظة تقول price < 50، لأنها بيانات صحيحة؛ والترميز وحده يبقيها غير ضارة في طريقها إلى الخارج. والترميز لا يستطيع رفض كمية -1 أو ملاحظة بحجم عشرة ميغابايت أو دولة غير موجودة، لأنها تُعرض على أكمل وجه؛ والتحقق وحده يُبقي البيانات السيئة خارجاً. وتقول ورقة التحقق من المدخلات الشيء نفسه: التحقق لا يغني عن الاستعلامات ذات المعاملات في SQL، ولا عن ترميز المخرجات حسب السياق في مواجهة XSS.
لذلك الترتيب ثابت: مدخل، ثم تحقق (قبول أو رفض، ولا إصلاح صامت أبداً)، ثم تخزين القيمة المقبولة من دون تغيير، ثم ترميز حسب السياق عند كل مخرج. وتخزين قيمة مرمَّزة سلفاً يكسر السلسلة، لأن كل مخرج آخر يتلقى عندئذ بيانات خاطئة: يعرض البريد الإلكتروني & نصاً، ويحمل تصدير CSV كيانات، وتعرض الصفحة التي ترمّز بصورة صحيحة & على الشاشة لأن مصدرها صار يحوي &amp;، وهو عيب الترميز المزدوج. أما التنقية (sanitisation) فعملية ثالثة منفصلة للحقول القليلة التي يجب أن تقبل وسوم HTML (markup)، مثل محرر النص المنسّق: تُبقي مكتبة التنقية قائمة سماح من الوسوم والسمات فقط، وتبقى النتيجة مرمَّزة أينما خرجت نصاً عادياً.
- 1وصول المدخلأي نقطة دخول: نموذج، أو واجهة JSON، أو استيراد، أو سلسلة استعلام، أو ترويسة، أو ملف تعريف ارتباط، أو خطاف ويب
O'Brien & Sons - 2التحقق على الخادمقاعدة قائمة سماح لكل حقل: النوع والطول والنطاق والصيغة والمجموعة، ثم المعنى في سياق العملقائمة سماح
فرع: مرفوض: استجابة
4xxتسمّي الحقل والقاعدة؛ لا شيء مخزَّن ولا إصلاح صامتبوابة: القيم المقبولة فقط، من دون تغيير
- 3التخزين كما تحقّقتالقيمة المخزَّنة لا تتغير أبداً: لا كيانات ولا حذف ولا قصّ
O'Brien & Sonsفرع: عيب: خُزّنت مرمَّزة سلفاً، فتعرض الصفحة
&نصاً (و&amp;في مصدرها) وتحمل الرسائل والتصديرات كيانات خاماًفشل - 4الترميز عند الإخراج حسب السياقفي الشيفرة التي تكتب القيمة، لحظة خروجهاقيمة واحدة وترميز واحد لكل سياق
- 5محتوى HTML أو سمة مقتبسةكيانات
O'Brien & Sons - 6معامل العنوانترميز النسبة المئوية
?q=O%27Brien%20%26%20Sons - 7سلسلة JavaScript أو JSONتهريب السلاسل لـ
"و\، و<بوصفها\u003cداخل صفحة؛ ولا شيء يحتاج إلى تهريب هنا"O'Brien & Sons" - 8SQLاستعلام ذو معاملات: القيمة لا تلمس العبارة أبداً
WHERE company = ?
فرع: عيب: ترميز لسياق خاطئ، مثل كيانات HTML داخل عنوان أو سلسلة سكربت، حيث لا تحمي شيئاًفشل
- 9المخرجصفحة أو رابط أو سكربت أو استعلام أو بريد أو تصدير CSV أو استجابة واجهة برمجية: كل مخرج، ويُعرض كما كُتب
O'Brien & Sons
بعد ذلك:يعامل المتصفح أو محلّل العناوين أو قاعدة البيانات القيمة بياناتٍ لا شيفرة
مثال تطبيقي: عميل واحد عبر مخرجاته
نظام إدارة علاقات العملاء (CRM) في بيئة الاختبار لديك، مع إذن مكتوب باختباره، فيه نموذج العملاء المذكور أعلاه. يحفظ المختبِر عميلاً اسم شركته O'Brien & Sons وملاحظته Discount < 10% until <b>Ramadan</b>، مرة عبر النموذج ومرة عبر الواجهة البرمجية بكمية ودولة صالحتين، ثم يزور كل مكان تظهر فيه القيمتان: قائمة العملاء، وتلميح الاسم (سمة title)، ورابط «البحث عن مشابه»، وتصدير CSV، وبريد الترحيب.
- قائمة العملاء: القيمتان معروضتان كما كُتبتا؛ والمصدر يحوي
'و&و<. ناجح. - التلميح: يعرض
Oفقط. وفي المصدرtitle='O'Brien & Sons': أنهت الفاصلة العليا السمة المحاطة بعلامة اقتباس مفردة، وحطّ باقي القيمة خارجها. النتيجة: لا ترميز للسمات. توقّف وأبلغ؛ ومن هنا يكمل درس XSS. - رابط البحث عن مشابه:
/customers?q=O'Brien & Sonsمن دون ترميز نسبة مئوية؛ فيجري البحث عنO'Brienويتلقى الخادم معاملاً ثانياً اسمهSons. النتيجة: لا ترميز للعناوين، وعيب وظيفي لكل اسم فيه علامة عطف. - تصدير CSV: تصل الملاحظة بصيغة
Discount < 10% until <b>Ramadan</b>. النتيجة: أعاد التصدير استخدام نص مرمَّز لـHTML، فيحصل من ينزّله على بيانات خاطئة؛ ترميز لسياق خاطئ. - بريد الترحيب:
Ramadanبخط عريض. النتيجة: يدرج القالب الملاحظة وسومَ HTML تُفسَّر، فيُعرض نص كتبه مستخدم في صندوق بريد مستخدم آخر؛ أبلغ عنه بوصفه حقن HTML برؤية مقيَّدة، واترك تقدير الخطورة لمسؤول الأمان. - نقاط الدخول: عبر الواجهة البرمجية تعيد
quantity: 21وcountry: ZZاستجابة422تسمّي الحقلين، ولا شيء مخزَّن. ناجح. وعبر الاستيراد يُقبل اسم شركة من 81 حرفاً ويُقصّ إلى 80 من دون رسالة. النتيجة: الاستيراد يتحقق أقل مما يتحقق النموذج.
أخطاء شائعة
- عدّ
requiredأوmaxlengthأو النمط في المتصفح حمايةً، وعدم إرسال الطلب من دون الصفحة أبداً. - اختبار النموذج الرئيسي وحده، بينما تصل الواجهة البرمجية والاستيراد وعميل الجوال إلى قاعدة البيانات نفسها بقواعد أضعف.
- كتابة قوائم حظر مثل «ارفض
<script>» بدلاً من قواعد قائمة السماح؛ فأول صيغة لا تحويها القائمة تمرّ. - الترميز قبل التخزين، أو تخزين قيمة مرمَّزة سلفاً، فيصير
&amp;في مصدر صفحة وتظهر الكيانات خاماً في الرسائل والتصديرات. - الترميز لسياق خاطئ، مثل كيانات HTML داخل عنوان أو سلسلة سكربت، حيث لا تحمي شيئاً.
- استخدام حمولات سكربت بدلاً من علامات مميّزة غير ضارة، أو اختبار نظام من دون إذن مكتوب.
من منظور ضمان الجودة
قواعد التحقق جزء من أساس الاختبار (test basis). وفي جلسات التنقيح اسأل عن كل حقل جديد: النوع والطول والنطاق والصيغة والمجموعة المسموحة، وما يراه المستخدم عند الرفض، وأين ستُعرض القيمة وفي أي سياقات. واكتب الإجابات في معايير القبول ليتفق المطوّر والمختبِر وتوثيق الواجهة البرمجية، ثم اشتقّ حالات الاختبار بتقسيم التكافؤ وتحليل القيم الحدّية كما في وحدة تصميم الاختبار.
وأثناء الاختبار احتفظ بمجموعة واحدة من العلامات المميّزة واحملها عبر كل نقطة دخول إلى كل مخرج، بما في ذلك الرسائل وملفات PDF والتصديرات وشاشات المسؤول؛ وسجّل الطلب والاستجابة ومصدر الصفحة، لا لقطات الشاشة وحدها، مع إخفاء الرموز المميّزة (tokens). وأبلغ عن فحص خادم مفقود أو ترميز مفقود بوصفه ملاحظة أمنية (security finding) برؤية مقيَّدة، وسمِّ نقطة الدخول والمخرج بالضبط، واتفق على الخطورة مع مسؤول الأمان. وبعد الإصلاح أجرِ اختبار التأكيد على كل مخرج، وأبقِ هذه العلامات في حزمة الانحدار: فكل قالب أو تصدير أو عميل جديد يعيد فتح الفجوة.
تمرين عملي
راجع التحقق والترميز في نموذج حجز
موقع حجز لعيادة في بيئة الاختبار لديك، ولديك إذن مكتوب باختباره، فيه نموذج بحقول: الاسم (من 2 إلى 60 حرفاً: حروف ومسافات وفاصلة عليا وشرطة)، والجوال (05 وثمانية أرقام)، والسبب (نص حر حتى 500 حرف)، والموعد (أحد الأوقات المعروضة). وأدناه طلب واحد إلى الواجهة البرمجية مع استجابته، وثلاثة مقتطفات من مصدر الصفحات تظهر فيها القيم المحفوظة.
قرّر لكل ملاحظة من الملاحظات الخمس هل هي ناجحة أم مشكلة تستحق الإبلاغ (finding): الاسم المقبول، والموعد المقبول، والمقتطفات الثلاثة. سمِّ الضابط المفقود (قاعدة تحقق، أو فرض على جانب الخادم، أو ترميز وسياقه) واكتب عنوان تقرير خطأ. ثم اذكر الفحوص التالية التي ستجريها.
POST /api/bookings
{"name": "Sara <b>qa</b>", "mobile": "0512345678",
"reason": "Follow-up, pain < 3/10 since 'Sunday'", "slot": "2026-11-03T25:00"}
HTTP/1.1 201 Created
{"id": 8821, "name": "Sara <b>qa</b>", "slot": "2026-11-03T25:00"}
المقتطف 1: قائمة الاستقبال
<td>Sara <b>qa</b></td>
المقتطف 2: شاشة الطبيب
<p class="reason">Follow-up, pain < 3/10 since 'Sunday'</p>
المقتطف 3: صفحة التذكير
<a href="/r?name=Sara <b>qa</b>&id=8821">Reschedule</a>- قارن قيم الطلب بالقواعد الأربع واقرأ الاستجابة: أي القواعد فرضها الخادم وأيها لم يفرض؟
- سمِّ لكل مقتطف سياق الإخراج والترميز الذي يتطلبه، ثم قارن بما يظهره المصدر.
- رتّب النتائج حسب المخاطر واكتب عنوان تقرير خطأ واحداً لكل منها.
إظهار الإجابة النموذجية
الاسم: Sara <b>qa</b> يحوي < و> و/ التي لا تسمح بها قائمة السماح، ومع ذلك تعيده استجابة 201 Created. النتيجة: الخادم لا يفرض قاعدة الاسم التي يعرضها النموذج. عنوان تقرير الخطأ: «POST /api/bookings يقبل في الاسم محارف وسوم HTML يرفضها النموذج».
الموعد: 2026-11-03T25:00 ليس من الأوقات المعروضة والساعة 25 غير موجودة، ومع ذلك خُزّن. النتيجة: لا تحقق من المجموعة ولا تحقق دلالي على slot. عنوان تقرير الخطأ: «واجهة الحجز تخزّن موعداً لم يُعرض قط».
المقتطف 1: <b>qa</b> ترميز صحيح لمحتوى العنصر؛ وترى موظفة الاستقبال الاسم كما كُتب. ناجح.
المقتطف 2: السبب مكتوب خاماً. ويُعرض بصورة صحيحة فقط لأن < تليها مسافة فيقرؤها المتصفح نصاً؛ أما سبب يحوي <b> فسيُفسَّر وسماً على شاشة الطبيب. النتيجة: ترميز HTML مفقود لنص مخزَّن من المرضى، أي XSS مخزَّن محتمل (مدخل يُحفظ مرة ويُعرض لكل من يشاهد الصفحة بعده، وهو موضوع درس XSS). عنوان تقرير الخطأ: «شاشة الطبيب تعرض سبب الحجز من دون ترميز HTML». أبلغ برؤية مقيَّدة ولا تتعمق أكثر.
المقتطف 3: بُني href من دون ترميز نسبة مئوية: يجب أن تصبح المسافة و< و> و/ هي %20 و%3C و%3E و%2F، والاسم الذي يحوي &، وهو يمرّ لأن الخادم لا يفرض قاعدة الاسم، سيبدأ معاملاً جديداً. النتيجة: ترميز العناوين مفقود، وعيب وظيفي أيضاً. عنوان تقرير الخطأ: «رابط إعادة الجدولة يتعطل مع الأسماء ذات المحارف الخاصة».
الترتيب: المقتطف 2 أولاً، ثم فجوتا التحقق، ثم الرابط. والجوال والسبب صالحان في هذا الطلب، فهو لا يبيّن هل يفرض الخادم قاعدتيهما. الفحوص التالية: رقم جوال غير صالح وسبب من 501 حرف عبر الواجهة البرمجية مع توقّع استجابة 422 تسمّي الحقل؛ والقيم نفسها عبر نقطة نهاية تطبيق الجوال والاستيراد؛ وبريد التأكيد وخطاب الموعد بصيغة PDF؛ والاتفاق على خطورة كل نتيجة مع مسؤول الأمان.
أسئلة شائعة
هل يكفي التحقق على جانب العميل إذا كانت الواجهة البرمجية لا تستخدمها إلا صفحاتنا؟
لا. فمن جهة المتصفح لا توجد واجهة برمجية خاصة: كل ما تستطيع الصفحة إرساله يستطيع شخص بأدوات المطوّر إرساله بصورة مختلفة. وتشترط ورقة OWASP المرجعية للتحقق من المدخلات التحقق على الخادم حتى حين يفحص المتصفح الحقول نفسها؛ وتبقى فحوص المتصفح مفيدة للتغذية الراجعة السريعة.
هل ينبغي للتطبيق تخزين القيمة مرمَّزة ليكون كل مخرج آمناً؟
لا. خزّن القيمة كما تحقّقت منها ورمّزها عند كل مخرج حسب سياقه. فقيمة < المخزَّنة بيانات خاطئة في بريد أو تصدير أو استجابة واجهة برمجية، والصفحة التي ترمّز بصورة صحيحة تعرضها < على الشاشة لأن مصدرها يحوي عندئذ &lt;. والنص المنسّق هو الاستثناء، وتتولاه التنقية لا الترميز.
ما الفرق بين التحقق والتنقية والترميز؟
التحقق يقبل القيمة أو يرفضها مقابل القواعد ولا يغيّر شيئاً. والتنقية تغيّر القيمة بحذف أجزاء أو تعديلها، مثل وسوم لا يجوز أن يحويها حقل نص منسّق. والترميز يغيّر التمثيل فقط لسياق إخراج واحد، وتبقى القيمة المخزَّنة كما هي. وتبحث الاختبارات عن غياب أحد الثلاثة، وعن تنقية تجري بصمت حيث كان الرفض متوقعاً.
هل أستطيع العثور على هذه العيوب من دون أدوات أمنية؟
نعم. فالعلامات المميّزة غير الضارة مثل الفاصلة العليا وعلامة العطف وقوسي الزاوية حول كلمة وسلسلة أطول من الحد ورقم خارج النطاق، مع أدوات المطوّر وعميل سطر أوامر لإرسال الطلبات من دون الصفحة، تكشف الفحوص المفقودة والترميز المفقود. أما إثبات إمكانية استغلال الضعف فعمل فريق الأمان؛ والضابط المفقود عيب يستحق الإبلاغ بذاته.
المراجع
- OWASP Cheat Sheet Series: Input Validationالتحقق بقوائم السماح، والفرق بين الفحص النحوي والدلالي، ولماذا لا يُعدّ التحقق في المتصفح ضابطاً أمنياً أبداً.
- OWASP Cheat Sheet Series: Cross Site Scripting Preventionمنع XSS: الترميز عند الإخراج بحسب كل سياق، وتعقيم HTML الذي يكتبه المستخدم، ومواضع الإدراج الآمنة في DOM وحمايات الأطر، مع اعتبار CSP طبقة دفاع إضافية فقط.
- OWASP Cheat Sheet Series: Injection Preventionمنع حقن SQL وأوامر النظام وغيرها عبر التعامل بالمعاملات والتحقق والتهريب.
- OWASP Top 10:2025أخطر عشرة مخاطر أمنية لتطبيقات الويب، مع كيفية اختبار كل منها والوقاية منه.
تدرّب بأدوات متقن
اختبر التعابير النمطية مباشرةً مع إبراز التطابقات ومجموعات الالتقاط ومعاينة الاستبدال.
ولّد حالات اختبار سلبية لحقول النماذج وواجهات API: قيم فارغة وnull ونوع خاطئ وطول زائد وحقن وصيغة غير صالحة.
ولّد مدخلات مليئة بالأحرف الخاصة: علامات الاقتباس، والأحرف الوصفية لـ SQL/HTML/JSON، وأحرف التحكم، والرموز التعبيرية، وحيل المسارات.
تهريب أحرف HTML الخاصة (< و> و& وعلامات الاقتباس) إلى كيانات لمنع هجمات XSS.
ترميز النص بالنسبة المئوية (percent-encoding) لاستخدامه بأمان في عناوين URL وسلاسل الاستعلام وبيانات النماذج.
تهريب النصوص (escape) لتضمينها بأمان داخل سلسلة JSON نصية، أو إلغاء تهريب سلسلة JSON نصية حرفية.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.