في المقالة السابقة، تحدثنا بالفعل عن جوهر الثغرات الأمنية في هجوم حقن SQL والتي تنتج عن البرمجة غير الصحيحة من قبل المبرمجين. والآن سنواصل الحديث عن كيفية البرمجة بشكل صحيح حتى لا يتم مهاجمتها عن طريق حقن SQL المشكلة دعونا نلقي نظرة على جزء من التعليمات البرمجية أولاً:
انسخ رمز الكود كما يلي:
خافت sql_injdata، SQL_inj، SQL_Get، SQL_Data، Sql_Post
SQL_injdata = '|و|exec|إدراج|تحديد|حذف|تحديث|عدد|*|%|chr|منتصف|رئيس|اقتطاع|شار|إعلان
SQL_inj = تقسيم (SQL_Injdata، |)
إذا Request.QueryString<> ثم
لكل SQL_Get في Request.QueryString
بالنسبة لـ SQL_Data=0 إلى Ubound(SQL_inj)
إذا instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 ثم
Response.Write <Script Language=javascript>alert('يطالبك نظام مكافحة حقن SQL، من فضلك لا تحاول الحقن مرة أخرى!');history.back(-1)</Script>
الاستجابة. النهاية
نهاية إذا
التالي
التالي
نهاية إذا
إذا Request.Form<> ثم
لكل Sql_Post في Request.Form
بالنسبة لـ SQL_Data=0 إلى Ubound(SQL_inj)
إذا instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 ثم
Response.Write <Script Language=javascript>alert('يطالبك نظام مكافحة حقن SQL، من فضلك لا تحاول الحقن مرة أخرى!');history.back(-1)</Script>
الاستجابة. النهاية
نهاية إذا
التالي
التالي
نهاية إذا
هذا جزء من تعليمات برمجية مضادة للحقن لـ ASP تحظى بشعبية كبيرة على الإنترنت. والفكرة هي التحقق من البيانات المرسلة بواسطة طريقة Post وطريقة Get، ومنع حقن SQL عن طريق تصفية الأحرف الحساسة مثل Insert وUpdate وAnd. ، وما إلى ذلك. من الناحية النظرية، إذا قمنا بتصفية عدد كافٍ من الأحرف، فيمكننا بالتأكيد ضمان عدم تعرضنا للهجوم عن طريق حقن SQL، ولكن يرجى توخي الحذر. اقرأ هذا الرمز وانتبه إلى كيفية الحكم عليه من خلال وظيفة instr، وهذا يعني أنه إذا أردت تصفية الحرف، فلا يتم تصفية الكلمة فقط، بل يتم أيضًا تصفية جميع الكلمات. تم تصفية جميع الكلمات التي تحتوي على مجموعات الأحرف التالية، مثل الجزيرة والبر الرئيسي واليد... إذا تمت تصفية هذه الأحرف، فهل سيظل أي شخص على استعداد لاستخدامها؟ لذلك، فإن طريقة تصفية الشخصيات الحساسة هذه لا معنى لها على الإطلاق، ما يفاجئني هو أن مثل هذه القطعة من القمامة يتم نشرها بالفعل على الإنترنت باعتبارها كلاسيكية، وأنا عاجز عن الكلام حقًا.
يقول بعض الأشخاص أن هجمات حقن SQL تنتج عن ربط سلاسل استعلام SQL، لذا فإن استخدام الإجراءات المخزنة دون ربط سلاسل استعلام SQL يمكن أن يحميك من هجمات حقن SQL. ليس بالضرورة، دعونا نلقي نظرة على مثال لهجوم حقن الإجراء المخزن.
رمز الإجراء المخزن dt_GetNews كما يلي:
إنشاء الإجراء dt_GetNews
@newstype int
مثل
حدد * من الأخبار حيث newstype=@newstype
يذهب
رمز الاتصال:
<%
اتصال خافت
تعيين adoconnection=server.createobject(adodb.connection)
'.........تم حذف الكود ذي الصلة لإنشاء اتصال بقاعدة البيانات هنا
adoconnection.execute exec dt_GetNews +request(newstype)
adoconnection. Close
%>
إذا كانت قيمة الطلب (نوع الأخبار) تساوي 1، فإن نتيجة العملية هي إرجاع جميع السجلات التي يكون حقل نوع الأخبار في جدول الأخبار فيها 1. ومع ذلك، إذا كانت قيمة الطلب (نوع الأخبار) هي 1؛ والنتيجة التي تم إرجاعها هي حذف جدول الأخبار.
يمكن أن نرى من هذا المثال أنه حتى استخدام الإجراءات المخزنة سيظل يتعرض للهجوم، بالإضافة إلى ذلك، حدد * من الأخبار حيث لا يتم الربط بين newstype=@newstype، لذلك لا يوجد اتصال لا مفر منه بين ربط سلاسل استعلام SQL وهجمات حقن SQL. قد لا تتمكن الإجراءات المخزنة من الحماية من هجمات الحقن.
فكيف تكتبها دون أن تتعرض لهجوم من خلال حقن SQL؟ أدناه سأقدم طريقة نهائية بصراحة، وهي بسيطة جدًا وبدائية، وهي التحقق من نوع البيانات واستبدال الاقتباس الفردي. سواء كانت Oracle أو Sql Server أو mySql أو Access أو قواعد بيانات علائقية أخرى، يمكن تقسيم أنواع الحقول تقريبًا إلى فئتين: الأنواع الرقمية (مثل int وfloat وما إلى ذلك) وأنواع الأحرف (مثل char وvarchar وما إلى ذلك). ). تختلف عبارات SQL المقابلة قليلاً حسب نوع الحقل، مثل:
يجب أن يكون حقل نوع الأخبار في تحديد * من الأخبار حيث نوع الأخبار=1 حقلاً رقميًا.
حدد * من الأخبار حيث يجب أن يكون نوع الأخبار='الأخبار الاجتماعية' حقل نوع الأخبار عبارة عن حقل حرف.
بالنسبة للحقول الرقمية، ما يجب علينا فعله هو التحقق من نوع بيانات المعلمة. على سبيل المثال، عندما نقوم بإنشاء عبارة استعلام باستخدام تحديد * من الأخبار حيث newstype=+v_newstype، يجب علينا التحقق من نوع بيانات المتغير v_newstype على الأقل يجب أن يكون رقمًا، والذي يمكن أن يكون عددًا صحيحًا أو رقمًا عائمًا إذا تم إجراء هذا التحقق، فحدد * من الأخبار حيث لن يقوم newstype=+v_newstype أبدًا بإنشاء شيء مشابه لـ Select * from news حيث newstype=1. ؛يسقط عبارات مثل أخبار الجدول. السبب وراء كون ASP أكثر عرضة للهجمات من ASP.Net وJSP وما إلى ذلك هو أن المتغيرات في ASP لا تحتاج إلى الإعلان عنها وأن نوع المتغير غير واضح.
بالنسبة لحقول الأحرف، ما يجب علينا فعله هو معالجة علامات الاقتباس المفردة (''). طريقة المعالجة هي استبدال علامة اقتباس واحدة بعلامتي اقتباس مفردتين (''). عند استخدام newstype='+v_newstype+' لإنشاء عبارة الاستعلام، يجب استبدال علامة الاقتباس المفردة في v_newstype بعلامتي اقتباس مفردتين، لأنه في SQL يمثل الجزء المحاط بعلامتي اقتباس مفردتين سلسلة، وعلامتي اقتباس مفردتين متتاليتين يمثل الاقتباس حرف اقتباس واحدًا، بعد هذه المعالجة، سننظر إلى طريقة إنشاء التحديد * من الأخبار حيث يكون newstype='+v_newstype+' عندما تكون قيمة v_newstype هي:
الأخبار الاجتماعية';أسقط جدول الأخبار--
بعد استبدال علامة اقتباس واحدة بعلامتي اقتباس منفردتين، تصبح قيمة v_newstype:
الأخبار الاجتماعية'';أسقط جدول الأخبار--
تصبح عبارة SQL التي تم إنشاؤها:
حدد * من الأخبار حيث newstype='الأخبار الاجتماعية''؛أسقط جدول الأخبار—'
نتيجة الاستعلام هي إرجاع السجلات التي تكون قيمة حقل نوع الأخبار في جدول الأخبار هي الأخبار الاجتماعية';إسقاط أخبار الجدول--، دون التسبب في حذف جدول الأخبار كما كان من قبل.
بالإضافة إلى ذلك، لا تحتاج عبارة التحديد فقط إلى المعالجة، بما في ذلك إدراج وتحديث وحذف وExec وما إلى ذلك، يمكنك إلقاء نظرة على طرق الحقن التالية:
في البنية، أدخل في قيم الأخبار (العنوان) ('+v_title+')،
عندما v_title=123';أسقط أخبار الجدول--';
عند تحديث مجموعة الأخبار /> عندما يكون v_title=123'-- أو v_id=1;drop table news--، فهذه ليست مشكلة في عبارة Select فقط، ولكن قد تواجه العبارات الأخرى مشكلات، لا تركز فقط على Select
باختصار، بعد التحقق من نوع البيانات ومعالجة أحرف الاقتباس المفردة، حتى لو كان لديه كل القدرات، فلن يتمكن من الطيران من راحة يد Tathagata الخاصة بي.