it-swarm.asia

هل تمنع الإجراءات المخزنة إدخال SQL؟

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

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

84
Am1rr3zA

لا ، الإجراءات المخزنة لا تمنع إدخال SQL. في ما يلي مثال فعلي (من تطبيق داخلي أنشأه شخص أعمل فيه) لإجراء مخزن يسمح للأسف بإدخال SQL:

رمز خادم SQL هذا:

CREATE PROCEDURE [dbo].[sp_colunmName2]   
    @columnName as nvarchar(30),
    @type as nvarchar(30), 
    @searchText as nvarchar(30)           
AS
BEGIN
    DECLARE @SQLStatement NVARCHAR(4000)
    BEGIN
        SELECT @SQLStatement = 'select * from Stations where ' 
            + @columnName + ' ' + @type + ' ' + '''' + @searchText + '''' 
        EXEC(@SQLStatement)
    END      
END
GO

تقريبا يعادل postgres:

CREATE or replace FUNCTION public.sp_colunmName2 (
    columnName  varchar(30),
    type varchar(30), 
    searchText  varchar(30) ) RETURNS SETOF stations LANGUAGE plpgsql            
AS
$$
DECLARE SQLStatement VARCHAR(4000);
BEGIN
    SQLStatement = 'select * from Stations where ' 
            || columnName || ' ' || type || ' ' || ''''|| searchText || '''';
    RETURN QUERY EXECUTE  SQLStatement;
END
$$;

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

سواء كنت تستخدم عبارات SQL أو الإجراء المخزن لا يهم. ما يهم هو ما إذا كان SQL الخاص بك يستخدم معلمات أو سلاسل متسلسلة. تمنع المعلمات إدخال SQL ؛ تسمح السلاسل المتسلسلة بإدخال SQL.

71
Kyralessa

هجمات حقن SQL هي تلك التي يتم فيها إلحاق الاستعلامات غير الموثوق بها بشكل مباشر ، مما يسمح للمستخدم بتنفيذ تعليمات برمجية عشوائية بشكل فعال ، كما هو موضح في هذا الكتاب الهزلي XKCD.

وهكذا نحصل على الوضع:

 userInput = getFromHTML # "Robert ') Drop table الطلاب ؛ -" 
 
 Query = "حدد * من الطلاب حيث studentName =" + userInput 

الإجراءات المخزنة هي ، بشكل عام ، دفاعات جيدة ضد هجمات حقن SQL لأنه لا يتم تحليل المعلمات الواردة مطلقًا.

في الإجراء المخزن ، في معظم قواعد البيانات (ولا تنسى أن الاستعلامات المجمعة تحسب كإجراءات مخزنة) تبدو كما يلي:

 
 
 إنشاء procdure foo مخزنة (
 حدد * من الطلاب حيث studentName =: 1 
) ؛ 
 

ثم ، عندما يرغب البرنامج في الوصول ، فإنه يستدعي foo(userInput) ويستعيد النتيجة بسعادة.

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

يمكنك قراءة المزيد عن SQL-Injection:

46
Brian Ballsun-Stanton

نعم ، إلى حد ما.
لن تمنع الإجراءات المخزنة وحدها إدخال SQL.

اسمحوا لي أن أقتبس أولاً عن حقن SQL من OWASP

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

يجب عليك تطهير إدخالات المستخدم وعدم ربط عبارات SQL ، حتى إذا كنت تستخدم الإجراء المخزن.

شرح جيف أتوود عواقب تسلسل SQL في " أعطني SQL ذات معلمات أو أعطني الموت "

فيما يلي الرسوم المتحركة المثيرة للاهتمام التي تتبادر إلى ذهني كلما سمعت حقن SQL alt text أعتقد أنك حصلت على النقطة :-)

إلقاء نظرة على ورقة الغش لمنع حقن SQL ، يتم شرح طرق الوقاية بدقة ...

29
CoderHawk

سلسلة السلاسل هي سبب حقن SQL. يتم تجنب ذلك باستخدام بارامترسيريشن.

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

لذا ، فإن رمزك أعلاه ناتج عن سلسلة من هذه السلاسل

  • exec sp_GetUser '
  • x' AND 1=(SELECT COUNT(*) FROM Client); --
  • ' , '
  • monkey
  • '

هذا يعطي بناء جملة غير صالح ، لحسن الحظ

Parametrising سيعطي

exec sp_GetUser 'x'' AND 1=(SELECT COUNT(*) FROM Client); --' , 'monkey'

هذا يعنى

  • @UserName = x' AND 1=(SELECT COUNT(*) FROM Client); --
  • @Password = monkey

الآن ، في الرمز أعلاه ، لن تحصل على أي صفوف لأنني أفترض أنه ليس لديك مستخدم x' AND 1=(SELECT COUNT(*) FROM Client); --

إذا كان proc المخزن يشبه هذا (باستخدام SQL ديناميكية متسلسلة SQL ) ، فإن مكالمات proc المخزنة الخاصة بك ستظل تسمح بإدخال SQL

...
SET @sql = 'SELECT userName from users where userName = ''' + 
               @UserName + 
               ''' and userPass = ''' +
               @Password +
               ''''
EXEC (@sql)
....

لذا ، كما هو موضح ، سلسلة التسلسل هي العدو الرئيسي لحقن SQL

تضيف الإجراءات المخزنة التغليف ومعالجة المعاملات والأذونات المخفضة وما إلى ذلك ، ولكن لا يزال من الممكن إساءة استخدامها لحقن SQL.

يمكنك إلقاء نظرة على Stack Overflow لمعرفة المزيد عن parametrisation

12
gbn

"تحدث هجمات إدخال SQL عندما يتم = إدخال المستخدم بشكل غير صحيح. عادةً ما يكون إدخال المستخدم هو بعض البيانات التي يرسلها المستخدم مع استعلامه ، أي القيم في $_GET ، $_POST ، $_COOKIE ، $_REQUEST ، أو $_SERVER المصفوفات. ومع ذلك ، يمكن أن يأتي إدخال المستخدم أيضًا من مجموعة متنوعة من المصادر الأخرى ، مثل المقابس والمواقع البعيدة والملفات وما إلى ذلك. لذلك ، يجب عليك حقًا معالجة كل شيء ما عدا الثوابت (مثل 'foobar') كمدخل للمستخدم . "

لقد قمت بالتحقيق بدقة في هذا الموضوع مؤخرًا وأرغب في مشاركته مع الآخرين مواد مثيرة للاهتمام للغاية ، وبالتالي ، جعل هذا المنشور أكثر اكتمالاً وإفادة للجميع.



من يوتيوب


من ويكيبيديا


من OWASP


من PHP يدوي


من Microsoft و Oracle


تجاوز سعة المكدس


ماسح حقن SQL

10
Ilia Rostovtsev

الإجراءات المخزنة لا تمنع بشكل سحري حقن SQL ، لكنها تجعل منعها أسهل بكثير. كل ما عليك فعله هو شيء من هذا القبيل (مثال Postgres):

CREATE OR REPLACE FUNCTION my_func (
  IN in_user_id INT 
)
[snip]
  SELECT user_id, name, address FROM my_table WHERE user_id = in_user_id; --BAM! SQL INJECTION IMMUNE!!
[snip]

هذا هو! لا تظهر المشكلة إلا عند تكوين استعلام عبر سلسلة متسلسلة (أي SQL ديناميكية) ، وحتى في تلك الحالات قد تتمكن من الربط! (يعتمد على قاعدة البيانات.)

كيفية تجنب إدخال SQL في الاستعلام الديناميكي:

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

الخطوة 2) ابحث عن الطريقة المناسبة لتعيين المتغير الخاص بـ RDBMS الخاص بك. على سبيل المثال ، تتيح لك Oracle القيام بما يلي (اقتباس من مستنداتها):

sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE ' 
           || v_column || ' = :2';
EXECUTE IMMEDIATE sql_stmt USING amount, column_value; --INJECTION IMMUNE!!

هنا ما زلت لا تسلسل الإدخال. أنت ملزم بأمان! مرحى!

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

sql_stmt := 'SELECT salary FROM employees WHERE name = ' || quote_literal(in_name);

بهذه الطريقة إذا كان in_name شيء مخادع مثل "[snip] أو 1 = 1" (الجزء "أو 1 = 1" يعني تحديد جميع الصفوف ، مما يسمح للمستخدم برؤية المرتبات التي لا يجب عليه!) ، ثم quote_literal يحفظ مؤخرتك عمل السلسلة الناتجة:

SELECT salary FROM employees WHERE name = '[snip] or 1=1'

لن يتم العثور على نتائج (إلا إذا كان لديك بعض الموظفين بأسماء غريبة حقًا.)

هذا هو جوهر ذلك! دعني الآن أتركك فقط مع رابط إلى منشور كلاسيكي من قبل معلم Oracle Tom Kyte حول موضوع SQL Injection ، لتوجيه النقطة إلى المنزل: Linky

2
MWDB