إطار الأمان: التحقق من صحة الإدخال | التخفيفات من المخاطر

المنتج /الخدمة مقال
تطبيق ويب
قاعدة بيانات
واجهة برمجة تطبيقات الويب
Azure Document DB
WCF

تعطيل برمجة XSLT النصية لجميع التحويلات التي تستخدم أوراق أنماط غير موثوق بها

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع XSLT Security، خاصية XsltSettings.EnableScript
الخطوات XSLT يدعم البرمجة النصية داخل أوراق الأنماط باستخدام عنصر <msxml:script>. يسمح هذا باستخدام الوظائف المخصصة في تحويل XSLT. يتم تنفيذ البرنامج النصي في سياق عملية إجراء التحويل. يجب تعطيل البرنامج النصي XSLT في بيئة غير موثوق بها لمنع تنفيذ التعليمة البرمجية غير الموثوق بها. في حال استخدام .NET: يتم تعطيل البرمجة النصية لـ XSLT افتراضياً؛ ومع ذلك، يجب عليك التأكد من أنه لم يتم تمكينه بشكل صريح من خلال خاصية XsltSettings.EnableScript.

مثال

XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false

مثال

إذا كنت تستخدم MSXML 6.0، يتم تعطيل البرمجة النصية لـ XSLT افتراضياً؛ ومع ذلك، يجب التأكد من أنه لم يتم تمكينه بشكل صريح من خلال خاصية عنصر XML DOM AllowXsltScript.

doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false

مثال

إذا كنت تستخدم MSXML 5 أو إصداراً أقل، يتم تمكين البرمجة النصية لـ XSLT افتراضياً ويجب عليك تعطيلها بشكل صريح. قم بتعيين خاصية عنصر XML DOM AllowXsltScript إلى false.

doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.

تأكد من أن كل صفحة يمكن أن تحتوي على محتوى يمكن التحكم فيه من قِبل المستخدم تختار من التنصت التلقائي على MIME

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع الجزء الخامس من أمان IE8 - الحماية الشاملة
الخطوات

لكل صفحة يمكن أن تحتوي على محتوى يمكن للمستخدم التحكم فيه، يجب عليك استخدام رأس HTTP X-Content-Type-Options:nosniff. للامتثال لهذا المطلب، يمكنك إما تعيين صفحة العنوان المطلوبة بصفحة للصفحات التي قد تحتوي على محتوى يمكن التحكم فيه بواسطة المستخدم، أو يمكنك تعيينها عالمياً لجميع الصفحات في التطبيق.

يحتوي كل نوع من أنواع الملفات التي يتم تسليمها من خادم ويب على نوع MIME مرتبط (يُسمى أيضاً نوع المحتوى) الذي يصف طبيعة المحتوى (أي، صورة، نص، تطبيق، إلخ.)

رأس X-Content-Type-Options هو رأس HTTP يسمح للمطورين بتحديد أن المحتوى الخاص بهم لا ينبغي شمه بواسطة MIME. تم تصميم هذا الرأس للتخفيف من هجمات MIME-Sniffing. تمت إضافة دعم هذا العنوان في Internet Explorer 8 (IE8)

سيستفيد مستخدمو Internet Explorer 8 (IE8) فقط من X-Content-Type-Options. الإصدارات السابقة من Internet Explorer لا تحترم حالياً رأس X-Content-Type-Options

Internet Explorer 8 (والإصدارات الأحدث) هي المستعرضات الرئيسية الوحيدة التي تنفذ ميزة إلغاء الاشتراك في MIME-sniffing. إذا وعندما تقوم المتصفحات الرئيسية الأخرى (Firefox وSafari وChrome) بتنفيذ ميزات مماثلة، فسيتم تحديث هذه التوصية لتشمل بناء الجملة لتلك المتصفحات أيضاً

مثال

لتمكين الرأس المطلوب عالمياً لجميع الصفحات في التطبيق، يمكنك القيام بأحد الإجراءات التالية:

  • أضف الرأس في ملف web.config إذا كان التطبيق مستضافاً بواسطة خدمات معلومات الإنترنت (IIS) 7
<system.webServer> 
  <httpProtocol> 
    <customHeaders> 
      <add name=""X-Content-Type-Options"" value=""nosniff""/>
    </customHeaders>
  </httpProtocol>
</system.webServer> 
  • أضف الرأس من خلال Application_BeginRequest العالمي
void Application_BeginRequest(object sender, EventArgs e)
{
  this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
} 
  • تنفيذ وحدة HTTP مخصصة
public class XContentTypeOptionsModule : IHttpModule 
  {
    #region IHttpModule Members 
    public void Dispose() 
    { 

    } 
    public void Init(HttpApplication context)
    { 
      context.PreSendRequestHeaders += newEventHandler(context_PreSendRequestHeaders); 
    } 
    #endregion 
    void context_PreSendRequestHeaders(object sender, EventArgs e) 
      { 
        HttpApplication application = sender as HttpApplication; 
        if (application == null) 
          return; 
        if (application.Response.Headers[""X-Content-Type-Options ""] != null) 
          return; 
        application.Response.Headers.Add(""X-Content-Type-Options "", ""nosniff""); 
      } 
  } 

  • يمكنك تمكين العنوان المطلوب فقط لصفحات معينة عن طريق إضافته إلى الردود الفردية:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff""; 

تقوية أو تعطيل دقة كيان XML

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع توسيع كيان XML، هجمات ودفاعات رفض الخدمة لـ XML، نظرة عامة على أمان MSXML، أفضل الممارسات لتأمين تعليمة برمجية MSXML، مرجع بروتوكول NSXMLParserDelegate، حل المراجع الخارجية
الخطوات

على الرغم من عدم استخدامه على نطاق واسع، إلا إن هناك ميزة في XML تسمح لمحلل XML بتوسيع كيانات الماكرو بقيم محددة إما داخل المستند نفسه أو من مصادر خارجية. على سبيل المثال، قد يعرف المستند كيانا "companyname" بالقيمة "Microsoft"، بحيث يتم استبداله تلقائيا بالنص Microsoft في كل مرة يظهر فيها النص "اسم الشركة;". أو، قد يحدد المستند كياناً "MSFTStock" يشير إلى خدمة ويب خارجية لجلب القيمة الحالية لمخزون Microsoft.

ثم في أي وقت يظهر فيه "MSFTStock;" في المستند، يتم استبداله تلقائيا بسعر السهم الحالي. ومع ذلك، يمكن إساءة استخدام هذه الوظيفة لإنشاء شروط رفض الخدمة (DoS). يمكن للمهاجم تداخل كيانات متعددة لإنشاء قنبلة XML للتوسعة الأسية تستهلك كل الذاكرة المتوفرة على النظام.

بدلاً من ذلك، يمكنه إنشاء مرجع خارجي يقوم بتدفق كمية لا حصر لها من البيانات أو يقوم ببساطة بتعليق مؤشر الترابط. نتيجة لذلك، يجب على جميع الفرق تعطيل دقة كيان XML الداخلية و/أو الخارجية تماماً إذا كان التطبيق الخاص بهم لا يستخدمه، أو تحديد مقدار الذاكرة والوقت الذي يمكن أن يستهلكه التطبيق يدوياً لحل الكيان إذا كانت هذه الوظيفة ضرورية للغاية. إذا لم يكن تطبيقك مطلوباً لحل الكيان، فقم بتعطيله.

مثال

بالنسبة إلى التعليمة البرمجية لـ NET Framework. يمكنك استخدام الطرق التالية:

XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);

// for .NET 4
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);

لاحظ أن القيمة الافتراضية لـ ProhibitDtd في XmlReaderSettings هي true بينما هي في XmlTextReader على false. إذا كنت تستخدم XmlReaderSettings، فلن تحتاج إلى ضبط ProhibitDtd على true بشكل صريح، ولكن يوصى بذلك من أجل السلامة. لاحظ أيضاً أن فئة XmlDocument تسمح بدقة الكيان افتراضياً.

مثال

لتعطيل دقة الكيان لـ XmlDocuments، استخدم XmlDocument.Load(XmlReader) التحميل الزائد لأسلوب التحميل وقم بتعيين الخصائص المناسبة في وسيطة XmlReader لتعطيل الدقة، كما هو موضح في التعليمة البرمجية التالية:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);

مثال

إذا لم يكن تعطيل دقة الكيان ممكناً لتطبيقك، فاضبط خاصية XmlReaderSettings.MaxCharactersFromEntities على قيمة معقولة وفقاً لاحتياجات التطبيق الخاص بك. سيؤدي ذلك إلى الحد من تأثير هجمات DoS التوسعية المحتملة. تقدم التعليمة البرمجية التالية مثالاً على هذا الأسلوب:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);

مثال

إذا كنت بحاجة إلى حل الكيانات المضمنة ولكنك لا تحتاج إلى حل الكيانات الخارجية، فقم بتعيين الخاصية XmlReaderSettings.XmlResolver على قيمة خالية. على سبيل المثال:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);

لاحظ أنه في MSXML6، تم تعيين ProhibitDTD على true (تعطيل معالجة DTD) افتراضياً. بالنسبة إلى كود Apple OSX/iOS، هناك نوعان من محللي XML يمكنك استخدامهما: NSXMLParser وlibXML2.

التطبيقات التي تستخدم http.sys تنفذ التحقق من عنوان URL الأساسي

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوات

يجب أن يتبع أي تطبيق يستخدم http.sys الإرشادات التالية:

  • حدد طول عنوان URL بما لا يزيد عن 16384 حرفاً (ASCII أو Unicode). هذا هو الحد الأقصى المطلق لطول URL استناداً إلى الإعداد الافتراضي Internet Information Services (IIS) على رقم 6. يجب أن تسعى مواقع الويب إلى طول أقصر من هذا إن أمكن
  • استخدم فئات الإدخال/الإخراج القياسية لملف .NET Framework (مثل FileStream) لأنها ستستفيد من قواعد تحديد العنوان في .NET FX
  • قم بإنشاء قائمة سماح بأسماء الملفات المعروفة
  • رفض صراحة أنواع الملفات المعروفة التي لن تخدمها UrlScan المرفوضة: ملفات exe, bat, cmd, com, htw, ida, idq, htr, idc, shtm[l], stm, printer, ini, pol, dat
  • اكتشف الاستثناءات التالية:
    • System.ArgumentException (لأسماء الأجهزة)
    • System.NotSupportedException (لتدفقات البيانات)
    • System.IO.FileNotFoundException (لأسماء ملفات تم تجاوزها غير صالحة)
    • System.IO.DirectoryNotFoundException (للأدلة الملغاة غير الصالحة)
  • لا تستدعِ ملف Win32 I/O APIs. على عنوان URL غير صالح، قم بإرجاع خطأ 400 للمستخدم بأمان، وقم بتسجيل الخطأ الحقيقي.

تأكد من وجود عناصر التحكم المناسبة عند قبول الملفات من المستخدمين

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع تحميل ملف غير مقيد، جدول توقيع الملف
الخطوات

تمثل الملفات التي تم تحميلها خطراً كبيراً على التطبيقات.

تتمثل الخطوة الأولى في العديد من الهجمات في الحصول على بعض التعليمة البرمجية إلى النظام لتتم مهاجمتها. ثم يحتاج الهجوم فقط إلى إيجاد طريقة لتنفيذ التعليمة البرمجية. يساعد استخدام تحميل الملف المهاجم على إنجاز الخطوة الأولى. يمكن أن تختلف عواقب تحميل الملفات غير المقيد، بما في ذلك الاستيلاء الكامل على النظام، ونظام الملفات أو قاعدة البيانات المحملة بشكل زائد، وإعادة توجيه الهجمات إلى الأنظمة الخلفية، والتشويه البسيط.

يعتمد ذلك على ما يفعله التطبيق بالملف الذي تم تحميله وخاصة مكان تخزينه. التحقق من جانب الخادم لعمليات تحميل الملفات مفقود. يجب تنفيذ ضوابط الأمان التالية لوظيفة تحميل الملفات:

  • فحص ملحق الملف (يجب قبول مجموعة صالحة فقط من أنواع الملفات المسموح بها)
  • الحد الأقصى لحجم الملف
  • لا ينبغي تحميل الملف إلى webroot؛ يجب أن يكون الموقع دليلاً على محرك أقراص غير تابع للنظام
  • يجب اتباع اصطلاح التسمية، بحيث يكون لاسم الملف الذي تم تحميله بعض العشوائية، وذلك لمنع الكتابة فوق الملف
  • يجب فحص الملفات بحثاً عن برنامج مكافحة الفيروسات قبل الكتابة إلى القرص
  • تأكد من التحقق من صحة اسم الملف وأي بيانات تعريف أخرى (مثل مسار الملف) للأحرف الضارة
  • يجب التحقق من توقيع تنسيق الملف، لمنع المستخدم من تحميل ملف متخفي (على سبيل المثال، تحميل ملف exe عن طريق تغيير الملحق إلى txt)

مثال

للنقطة الأخيرة المتعلقة بالتحقق من صحة توقيع تنسيق الملف، راجع الفئة أدناه للحصول على التفاصيل:

        private static Dictionary<string, List<byte[]>> fileSignature = new Dictionary<string, List<byte[]>>
                    {
                    { ".DOC", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } } },
                    { ".DOCX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".PDF", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
                    { ".ZIP", new List<byte[]> 
                                            {
                                              new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                                              new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x55 },
                                              new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
                                              new byte[] { 0x50, 0x4B, 0x05, 0x06 },
                                              new byte[] { 0x50, 0x4B, 0x07, 0x08 },
                                              new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 }
                                                }
                                            },
                    { ".PNG", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
                    { ".JPG", new List<byte[]>
                                    {
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 }
                                    }
                                    },
                    { ".JPEG", new List<byte[]>
                                        { 
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 }
                                        }
                                        },
                    { ".XLS", new List<byte[]>
                                            {
                                              new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
                                              new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
                                              new byte[] { 0xFD, 0xFF, 0xFF, 0xFF }
                                            }
                                            },
                    { ".XLSX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".GIF", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } }
                };

        public static bool IsValidFileExtension(string fileName, byte[] fileData, byte[] allowedChars)
        {
            if (string.IsNullOrEmpty(fileName) || fileData == null || fileData.Length == 0)
            {
                return false;
            }

            bool flag = false;
            string ext = Path.GetExtension(fileName);
            if (string.IsNullOrEmpty(ext))
            {
                return false;
            }

            ext = ext.ToUpperInvariant();

            if (ext.Equals(".TXT") || ext.Equals(".CSV") || ext.Equals(".PRN"))
            {
                foreach (byte b in fileData)
                {
                    if (b > 0x7F)
                    {
                        if (allowedChars != null)
                        {
                            if (!allowedChars.Contains(b))
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                }

                return true;
            }

            if (!fileSignature.ContainsKey(ext))
            {
                return true;
            }

            List<byte[]> sig = fileSignature[ext];
            foreach (byte[] b in sig)
            {
                var curFileSig = new byte[b.Length];
                Array.Copy(fileData, curFileSig, b.Length);
                if (curFileSig.SequenceEqual(b))
                {
                    flag = true;
                    break;
                }
            }

            return flag;
        }

تأكد من استخدام معلمات النوع الآمن في تطبيق الويب للوصول إلى البيانات

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوات

إذا كنت تستخدم مجموعة المعلمات، فإن SQL تتعامل مع الإدخال كقيمة حرفية بدلاً من تعليمة برمجية قابل للتنفيذ. يمكن استخدام مجموعة المعلمات لفرض قيود النوع والطول على بيانات الإدخال. تؤدي القيم الموجودة خارج النطاق إلى استثناء. إذا لم يتم استخدام معلمات SQL الآمنة من النوع، فقد يتمكن المهاجمون من تنفيذ هجمات الإدخال المضمنة في الإدخال غير عامل التصفية.

استخدم معلمات النوع الآمن عند إنشاء استعلامات SQL لتجنب هجمات إدخال SQL المحتملة التي يمكن أن تحدث مع إدخال غير مصفى. يمكنك استخدام معلمات الكتابة الآمنة مع الإجراءات المخزنة وعبارات SQL الديناميكية. يتم التعامل مع المعلمات كقيم حرفية بواسطة قاعدة البيانات وليس ككود قابل للتنفيذ. يتم فحص المعلمات أيضاً من أجل النوع والطول.

مثال

توضح التعليمة البرمجية التالية كيفية استخدام معلمات النوع الآمن مع SqlParameterCollection عند استدعاء إجراء مخزن.

using System.Data;
using System.Data.SqlClient;

using (SqlConnection connection = new SqlConnection(connectionString))
{ 
DataSet userDataset = new DataSet(); 
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection); 
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; 
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); 
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; 
myCommand.Fill(userDataset);
}  

في مثال التعليمة البرمجية السابق، لا يمكن أن تكون قيمة الإدخال أطول من 11 حرفاً. إذا كانت البيانات لا تتوافق مع النوع أو الطول المحدد بواسطة المعلمة، فإن فئة SqlParameter تطرح استثناءً.

استخدم فئات ربط نموذج منفصلة أو قوائم عوامل تصفية ملزمة لمنع ثغرة أمنية كبيرة في تعيينات MVC

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها MVC5، MVC6
السمات ‏‫غير متوفر‬
المراجع سمات بيانات التعريف، ثغرة أمان المفتاح العام والتخفيف منه، الدليل الكامل للتعيين الشامل في ASP.NET MVC، بدء استخدام EF باستخدام MVC
الخطوات
  • متى يجب أن أبحث عن الإفراط في نشر الثغرات الأمنية؟ - يمكن أن يحدث الإفراط في نشر الثغرات الأمنية في أي مكان تقوم فيه بربط فئات النموذج من إدخال المستخدم. يمكن أن تمثل أطر العمل مثل MVC بيانات المستخدم في فئات .NET المخصصة، بما في ذلك Plain Old CLR Objects (POCOs). يملأ MVC فئات النموذج هذه تلقائياً ببيانات من الطلب، ما يوفر تمثيلاً مناسباً للتعامل مع مدخلات المستخدم. عندما تتضمن هذه الفئات خصائص لا ينبغي للمستخدم تعيينها، يمكن أن يكون التطبيق عرضة لهجمات النشر الزائد، والتي تتيح للمستخدم التحكم في البيانات التي لم يقصدها التطبيق مطلقاً. مثل ربط نموذج MVC، غالباً ما تدعم تقنيات الوصول إلى قاعدة البيانات مثل مخططي العناصر/العلائقية مثل Entity Framework أيضاً استخدام عناصر POCO لتمثيل بيانات قاعدة البيانات. توفر فئات نماذج البيانات هذه نفس الراحة في التعامل مع بيانات قاعدة البيانات كما يفعل MVC في التعامل مع مدخلات المستخدم. نظراً لأن كلاً من MVC وقاعدة البيانات يدعمان نماذج متشابهة، مثل عناصر POCO، يبدو من السهل إعادة استخدام نفس الفئات لكلا الغرضين. تفشل هذه الممارسة في الحفاظ على فصل الاهتمامات، وهي منطقة مشتركة واحدة تتعرض فيها الخصائص غير المقصودة لربط النموذج، ما يتيح الإفراط في نشر الهجمات.
  • لماذا لا يجب عليَّ استخدام فئات نموذج قاعدة البيانات التي لم تتم تصفيتها كمعلمات لإجراءات MVC الخاصة بي؟ - لأن ربط نموذج MVC سيربط أي شيء في تلك الفئة. حتى إذا لم تظهر البيانات في طريقة العرض الخاصة بك، يمكن لمستخدم ضار إرسال طلب HTTP مع تضمين هذه البيانات، وسيقوم MVC بربطه بكل سرور لأن الإجراء الخاص بك يقول إن فئة قاعدة البيانات هي شكل البيانات التي يجب أن يقبلها لإدخال المستخدم.
  • لماذا يجب أن أهتم بالشكل المستخدم لربط النموذج؟ - يؤدي استخدام ASP.NET ربط نموذج MVC مع نماذج واسعة للغاية إلى تعريض التطبيق لهجمات النشر الزائد. قد يُمكِّن النشر الزائد المهاجمين من تغيير بيانات التطبيق بما يتجاوز ما قصده المطور، مثل تجاوز سعر عنصر أو امتيازات الأمان لحساب. يجب أن تستخدم التطبيقات نماذج الربط الخاصة بالإجراء (أو قوائم عوامل تصفية الخصائص المسموح بها المحددة) لتوفير عقد صريح لما تسمح به المدخلات غير الموثوق بها عبر ربط النموذج.
  • هل وجود نماذج ربط منفصلة هو مجرد تكرار للتعليمة برمجية؟ - لا، إنها مسألة فصل بين الشواغل. إذا قمت بإعادة استخدام نماذج قاعدة البيانات في طرق الإجراء، فأنت تقول إن أي خاصية (أو خاصية فرعية) في تلك الفئة يمكن تعيينها بواسطة المستخدم في طلب HTTP. إذا لم يكن هذا هو ما تريد من MVC القيام به، فأنت بحاجة إلى قائمة عوامل التصفية أو شكل فئة منفصل لإظهار MVC ما البيانات التي يمكن أن تأتي من إدخال المستخدم بدلاً من ذلك.
  • إذا كان لديَّ نماذج ربط منفصلة لإدخال المستخدم، فهل يتعين عليَّ تكرار جميع سمات التعليقات التوضيحية للبيانات الخاصة بي؟ - ليس بالضرورة. يمكنك استخدام MetadataTypeAttribute في فئة نموذج قاعدة البيانات للارتباط ببيانات التعريف في فئة ربط النموذج. فقط لاحظ أن النوع المشار إليه بواسطة MetadataTypeAttribute يجب أن يكون مجموعة فرعية من النوع المرجعي (يمكن أن يكون لها خصائص أقل، ولكن ليس أكثر).
  • يعد نقل البيانات ذهاباً وإياباً بين نماذج إدخال المستخدم ونماذج قواعد البيانات أمراً شاقاً. هل يمكنني فقط نسخ جميع الخصائص باستخدام الانعكاس؟ - نعم. الخصائص الوحيدة التي تظهر في نماذج الربط هي تلك التي حددتها لتكون آمنة لإدخال المستخدم. لا يوجد سبب أمني يمنع استخدام الانعكاس لنسخ جميع الخصائص المشتركة بين هذين النموذجين.
  • ماذا عن [ربط (استبعاد = "â € ¦")]. هل يمكنني استخدام ذلك بدلاً من امتلاك نماذج ربط منفصلة؟ - هذا النهج غير مستحسن. استخدام [Bind(Exclude ="…")] يعني أن أي خاصية جديدة قابلة للربط افتراضياً. عند إضافة خاصية جديدة، هناك خطوة إضافية يجب تذكرها للحفاظ على أمان الأشياء، بدلاً من جعل التصميم آمناً بشكل افتراضي. اعتماداً على مطور البرامج الذي يتحقق من هذه القائمة في كل مرة يتم فيها إضافة خاصية تكون محفوفة بالمخاطر.
  • هل [Bind(Include ="…")] مفيد لعمليات التحرير؟ - ‏‏لا. إن [Bind(Include ="…")] مناسب فقط للعمليات على غرار INSERT (إضافة بيانات جديدة). بالنسبة للعمليات ذات النمط UPDATE (مراجعة البيانات الموجودة)، استخدم طريقة أخرى، مثل وجود نماذج ربط منفصلة أو تمرير قائمة صريحة بالخصائص المسموح بها إلى UpdateModel أو TryUpdateModel. إن إضافة سمة [Bind(Include ="…")] في عملية التحرير تعني أن MVC سينشئ مثيلاً لعنصر ويضبط الخصائص المدرجة فقط، مع ترك جميع الخصائص الأخرى في قيمها الافتراضية. عند استمرار البيانات، ستحل محل الكيان الحالي بالكامل، مع إعادة تعيين قيم أي خصائص تم حذفها إلى إعداداتها الافتراضية. على سبيل المثال، إذا تم حذف IsAdmin من السمة [Bind(Include ="…")] في عملية التحرير، فستتم إعادة تعيين أي مستخدم تم تحرير اسمه من خلال هذا الإجراء إلى IsAdmin = false (أي مستخدم تم تعديله سيفقد المسؤول الحالة). إذا كنت تريد منع التحديثات على خصائص معينة، فاستخدم أحد الأساليب الأخرى المذكورة أعلاه. لاحظ أن بعض إصدارات أدوات MVC تنشئ فئات تحكم مع [Bind(Include ="…")] في إجراءات التحرير وتلمح إلى أن إزالة خاصية من تلك القائمة ستمنع هجمات النشر الزائد. ومع ذلك، كما هو موضح أعلاه، لا يعمل هذا الأسلوب على النحو المنشود وبدلاً من ذلك سيعيد تعيين أي بيانات في الخصائص المحذوفة إلى قيمها الافتراضية.
  • بالنسبة لعمليات الإنشاء، هل هناك أي محاذير باستخدام [Bind(Include ="…")] بدلاً من نماذج الربط المنفصلة؟ - نعم. أولاً، لا يعمل هذا الأسلوب في تحرير السيناريوهات، ما يتطلب الحفاظ على نهجين منفصلين للتخفيف من الإفراط في نشر الثغرات الأمنية. ثانياً، تفرض نماذج الربط المنفصلة فصل الاهتمامات بين الشكل المستخدم لإدخال المستخدم والشكل المستخدم للثبات، وهو شيء لا يفعله [Bind(Include ="…")]. ثالثاً، لاحظ أن [Bind(Include ="…")] يمكنها فقط التعامل مع خصائص المستوى الأعلى؛ لا يمكنك السماح فقط بأجزاء من الخصائص الفرعية (مثل "Details.Name") في السمة. أخيراً، وربما الأهم من ذلك، أن استخدام [Bind(Include ="…")] يضيف خطوة إضافية يجب تذكرها في أي وقت يتم فيه استخدام الفئة لربط النموذج. إذا ارتبطت طريقة إجراء جديدة بفئة البيانات مباشرة ونسيت تضمين سمة [Bind(Include ="…")]، فيمكن أن تكون عرضة للهجمات الزائدة عن الحاجة، لذا فإن [Bind (Include = "â € ¦ ")] أقل أماناً إلى حد ما بشكل افتراضي. إذا كنت تستخدم [Bind(Include ="…")]، فاحرص دائماً على تذكر تحديده في كل مرة تظهر فيها فئات البيانات كمعلمات أسلوب الإجراء.
  • بالنسبة لعمليات الإنشاء، ماذا عن وضع السمة [Bind(Include ="…")] على فئة النموذج نفسها؟ ألا يتجنب هذا النهج الحاجة إلى تذكر وضع السمة على كل طريقة عمل؟ - ويعمل هذا النهج في بعض الحالات. يؤدي استخدام [Bind(Include ="…")] في نوع النموذج نفسه (بدلاً من معلمات الإجراء التي تستخدم هذه الفئة) إلى تجنب الحاجة إلى تذكر تضمين [Bind(Include ="…")] السمة على كل طريقة عمل. يؤدي استخدام السمة مباشرة على الفئة إلى إنشاء مساحة سطح منفصلة لهذه الفئة لأغراض ربط النموذج. ومع ذلك، فإن هذا الأسلوب يسمح فقط لشكل ربط نموذج واحد لكل فئة نموذج. إذا احتاجت إحدى طرق الإجراء إلى السماح بربط نموذج للحقل (على سبيل المثال، إجراء خاص بالمسؤول فقط يقوم بتحديث أدوار المستخدم) وتحتاج الإجراءات الأخرى إلى منع ربط النموذج بهذا الحقل، فلن يعمل هذا الأسلوب. يمكن أن يكون لكل فئة شكل ربط نموذج واحد فقط؛ إذا احتاجت الإجراءات المختلفة إلى أشكال ربط مختلفة للنماذج، فإنها تحتاج إلى تمثيل هذه الأشكال المنفصلة باستخدام إما فئات ربط نموذج منفصلة أو سمات منفصلة [Bind(Include ="…")] على طرق الإجراء.
  • ما النماذج الملزمة؟ هل هي نفس الشيء مثل نماذج العرض؟ - هذان مفهومان مرتبطان. يشير مصطلح نموذج الربط إلى فئة النموذج المستخدمة في قائمة معلمات الإجراء (الشكل الذي تم تمريره من نموذج MVC يرتبط بطريقة الإجراء). يشير مصطلح نموذج العرض إلى فئة النموذج التي تم تمريرها من طريقة الإجراء إلى طريقة العرض. يعد استخدام نموذج خاص بالعرض طريقة شائعة لتمرير البيانات من طريقة إجراء إلى طريقة عرض. غالباً ما يكون هذا الشكل مناسباً أيضاً لربط النموذج، ويمكن استخدام مصطلح نموذج العرض للإشارة إلى نفس النموذج المستخدم في كلا المكانين. لكي نكون دقيقين، يتحدث هذا الإجراء بشكل خاص عن نماذج الربط، مع التركيز على الشكل الذي تم تمريره إلى الإجراء، وهو ما يهم لأغراض التخصيص الجماعي.

ترميز مخرجات الويب غير الموثوق بها قبل العرض

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها عام، نماذج الويب، MVC5، MVC6
السمات ‏‫غير متوفر‬
المراجع كيفية منع البرمجة النصية عبر المواقع في ASP.NET، البرمجة النصية عبر المواقع، ورقة الغش الخاصة بمنع XSS (البرمجة النصية عبر المواقع)
الخطوات البرمجة النصية عبر المواقع (التي يشار إليها عادةً باسم XSS) هي متجه هجوم للخدمات عبر الإنترنت أو أي تطبيق/مكون يستهلك مدخلات من الويب. قد تسمح ثغرات XSS للمهاجم بتنفيذ نص برمجي على جهاز مستخدم آخر من خلال تطبيق ويب ضعيف. يمكن استخدام البرامج النصية الضارة لسرقة ملفات تعريف الارتباط والتلاعب بجهاز الضحية من خلال JavaScript. يتم منع XSS من خلال التحقق من صحة إدخال المستخدم، والتأكد من تشكيله جيداً وترميزه قبل عرضه في صفحة ويب. يمكن التحقق من صحة الإدخال وترميز الإخراج باستخدام مكتبة حماية الويب. بالنسبة إلى التعليمة البرمجية المُدارة (C #، VB.NET، إلخ)، استخدم طريقة أو أكثر من طرق الترميز المناسبة من مكتبة حماية الويب (Anti-XSS)، اعتماداً على السياق الذي يظهر فيه إدخال المستخدم:

مثال

* Encoder.HtmlEncode 
* Encoder.HtmlAttributeEncode 
* Encoder.JavaScriptEncode 
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode 
* Encoder.XmlEncode 
* Encoder.XmlAttributeEncode 
* Encoder.CssEncode 
* Encoder.LdapEncode 

إجراء التحقق من صحة الإدخال والتصفية لجميع خصائص النموذج من نوع السلسلة

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها Generic, MVC5, MVC6
السمات ‏‫غير متوفر‬
المراجع إضافة التحقق، التحقق من صحة بيانات النموذج في تطبيق MVC، الكيانات التوجيهية لتطبيقات ASP.NET MVC
الخطوات

يجب التحقق من صحة جميع معلمات الإدخال قبل استخدامها في التطبيق لضمان حماية التطبيق من إدخالات المستخدم الضارة. تحقق من صحة قيم الإدخال باستخدام عمليات التحقق من صحة التعبير العادي على جانب الخادم باستخدام استراتيجية التحقق من صحة القائمة المسموح بها. يمكن أن تتسبب مدخلات/معلمات المستخدم غير المصححة التي تم تمريرها إلى الأساليب في حدوث ثغرات أمنية في إدخال التعليمة البرمجية.

بالنسبة لتطبيقات الويب، يمكن أن تتضمن نقاط الإدخال أيضاً حقول النموذج وQueryStrings وملفات تعريف الارتباط ورؤوس HTTP ومعلمات خدمة الويب.

يجب إجراء عمليات التحقق من صحة الإدخال التالية عند ربط النموذج:

  • يجب وضع تعليق توضيحي على خصائص النموذج باستخدام التعليق التوضيحي لـ RegularExpression، لقبول الأحرف المسموح بها والحد الأقصى للطول المسموح به
  • يجب أن تؤدي أساليب وحدة التحكم صلاحية ModelState

يجب تطبيق المسح الشامل على حقول النموذج التي تقبل جميع الأحرف، مثل محرر النص المنسق

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ترميز الإدخال غير الآمن، معقم HTML
الخطوات

حدد جميع علامات الترميز الثابتة التي تريد استخدامها. من الممارسات الشائعة قصر التنسيق على عناصر HTML الآمنة، مثل <b> (غامق) و<i> (مائل).

قبل كتابة البيانات، قم بترميزها بتنسيق HTML. هذا يجعل أي نص برمجي ضار آمناً من خلال التسبب في التعامل معه كنص وليس كتعليمة برمجية قابلة للتنفيذ.

  1. تعطيل التحقق من صحة طلب ASP.NET عن طريق إضافة ValidateRequest = السمة "false" إلى التوجيه @ الصفحة
  2. قم بترميز إدخال السلسلة باستخدام أسلوب HtmlEncode
  3. استخدم StringBuilder واستدعِ أسلوب الاستبدال الخاص به لإزالة الترميز بشكل انتقائي على عناصر HTML التي تريد السماح بها

تُعطل الصفحة الموجودة في المراجع التحقق من صحة طلب ASP.NET عن طريق تعيين ValidateRequest="false". يقوم بترميز الإدخال بتنسيق HTML ويسمح بشكل انتقائي لـ <b> و<i> بدلاً من ذلك، يمكن أيضاً استخدام مكتبة .NET لتعقيم HTML.

HtmlSanitizer هي مكتبة .NET لتنظيف أجزاء HTML والمستندات من التركيبات التي يمكن أن تؤدي إلى هجمات XSS. يستخدم AngleSharp لتحليل ومعالجة وعرض HTML وأوراق الأنماط المتتالية. يمكن تثبيت HtmlSanitizer كحزمة NuGet، ويمكن تمرير مدخلات المستخدم من خلال أساليب التعقيم HTML أو CSS ذات الصلة، حسب الاقتضاء، على جانب الخادم. يرجى ملاحظة أنه يجب اعتبار التطهير كعنصر تحكم أمني كخيار أخير فقط.

يعد التحقق من صحة الإدخال وترميز الإخراج ضوابط أمان أفضل.

لا تقم بتعيين عناصر DOM لجهات التلقي التي لا تحتوي على ترميز يحمل في ثناياه عوامل

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوات لا تقوم العديد من وظائف JavaScript بالترميز افتراضياً. عند تعيين مدخلات غير موثوق بها لعناصر DOM عبر هذه الوظائف، فقد يؤدي ذلك إلى تنفيذ البرامج النصية عبر المواقع (XSS).

مثال

فيما يلي أمثلة غير آمنة:

document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);   

لا تستخدم innerHtml؛ بدلاً من ذلك استخدم innerText. بالمثل، استخدم $("#elm").text() بدلاً من $("#elm").html()

التحقق من إغلاق جميع عمليات إعادة التوجيه داخل التطبيق أو من إجرائها بأمان

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع إطار تخويل OAuth 2.0 - فتح معيدات التوجيه
الخطوات

يجب أن يقيد تصميم التطبيق الذي يتطلب إعادة التوجيه إلى موقع يوفره المستخدم أهداف إعادة التوجيه المحتملة إلى قائمة "آمنة" من المواقع أو المجالات المحددة مسبقاً. يجب أن تكون جميع عمليات إعادة التوجيه في التطبيق مغلقة/آمنة.

للقيام بذلك:

  • حدد جميع عمليات إعادة التوجيه
  • تنفيذ التخفيف المناسب لكل إعادة توجيه. تتضمن عوامل التخفيف المناسبة إعادة توجيه القائمة المسموح بها أو تأكيد المستخدم. إذا كان موقع ويب أو خدمة بها ثغرة أمنية مفتوحة لإعادة التوجيه تستخدم موفري هوية Facebook/OAuth/OpenID، فيمكن للمهاجم سرقة رمز تسجيل دخول المستخدم وانتحال شخصية هذا المستخدم. تعد هذه مخاطرة متأصلة عند استخدام OAuth، الموثق في RFC 6749 "إطار تخويل OAuth 2.0"، القسم 10.15 "عمليات إعادة التوجيه المفتوحة" وبالمثل، يمكن اختراق بيانات اعتماد المستخدمين عن طريق هجمات التصيّد الاحتيالي باستخدام عمليات إعادة التوجيه المفتوحة

تنفيذ التحقق من صحة الإدخال على جميع معلمات نوع السلسلة المقبولة بواسطة أساليب وحدة التحكم

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها Generic, MVC5, MVC6
السمات ‏‫غير متوفر‬
المراجع التحقق من صحة بيانات النموذج في تطبيق MVC، الكيانات التوجيهية لتطبيقات ASP.NET MVC
الخطوات بالنسبة للطرق التي تقبل فقط نوع البيانات البدائي، وليس النماذج كوسيطة، يجب إجراء التحقق من صحة الإدخال باستخدام التعبير العادي. هنا يجب استخدام Regex.IsMatch مع نمط regex صالح. إذا كان الإدخال لا يتطابق مع التعبير العادي المحدد، فيجب ألا يستمر التحكم أكثر، ويجب عرض تحذير مناسب بشأن فشل التحقق من الصحة.

تعيين مهلة الحد الأعلى لمعالجة التعبير العادي لمنع DoS بسبب التعبيرات العادية غير الصحيحة

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها عام، نماذج الويب، MVC5، MVC6
السمات ‏‫غير متوفر‬
المراجع خاصية DefaultRegexMatchTimeout
الخطوات لضمان هجمات رفض الخدمة ضد التعبيرات العادية التي تم إنشاؤها بشكل سيئ، والتي تسبب الكثير من التراجع، قم بتعيين المهلة الافتراضية العامة. إذا استغرق وقت المعالجة وقتاً أطول من الحد الأعلى المحدد، فسيؤدي ذلك إلى استثناء المهلة. إذا لم يتم تكوين أي شيء، فستكون المهلة لانهائية.

مثال

على سبيل المثال، سيؤدي التكوين التالي إلى طرح RegexMatchTimeoutException، إذا استغرقت المعالجة أكثر من 5 ثوانٍ:

<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />

تجنب استخدام Html.Raw في عروض Razor

‏‫العنوان التفاصيل
المكون تطبيق ويب
مرحلة SDL إنشاء
التقنيات المعمول بها MVC5، MVC6
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوة تقوم صفحات الويب ASP.NET (Razor) بتنفيذ ترميز HTML تلقائياً. جميع السلاسل المطبوعة بواسطة شذرات التعليمة البرمجية المضمنة (@ block) يتم ترميزها تلقائياً بتنسيق HTML. ومع ذلك، عندما يتم استدعاء الأسلوب HtmlHelper.Raw، فإنه يقوم بإرجاع ترميز غير مشفر بتنسيق HTML. إذا تم استخدام الأسلوب المساعد Html.Raw()، فإنه يتجاوز حماية الترميز التلقائية التي توفرها Razor.

مثال

فيما يلي مثال غير آمن:

<div class="form-group">
            @Html.Raw(Model.AccountConfirmText)
        </div>
        <div class="form-group">
            @Html.Raw(Model.PaymentConfirmText)
        </div>
</div>

لا تستخدم Html.Raw() إلا إذا كنت تريد عرض الترميز. لا تؤدي هذه الطريقة ترميز الإخراج ضمنياً. استخدم أدوات مساعدة ASP.NET الأخرى، على سبيل المثال، @Html.DisplayFor()

لا تستخدم الاستعلامات الديناميكية في الإجراءات المخزنة

‏‫العنوان التفاصيل
المكون قاعدة بيانات
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوات

يستغل هجوم إدخال SQL الثغرات الأمنية في التحقق من صحة الإدخال لتشغيل أوامر عشوائية في قاعدة البيانات. يمكن أن يحدث عندما يستخدم التطبيق الخاص بك مدخلات لإنشاء عبارات SQL ديناميكية للوصول إلى قاعدة البيانات. يمكن أن يحدث أيضاً إذا كانت التعليمة البرمجية الخاصة بك تستخدم الإجراءات المخزنة التي يتم تمريرها سلاسل تحتوي على مدخلات المستخدم الأولية. باستخدام هجوم إدخال SQL، يمكن للمهاجم تنفيذ أوامر عشوائية في قاعدة البيانات. يجب أن تكون جميع جمل SQL (بما في ذلك عبارات SQL في الإجراءات المخزنة) ذات معلمات. ستقبل عبارات SQL ذات المعلمات الأحرف التي لها معنى خاص لـ SQL (مثل علامة اقتباس واحدة) دون مشاكل لأنها مكتوبة بشدة.

مثال

فيما يلي مثال على إجراء تخزين ديناميكي غير آمن:

CREATE PROCEDURE [dbo].[uspGetProductsByCriteria]
(
  @productName nvarchar(200) = NULL,
  @startPrice float = NULL,
  @endPrice float = NULL
)
AS
 BEGIN
  DECLARE @sql nvarchar(max)
  SELECT @sql = ' SELECT ProductID, ProductName, Description, UnitPrice, ImagePath' +
       ' FROM dbo.Products WHERE 1 = 1 '
       PRINT @sql
  IF @productName IS NOT NULL
     SELECT @sql = @sql + ' AND ProductName LIKE ''%' + @productName + '%'''
  IF @startPrice IS NOT NULL
     SELECT @sql = @sql + ' AND UnitPrice > ''' + CONVERT(VARCHAR(10),@startPrice) + ''''
  IF @endPrice IS NOT NULL
     SELECT @sql = @sql + ' AND UnitPrice < ''' + CONVERT(VARCHAR(10),@endPrice) + ''''

  PRINT @sql
  EXEC(@sql)
 END

مثال

فيما يلي نفس الإجراء المخزن الذي تم تنفيذه بأمان:

CREATE PROCEDURE [dbo].[uspGetProductsByCriteriaSecure]
(
             @productName nvarchar(200) = NULL,
             @startPrice float = NULL,
             @endPrice float = NULL
)
AS
       BEGIN
             SELECT ProductID, ProductName, Description, UnitPrice, ImagePath
             FROM dbo.Products where
             (@productName IS NULL or ProductName like '%'+ @productName +'%')
             AND
             (@startPrice IS NULL or UnitPrice > @startPrice)
             AND
             (@endPrice IS NULL or UnitPrice < @endPrice)         
       END

تأكد من إجراء التحقق من صحة النموذج باستخدام أساليب Web API

‏‫العنوان التفاصيل
المكون واجهة API للويب
مرحلة SDL إنشاء
التقنيات المعمول بها MVC5، MVC6
السمات ‏‫غير متوفر‬
المراجع التحقق من النموذج في ASP.NET Web API
الخطوات عندما يرسل العميل البيانات إلى واجهة برمجة تطبيقات الويب، فمن الضروري التحقق من صحة البيانات قبل القيام بأي معالجة. بالنسبة لـ ASP.NET Web APIs التي تقبل النماذج كمدخلات، استخدم التعليقات التوضيحية للبيانات على النماذج لتعيين قواعد التحقق من الصحة على خصائص النموذج.

مثال

توضح التعليمة البرمجية التالية نفسها:

using System.ComponentModel.DataAnnotations;

namespace MyApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        [RegularExpression(@"^[a-zA-Z0-9]*$", ErrorMessage="Only alphanumeric characters are allowed.")]
        public string Name { get; set; }
        public decimal Price { get; set; }
        [Range(0, 999)]
        public double Weight { get; set; }
    }
}

مثال

في طريقة عمل وحدات تحكم API، يجب التحقق من صلاحية النموذج بشكل صريح كما هو موضح أدناه:

namespace MyApi.Controllers
{
    public class ProductsController : ApiController
    {
        public HttpResponseMessage Post(Product product)
        {
            if (ModelState.IsValid)
            {
                // Do something with the product (not shown).

                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }
    }
}

تنفيذ التحقق من صحة الإدخال على جميع معلمات نوع السلسلة المقبولة بواسطة أساليب Web API

‏‫العنوان التفاصيل
المكون واجهة API للويب
مرحلة SDL إنشاء
التقنيات المعمول بها عام، MVC 5، MVC 6
السمات ‏‫غير متوفر‬
المراجع التحقق من صحة بيانات النموذج في تطبيق MVC، الكيانات التوجيهية لتطبيقات ASP.NET MVC
الخطوات بالنسبة للطرق التي تقبل فقط نوع البيانات البدائي، وليس النماذج كوسيطة، يجب إجراء التحقق من صحة الإدخال باستخدام التعبير العادي. هنا يجب استخدام Regex.IsMatch مع نمط regex صالح. إذا كان الإدخال لا يتطابق مع التعبير العادي المحدد، فيجب ألا يستمر التحكم أكثر، ويجب عرض تحذير مناسب بشأن فشل التحقق من الصحة.

تأكد من استخدام معلمات النوع الآمن في Web API للوصول إلى البيانات

‏‫العنوان التفاصيل
المكون واجهة API للويب
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع ‏‫غير متوفر‬
الخطوات

إذا كنت تستخدم مجموعة المعلمات، فإن SQL تتعامل مع الإدخال كقيمة حرفية بدلاً من تعليمة برمجية قابل للتنفيذ. يمكن استخدام مجموعة المعلمات لفرض قيود النوع والطول على بيانات الإدخال. تؤدي القيم الموجودة خارج النطاق إلى استثناء. إذا لم يتم استخدام معلمات SQL الآمنة من النوع، فقد يتمكن المهاجمون من تنفيذ هجمات الإدخال المضمنة في الإدخال غير عامل التصفية.

استخدم معلمات النوع الآمن عند إنشاء استعلامات SQL لتجنب هجمات إدخال SQL المحتملة التي يمكن أن تحدث مع إدخال غير مصفى. يمكنك استخدام معلمات الكتابة الآمنة مع الإجراءات المخزنة وعبارات SQL الديناميكية. يتم التعامل مع المعلمات كقيم حرفية بواسطة قاعدة البيانات وليس ككود قابل للتنفيذ. يتم فحص المعلمات أيضاً من أجل النوع والطول.

مثال

توضح التعليمة البرمجية التالية كيفية استخدام معلمات النوع الآمن مع SqlParameterCollection عند استدعاء إجراء مخزن.

using System.Data;
using System.Data.SqlClient;

using (SqlConnection connection = new SqlConnection(connectionString))
{ 
DataSet userDataset = new DataSet(); 
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection); 
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; 
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); 
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; 
myCommand.Fill(userDataset);
}  

في مثال التعليمة البرمجية السابق، لا يمكن أن تكون قيمة الإدخال أطول من 11 حرفاً. إذا كانت البيانات لا تتوافق مع النوع أو الطول المحدد بواسطة المعلمة، فإن فئة SqlParameter تطرح استثناءً.

استخدام استعلامات SQL ذات معلمات لـ Azure Cosmos DB

‏‫العنوان التفاصيل
المكون Azure Cosmos DB
مرحلة SDL إنشاء
التقنيات المعمول بها العام
السمات ‏‫غير متوفر‬
المراجع الإعلان عن معلمات SQL في Azure Cosmos DB
الخطوات رغم أن Azure Cosmos DB لا يدعم سوى استعلامات القراءة فقط، إلا إن إدخال SQL يظل ممكناً إذا تم إنشاء الاستعلامات من خلال ربطها بإدخال المستخدم. قد يكون من الممكن للمستخدم الوصول إلى البيانات التي لا ينبغي له الوصول إليها ضمن نفس المجموعة عن طريق صياغة استعلامات SQL ضارة. استخدم استعلامات SQL ذات المعلمات إذا تم إنشاء الاستعلامات بناءً على مدخلات المستخدم.

التحقق من صحة إدخال WCF من خلال ربط المخطط

‏‫العنوان التفاصيل
المكون WCF
مرحلة SDL إنشاء
التقنيات المعمول بها عام، NET Framework 3
السمات ‏‫غير متوفر‬
المراجع Msdn
الخطوات

يؤدي عدم التحقق من الصحة إلى أنواع مختلفة من هجمات الإدخال.

يمثل التحقق من صحة الرسائل خط دفاع واحد في حماية تطبيق WCF الخاص بك. باستخدام هذا الأسلوب، يمكنك التحقق من صحة الرسائل باستخدام المخططات لحماية عمليات خدمة WCF من هجوم من قِبل عميل ضار. تحقق من صحة جميع الرسائل التي يتلقاها العميل لحماية العميل من هجوم من قِبل خدمة ضارة. يتيح التحقق من صحة الرسائل إمكانية التحقق من صحة الرسائل عندما تستهلك العمليات عقود الرسائل أو عقود البيانات، وهو ما لا يمكن إجراؤه باستخدام التحقق من صحة المعلمة. يتيح لك التحقق من صحة الرسائل إنشاء منطق تحقق داخل المخططات، وبالتالي توفير المزيد من المرونة وتقليل وقت التطوير. يمكن إعادة استخدام المخططات عبر تطبيقات مختلفة داخل المؤسسة، وإنشاء معايير لتمثيل البيانات. بالإضافة إلى ذلك، يتيح لك التحقق من صحة الرسائل حماية العمليات عندما تستهلك أنواع بيانات أكثر تعقيداً تتضمن عقوداً تمثل منطق الأعمال.

لإجراء التحقق من صحة الرسائل، عليك أولاً إنشاء مخطط يمثل عمليات الخدمة وأنواع البيانات التي تستهلكها تلك العمليات. يمكنك بعد ذلك إنشاء فئة .NET التي تنفذ مفتش رسائل العميل المخصص ومراقب رسائل المرسل المخصص للتحقق من صحة الرسائل المرسلة/المستلمة إلى/من الخدمة. بعد ذلك، تقوم بتنفيذ سلوك نقطة نهاية مخصص لتمكين التحقق من صحة الرسائل على كل من العميل والخدمة. أخيراً، تقوم بتنفيذ عنصر تكوين مخصص على الفئة يتيح لك عرض سلوك نقطة النهاية المخصصة الموسعة في ملف التكوين الخاص بالخدمة أو العميل "

WCF- التحقق من صحة الإدخال من خلال مفتشي المعلمات

‏‫العنوان التفاصيل
المكون WCF
مرحلة SDL إنشاء
التقنيات المعمول بها عام، NET Framework 3
السمات ‏‫غير متوفر‬
المراجع Msdn
الخطوات

يمثل التحقق من صحة المدخلات والبيانات خط دفاع مهماً في حماية تطبيق WCF الخاص بك. يجب عليك التحقق من صحة جميع المعلمات المعروضة في عمليات خدمة WCF لحماية الخدمة من هجوم من قِبل عميل ضار. على العكس من ذلك، يجب عليك أيضاً التحقق من صحة جميع قيم الإرجاع التي يتلقاها العميل لحماية العميل من هجوم من قِبل خدمة ضارة

يوفر WCF نقاط توسع مختلفة تسمح لك بتخصيص سلوك وقت تشغيل WCF عن طريق إنشاء ملحقات مخصصة. مفتشو الرسائل ومفتشو المعلمات هما آليتان للتوسعة تستخدمان للحصول على تحكم أكبر في البيانات التي تمر بين العميل والخدمة. يجب عليك استخدام مفتشي المعلمات للتحقق من صحة الإدخال واستخدام مفتشي الرسائل فقط عندما تحتاج إلى فحص الرسالة الكاملة المتدفقة داخل وخارج الخدمة.

لإجراء التحقق من صحة الإدخال، ستنشئ فئة .NET وتنفذ مفتشاً مخصصاً للمعلمات من أجل التحقق من صحة المعلمات في العمليات في خدمتك. ستقوم بعد ذلك بتنفيذ سلوك نقطة نهاية مخصص لتمكين التحقق من الصحة على كل من العميل والخدمة. أخيراً، ستقوم بتنفيذ عنصر تكوين مخصص على الفئة يسمح لك بكشف سلوك نقطة النهاية المخصصة الموسعة في ملف التكوين الخاص بالخدمة أو العميل