وأقل مساعدة ستكون من الوظيفة التي طورتها. نمط حقن SQL الأكثر شيوعًا في PHP هو الهروب غير المجدي من البحث في التعليمات البرمجية

لذلك قمت بالتعمق في مجالات MySQL وPHP... وتحديدًا الإجراءات الأمنية التي يجب أن أتخذها عند التعامل مع قاعدة البيانات ومدخلات النماذج. لقد وجدت حتى الآن ما يلي موصى به للغاية:

  1. البيانات المعدة
  2. باستخدام _real_escape_string()
  3. عدم استخدام علامات الاقتباس السحرية لأنها تربك قواعد البيانات وينتهي الأمر بإعطائك أشياء مثل "لم تسميها...".

كل هذا رائع وأنا أراقبه. ومع ذلك، كنت أتساءل عما إذا كان ينبغي علي تجنب أحرف مثل علامة الدولار [$]، وعلامة النسبة المئوية [%]، وربما غيرها. هل يمكن للاستعلام أن يفسر علامة الدولار كمتغير PHP ربما؟ ماذا عن بناء الجملة LIKE الذي سمعته يستخدم الرمز % أو حتى حرف البدل؟ يجب أن تهتم البيانات المعدة بكل هذا من الناحية الفنية، لكنني أردت فقط أن أكون في الجانب الآمن وأتأكد من تغطية كل شيء بشكل صحيح. في الحالات التي أنسى فيها استخدام العبارات المعدة مسبقًا أو أهملها ببساطة، كنت آمل أن يخبرني خط الدفاع الثاني هذا أنني أستطيع التخلص من الدوخة.

إليك ما أستخدمه حاليًا للهروب:

وظيفة الهروب($connection, $data)( $new_data = Trim($data); $new_data = i_real_escape_string($connection, $new_data); $new_data = addcslashes($new_data, "%_$"); $new_data = htmlspecialchars ($new_data، ENT_NOQUOTES)؛ إرجاع $new_data؛

فهل هذا صحيح؟ هل أفعل شيئًا خاطئًا جدًا؟ يرجى ملاحظة أنه عند إرجاع بيانات قاعدة البيانات، سيتعين علي إزالة الخطوط المائلة العكسية قبل الأحرف $ و% و_.

هل أفعل شيئًا خاطئًا جدًا؟

أولا عن البحث الخاص بك.

تصريحات جاهزة – الوحيدشيء رائع وجدته.

على الرغم من أن استخدام mysqli_real_escape_string (على افتراض أنك تستخدم البيانات المعدة) سيكون كذلك عديمة الفائدة والضارة(إنشاء نتيجة لاحظتها بنفسك: "لقد اتصلت ليس\ر...").

وقد تمت إزالة الاقتباسات السحرية من اللغة منذ فترة طويلة - وبالتالي لا تستحق أي شيء حقًا.

لذا فمن الواضح أن معظم مقدماتك الأولية خاطئة.

الآن لسؤالك.

هل يمكن للاستعلام أن يفسر علامة الدولار كمتغير PHP ربما؟

ماذا عن بناء الجملة LIKE الذي سمعته يستخدم الرمز % أو حتى حرف البدل؟

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

في كل مرة ستستخدم فيها عامل التشغيل LIKE، يجب عليك تحديد الحرف المحدد الذي تريد استخدامه وأي الحرف الذي يجب عدم السماح به. لا يمكنك استخدام حل لمرة واحدة. ناهيك عن أنه في جميع تفاعلات MySQL الأخرى، فإن علامة % ليس لها معنى خاص.

يجب أن تهتم البيانات المعدة تقنيًا بكل هذا

البيانات المعدة ليس لها علاقة بعلامات $ أو %. تشير العبارات المعدة إلى حقن SQL، ولكن لا يمكن لأي حرف أن يسبب ذلك (لا يمكنك استدعاء "الحقن" كمشغل LIKE مستخدم بشكل صحيح، أليس كذلك؟).

وأخيرا، إلى أسوأ جزء.

في حالة نسيان استخدام البيانات المعدة أو ببساطة إهمال متابعتها،

لا شيء سيخلصك.

وأقل مساعدة ستكون من الوظيفة التي طورتها.

لخص.

  1. تخلص من هذه الميزة.
  2. يستخدم الحشو *لتمثيل كل متغير فردي في الاستعلام.
  3. قم بإلغاء % و_ من الأحرف في الإدخال فقط إذا كان سيتم استخدامها في عامل التشغيل LIKE ولا تريد تفسيرها.
  4. استخدم htmlspecialchars() للإخراج، وليس إدخال MySQL.

*اقرأ البيانات المعدة إذا كان هذا المصطلح غير مألوف لك.

ليس عليك تجنب علامة الدولار. لا ينظر MySQL إلى هذا الحرف على وجه التحديد، ولا يتعرف عليه PHP إلا في الكود المصدري، وليس في قيم السلسلة (إلا إذا قمت باستدعاء eval على السلسلة، ولكن هذه دودة أخرى تمامًا).

ستحتاج فقط إلى الهروب من % و_ إذا كنت تستخدم إدخال المستخدم كوسيطة LIKE ولا تريد أن يتمكن المستخدم من استخدام أحرف البدل. قد يحدث هذا إذا كنت تقوم بمعالجة نموذج بحث. لا تحتاج إلى استخدامه عند التخزين في قاعدة بيانات.

لا تحتاج إلى استخدام htmlspecialchars عند الوصول إلى قاعدة البيانات. يجب استخدام هذا فقط عند عرض البيانات للمستخدم على صفحة HTML لمنع إدخال XSS.

اعتمادًا على البيانات والغرض الذي يتم استخدامه من أجله.

إذا وجدت أن عبارات PHP الافتراضية الجاهزة كبيرة جدًا ومعقدة، أقترح عليك إلقاء نظرة على بعض الفئات المتوفرة على github لإعطائك فكرة عن الاستعلامات المبسطة.

مثال على إدراج الاستعلامات مع هذه الفئة

$data = Array ("تسجيل الدخول" => "admin"، "active" => صحيح، "firstName" => "John"، "lastName" => "Doe"، "password" => $db->func( "SHA1(?)",Array ("secretpassword+salt")), // كلمة المرور = SHA1("secretpassword+salt") "createdAt" => $db->now(), // createAt = NOW() " تنتهي" => $db->now("+1Y") // انتهاء الصلاحية = NOW() + فاصل زمني سنة واحدة // الفواصل الزمنية المدعومة [s]econd، [m]inute، [h]hour، [d]day، [شهر سنة)؛ $id = $db->insert("users", $data); إذا ($id) echo "تم إنشاء المستخدم. Id=" . معرف $؛ آخر صدى "فشل الإدراج:" . $db->getLastError();


أولاً، القليل عن سبب الحاجة إلى هذه الخطوط المائلة بشكل عام.
إذا قمنا باستبدال أي بيانات في استعلام، فمن أجل تمييز هذه البيانات عن أوامر SQL، يجب وضعها بين علامتي اقتباس.
على سبيل المثال، إذا كنت تكتب
حدد * من الجدول حيث الاسم = بيل
ثم ستقرر قاعدة البيانات أن Bill هو اسم حقل آخر، ولن تجده، وستظهر خطأ. لذلك، يجب وضع البيانات البديلة (في هذه الحالة، اسم Bill) بين علامتي اقتباس - ثم ستعتبرها قاعدة البيانات سلسلة، يجب تعيين قيمتها إلى حقل الاسم:
اختر * من الجدول حيث الاسم = "بيل"
ومع ذلك، قد تظهر علامات الاقتباس أيضًا في البيانات نفسها. على سبيل المثال،
اختر * من الجدول حيث الاسم = "D"Artagnan"
هنا ستقرر قاعدة البيانات أن "D" عبارة عن بيانات، وأن Artagnan هو أمر لا تعرفه، وسيؤدي أيضًا إلى ظهور خطأ. لذلك، من الضروري تتبع جميع البيانات لكي نوضح لقاعدة البيانات أن علامات الاقتباس (وبعض الأحرف الخاصة الأخرى) الموجودة فيها تشير إلى البيانات.
ونتيجة لذلك، سنتلقى طلبًا صحيحًا لن يسبب أخطاء:
اختر * من الجدول حيث الاسم = "D\"Artagnan"

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

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

كل ما سبق ينطبق على بيانات السلسلة والتواريخ. يمكن إدراج الأرقام دون زائدة أو إحاطتها بعلامات الاقتباس. إذا قمت بذلك بعد ذلك بالضرورة!فرض البيانات على النوع المطلوب قبل إدراجها في الاستعلام، على سبيل المثال:
$id = intval ($id);
ومع ذلك، من أجل البساطة (والموثوقية)، يمكنك العمل مع الأرقام كما هو الحال مع السلاسل (نظرًا لأن MySQL لا يزال يحولها إلى النوع المطلوب). وبناء على ذلك، سوف نقوم بتتبع أي بيانات يتم إدراجها في الطلب وإدراجها بين علامتي اقتباس.

هناك أيضًا قاعدة أخرى - اختيارية، ولكن يجب اتباعها لتجنب الأخطاء:
يجب أن تكون أسماء الحقول والجداول محاطة بعلامات اقتباس مفردة خلفية - "`" (يوجد المفتاح الذي يحمل هذا الرمز على لوحة المفاتيح القياسية على يسار المفتاح "1"). بعد كل شيء، يمكن أن يتطابق اسم الحقل مع mysql الكلمات الرئيسية، ولكن إذا استخدمنا الاقتباس الخلفي، فسوف تفهم MySQL أن كل شيء صحيح:
حدد * من "الجدول" حيث "التاريخ" = "04-04-2006"
يجب عليك التمييز بين علامات الاقتباس هذه وعدم الخلط بين إحداهما والأخرى. يجب أن تتذكر أيضًا أن العلامات الخلفية لا يمكن الهروب منها بالشرطة المائلة.

لذلك، تعلمنا كيفية استبدال البيانات بشكل صحيح في الطلب.
لكن! لا يقتصر بناء الاستعلام الديناميكي على استبدال البيانات. غالبًا ما يتعين علينا استبدال أوامر SQL وأسماء الحقول في الاستعلام. وهنا ننتقل إلى موضوع الأمن:

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

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

النقطة الثانية أكثر صعوبة، حيث لا توجد قاعدة عالمية واحدة فيما يتعلق بالبيانات - لن تحمي العلامات الخلفية اسم الحقل من التعديل بواسطة المتسلل. ليس من الممكن استخدام علامات الاقتباس لحماية أسماء الجداول وعبارات SQL ومعلمات أوامر LIMIT والعبارات الأخرى.
ولذلك، فإن القاعدة الأساسية عند استبدال عناصر التحكم في الاستعلام هي:
إذا كنت بحاجة إلى إدراج عبارات SQL أو أسماء الحقول وقواعد البيانات والجداول ديناميكيًا في استعلام، فلا يجب عليك تحت أي ظرف من الظروف إدراجها مباشرة في الاستعلام.
يجب كتابة جميع الخيارات الخاصة بهذه الإضافات مسبقًا في البرنامج النصي الخاص بك وتحديدها بناءً على ما أدخله المستخدم.
على سبيل المثال، إذا كنت بحاجة إلى تمرير اسم حقل إلى الأمر بواسطة عامل التشغيل، فلا ينبغي تحت أي ظرف من الظروف استبداله مباشرة. نحن بحاجة للتحقق من ذلك أولا. على سبيل المثال، أنشئ مصفوفة من القيم الصالحة، واستبدلها في الطلب فقط في حالة وجود المعلمة التي تم تمريرها في هذه المصفوفة:
$orders =array("name" , "price" , "qty" );
$key = array_search($_GET["sort"], $orders));
$orderby = $orders [$key];
استعلام $ = "اختر * من `الجدول` ORDER BY$orderby " ;

نقوم بالبحث في مصفوفة الخيارات الموضحة مسبقًا للكلمة التي أدخلها المستخدم، وإذا وجدناها، نختار العنصر المقابل للمصفوفة. إذا لم يتم العثور على تطابق، سيتم تحديد العنصر الأول من المصفوفة.
وبالتالي، فإن ما يتم استبداله في الطلب ليس هو ما أدخله المستخدم، ولكن ما هو مكتوب في البرنامج النصي الخاص بنا.
ويجب أن يتم نفس الشيء في جميع الحالات الأخرى.
على سبيل المثال، إذا تم إنشاء جملة WHERE ديناميكيًا:
if (!empty($_GET [ "price" ])) $where .= "price="" . mysql_real_escape_string ($_GET [ "price" ]). """ ;
$query = "SELECT * FROM `table` WHERE $where " ;

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

سلسلة الاقتباسات (11)

أحاول معرفة أفضل طريقة لكتابة الاستعلامات. أنا أفهم أيضًا أهمية الاتساق. لقد كنت حتى الآن أستخدم علامات الاقتباس المفردة وعلامات الاقتباس المزدوجة والعلامات الخلفية بشكل عشوائي دون أي تفكير حقيقي.

$query = "INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)";

أيضًا، في المثال أعلاه، ضع في اعتبارك أن "table" و"col[n]" و"val[n]" يمكن أن تكون متغيرات.

ما هو المعيار لهذا؟ ماذا تفعل؟

لقد قرأت إجابات لأسئلة مماثلة لمدة 20 دقيقة تقريبًا، ولكن لا يبدو أن هناك إجابة محددة لهذا السؤال.

الإجابات

لنفترض الآن أنك تستخدم متغير النشر المباشر في استعلام MySQL ثم استخدمه على النحو التالي:

$query = "INSERT INTO `table` (`id`، `name`، `email`) VALUES (" ".$_POST["id"]." "، " ".$_POST["name"]." ", " ".$_POST["البريد الإلكتروني"]";

هذه هي أفضل ممارسة لاستخدام متغيرات PHP في MySQL.

تُستخدم هذه الأنواع من المعرفات بشكل أساسي في Mysql في الاستعلامات ` و " و " و ().

    " أو " يُستخدم لتضمين سلسلة كقيمة "01/26/2014 00:00:00" أو "01/26/2014 00:00:00" . يتم استخدام هذا المعرف فقط لوظيفة السلسلة "01/26/2014 00:00:00"، مثل now() أو sum ,max .

    ` يُستخدم لتضمين جدول أو جدول، على سبيل المثال، حدد اسم العمود من اسم_الجدول حيث المعرف = "2"

    () تُستخدم فقط لإحاطة أجزاء من الاستعلام، على سبيل المثال، حدد column_name من table_name حيث (id = "2" والجنس = "male") أو name = "rakesh.

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

شيء صغير؛ يعتقد MySQL أنك تريد القيام بالرياضياتعلى الجدول/العمود الخاص بك وتفسير الواصلات مثل "البريد الإلكتروني" على أنها بريد إلكتروني.

إنكار المسؤولية.لذلك اعتقدت أنني سأضيف هذا كإجابة "لمعلوماتك" لأولئك الجدد تمامًا في العمل مع قواعد البيانات، والذين قد لا يفهمون المصطلحات التقنية الموضحة بالفعل.

(هناك إجابات جيدة أعلاه فيما يتعلق بطبيعة SQL لسؤالك، ولكن قد يكون هذا أيضًا ذا صلة إذا كنت جديدًا في PHP.)

قد يكون من المهم ملاحظة أن PHP تتعامل مع علامات الاقتباس المفردة والمزدوجة بشكل مختلف...

السلاسل ذات علامات الاقتباس المفردة هي "حرفية" وهي عبارة عن عدد كبير جدًا من سلاسل WYSIWYG. يتم تفسير السلاسل ذات علامات الاقتباس المزدوجة بواسطة PHP لاستبدال متغير محتمل (المراجع الخلفية في PHP ليست سلاسل بالضبط، فهي تنفذ الأمر في الصدفة وترجع النتيجة).

$foo = "شريط"; صدى "هناك $foo"; // يوجد صدى $foo "يوجد صدى $foo"; // يوجد شريط echo `ls -l`; //... قائمة الدليل

إذا كانت جداول وقيم الكولز متغيرة فهناك طريقتان:

مع علامات الاقتباس المزدوجة "" الاستعلام الكامل هو:

$query = "INSERT INTO $table_name (id, $col1, $col2) VALUES (NULL, "$val1", "$val2"");

$query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.") VALUES (NULL, "".$val1.", "".$val2."" ) "؛

مع علامات الاقتباس المفردة "" :

$query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.") VALUES (NULL, ".$val1.", ".$val2.""");

استخدم العلامات الخلفية `` عندما يكون اسم العمود/القيمة مشابهًا للكلمة الأساسية المحجوزة في MySQL.

ملحوظة.إذا قمت بتحديد اسم عمود باسم جدول، فاستخدم علامات التحديد الخلفية مثل هذا:

"اسم_الجدول". `اسم_العمود`<- Примечание: исключить. из задних клещей.

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

يجب استخدام علامات الاقتباس المفردة لقيم السلسلة، كما هو الحال في قائمة VALUES(). يتم دعم علامات الاقتباس المزدوجة بواسطة MySQL لقيم السلسلة أيضًا، ولكن يتم قبول علامات الاقتباس المفردة على نطاق أوسع بواسطة أنظمة RDBMS الأخرى، لذا من الجيد استخدام علامات الاقتباس المفردة بدلاً من علامات الاقتباس المزدوجة.

تتوقع MySQL أيضًا أن يتم وضع القيم الحرفية DATE و DATETIME ضمن علامات اقتباس مفردة كسلاسل، مثل "2001-01-01 00:00:00" . لمزيد من المعلومات، راجع وثائق التاريخ والوقت، وخاصة بدائل استخدام الواصلة - كفاصل مقطع في سلاسل التاريخ.

لذلك باستخدام المثال الخاص بك، أود أن أقوم بإدراج سلسلة PHP مرتين واستخدام علامات الاقتباس المفردة للقيم "val1"، "val2" . NULL هي كلمة أساسية في MySQL وهي غير ذات قيمة وبالتالي لا يتم استخدامها.

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

لا ينبغي اقتباس الوظائف المتعلقة بـ RDBMS (مثل NOW() في MySQL)، على الرغم من أن وسيطاتها تخضع لنفس القواعد أو قواعد الاقتباس المذكورة بالفعل.

Backtick(`) الجدول والعمود ─┬──── ┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ $query = " أدخل في الجدول (`id`، `col1`، `col2`، `date`، `updated`) القيم (NULL، "val1"، "val2"، "2001-01-01"، NOW())"؛ الكلمة الأساسية غير المقتبسة ─────┴┴┴┘ │ │ │ │ │ │││││ السلاسل ذات علامات الاقتباس المفردة ───────────┴─ ───┴── ┴────┘ │ │ │││││ تاريخ ──────────────────── ────┴── وظيفة غير مقتبسة ────────────────────── ────────── ──── ───┴┴┴┴┘

الاستيفاء المتغير

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

// نفس الشيء مع بعض بدائل المتغيرات // هنا، اسم جدول المتغير $table مقتبس بعلامة اقتباس خلفية، والمتغيرات // في قائمة القيم مقتبسة بعلامة اقتباس مفردة $query = "INSERT INTO ``جدول $``(`id`، `col1`، `col2`، `date`) القيم (NULL، "$val1", "$val2", "تاريخ $")";

البيانات المعدة

عند العمل مع البيانات المعدة، راجع الوثائق لتحديد ما إذا كان ينبغي تضمين حشو البيانات. تتضمن واجهات برمجة التطبيقات الأكثر شيوعًا المتوفرة في PHP وPDO وMySQLi غير مصرحالعناصر النائبة، مثل واجهات برمجة تطبيقات التعليمات الأكثر إعدادًا باللغات الأخرى:

// مثال PDO مع المعلمات المسماة، unquoted $query = "INSERT INTO `table` (`id`، `col1`، `col2`، `date`) VALUES (:id, :col1, :col2, :date)" ; // مثال MySQLi مع ? المعلمات، unquoted $query = "INSERT INTO `table` (`id`، `col1`، `col2`، `date`) VALUES (?, ?, ?, ?)";

الرموز التي تُرجع مرجعًا خلفيًا في المعرفات:

على سبيل المثال:

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

تحقق من هذه الإجابة لمعرفة المزيد حول الدبابيس العكسية.

الآن عن الاقتباسات المزدوجة والاقتباسات الفردية (ذكر مايكل هذا بالفعل).

ولكن لتحديد القيمة، تحتاج إلى استخدام علامات الاقتباس المفردة أو المزدوجة. دعونا نرى مثالا آخر.

INSERT INTO `tablename` (`id, `title`) VALUES (NULL, title1);

هنا نسيت عمدا أن أضع العنوان 1 بين علامتي اقتباس. سيقبل الخادم الآن title1 كاسم العمود (أي المعرف). لذا، للإشارة إلى أن هذه قيمة، تحتاج إلى استخدام علامات الاقتباس المزدوجة أو المفردة.

INSERT INTO `tablename` (`id، `title`) القيم (NULL، "title1")؛

الآن، مع PHP، تعمل علامات الاقتباس المزدوجة وعلامات الاقتباس المفردة على تبسيط الوقت الذي تستغرقه كتابة الاستعلام بشكل كبير. دعونا نلقي نظرة على النسخة المعدلة من الاستعلام في سؤالك.

$query = "INSERT INTO `table` (`id`، `col1`، `col2`) VALUES (NULL, "$val1"، "$val2"");

الآن، باستخدام علامات الاقتباس المزدوجة في PHP، ستجعل المتغيرين $val1 و $val2 يستخدمان قيمهما، وبالتالي إنشاء استعلام صالح. يحب

$val1 = "قيمتي 1"; $val2 = "قيمتي 2"; $query = "INSERT INTO `table` (`id`، `col1`، `col2`) VALUES (NULL, "$val1"، "$val2"");

أدخل في `الجدول` (`id`، `col1`، `col2`) القيم (NULL، "my value 1"، "my value 2")

كانت هناك العديد من الإجابات المفيدة هنا، وبلغت ذروتها بشكل عام في نقطتين.

  1. يتم استخدام العلامات الخلفية (`) حول أسماء المعرفات.
  2. يتم استخدام علامات الاقتباس المفردة (") حول القيم.

وكما قالMichaelBerkowski

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

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

123E10 هو اسم معرف صالح، ولكنه أيضًا عدد صحيح صحيح.

[بدون الخوض في التفاصيل حول كيفية الحصول على اسم معرف مثل هذا] لنفترض أنني أريد إنشاء جدول مؤقت يسمى 123456e6.

لا يوجد خطأ في backticcks.

قاعدة البيانات > إنشاء جدول مؤقت `123456e6` (`id` char (8)); الاستعلام موافق، 0 صفوف متأثرة (0.03 ثانية)

خطأ إذا كنت لا تستخدم عمليات الاسترجاعات.

DB> إنشاء جدول مؤقت 123451e6 (`id` char (8)); الخطأ 1064 (42000): لديك خطأ في بناء جملة SQL الخاص بك؛ تحقق من الدليل الذي يتوافق مع إصدار خادم MariaDB لديك للحصول على الصيغة الصحيحة لاستخدامها بالقرب من "123451e6 (`id` char (8))" في السطر 1

ومع ذلك، 123451a6 هو اسم معرف جيد (بدون علامات خلفية).

DB> إنشاء جدول مؤقت 123451a6 (`id` char (8)); الاستعلام موافق، 0 صفوف متأثرة (0.03 ثانية)

هذا تمامًا لأن 1234156e6 هو أيضًا رقم أسي.

يجب استخدام علامات الاقتباس المفردة لقيم السلسلة، كما هو الحال في قائمة VALUES().

تُستخدم العلامات الخلفية عادةً للإشارة إلى معرف ويمكن أن تكون آمنة أيضًا بسبب الاستخدام العرضي للكلمات الرئيسية المحجوزة.

عند دمجها مع PHP وMySQL، تعمل علامات الاقتباس المزدوجة وعلامات الاقتباس المفردة على تبسيط وقت كتابة الاستعلام بشكل كبير.

هناك نوعان من علامات الاقتباس في MySQL:

  1. "لتضمين سلسلة حرفية
  2. ` لتضمين معرفات مثل أسماء الجداول والأعمدة

ثم هناك "هذه حالة خاصة. يمكن استخدامها من أجل واحدمن الأهداف المذكورة أعلاه في وقت واحد اعتمادًا على sql_mode الخاص بالخادم:

  1. تقصيريمكن استخدام "الحرف" لتداخل سلسلة حرفية "
  2. في وضع ANSI_QUOTES "يمكن استخدام الرمز لتضمين المعرفات، ANSI_QUOTES

سيؤدي الاستعلام التالي إلى نتائج (أو أخطاء) مختلفة اعتمادًا على وضع SQL:

حدد "عمود" من الجدول حيث foo = "bar"

تم تعطيل ANSI_QUOTES

سيحدد الاستعلام "العمود" الحرفي للسلسلة حيث يكون العمود foo مساويًا للسلسلة "bar"

تم تمكين ANSI_QUOTES

سيحدد الاستعلام عمودًا حيث يكون العمود foo مساويًا للعمود

متى يجب استخدام

  • أقترح عليك تجنب استخدام "حتى لا يعتمد الكود الخاص بك على أوضاع SQL
  • قم دائمًا بتضمين المعرفات لأن هذه ممارسة جيدة (هناك عدد قليل من الأسئلة حول SO تناقش هذا)

هناك فرق واضح بين استخدام " " و " " .

عندما يتم استخدام " " طوال الوقت، لا يوجد "تحويل أو ترجمة". تتم طباعتها كما هي.

مع "" كل ما يحيط به يتم "ترجمته أو تحويله" إلى قيمته.

ما أعنيه بالترجمة/التحويل هو أن أي شيء موجود ضمن علامات الاقتباس المفردة لن يتم "ترجمته" إلى قيمه. سيتم قبولها لأنها داخل علامات الاقتباس. مثال: a=23، ثم echo "$a" سيولد $a على الإخراج القياسي. بينما سينتج الصدى "$a" 23 عند الإخراج القياسي.

نظرًا لطبيعة عملي، يتعين علي إجراء عمليات تدقيق أمنية للكود المصدري لتطبيقات الويب.
الكثير من تطبيقات الويب والكثير من الأكواد...

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

لذلك، دعونا نبدأ.

الهروب شخصية عديمة الفائدة
يوجد في 83% من تطبيقات الويب PHP المعرضة لحقن SQL
استخدام وظيفة الهروب لأحرف مثل
mysql_escape_string
mysql_real_escape_string
com.adslashes
بدون علامات الاقتباس. غالبًا ما يتجلى في المعلمات الرقمية (جميع أنواع *_id).
مثال
$sql = "اختر المستخدم من قائمة المستخدمين حيث userid=".mysql_real_escape_string($_GET["uid"]);

يبدو أن هذا رمز آمن، ولكن على السطح فقط. النمط الأكثر شيوعًا لحقن SQL في PHP في ممارستي تسلل هنا. لمهاجمة هذه الثغرة الأمنية، يحتاج المهاجم ببساطة إلى تجنب استخدام الأحرف " " \x00 \r \n \x1a في ناقل الهجوم.
على سبيل المثال:
/index.php?uid=-777 UNION SELECT كلمة المرور من قائمة المستخدمين

البحث في الكود
معقدة بسبب دلالات اللغة. لإجراء بحث بسيط يمكنك استخدام egrep:
egrep -Rin "(select|update|insert|delete|replace).*(from|set|into).*(mysql_escape_string|mysql_real_escape_string|addslashes)" . | grep -v "[\""]["\"]"

منطق تعبير البحث هو كما يلي: ابحث عن جميع الأسطر التي لا يوجد فيها تسلسل لأحرف الاقتباس (""، ""، ""، "") على يسار وظائف التصفية. الطريقة بالطبع بعيدة كل البعد عن 100٪، لكن من المستحيل طلب تعبير عادي لإجراء التحليل الدلالي.
لتسهيل عرض المعلومات، يمكنك تمييز الوظيفة بالألوان في وحدة التحكم:
egrep -Rin "(select|update|insert|delete|replace).*(from|set|into).*(mysql_escape_string|mysql_real_escape_string|addslashes)" . | grep -v "[\""]["\"]" | egrep --color "(mysql_escape_string|mysql_real_escape_string|addslashes)"

للحماية من ثغرة البدل هذه، من الأفضل استخدام نوع النوع.
يعمل هذا دائمًا بشكل أسرع وأكثر موثوقية من جميع أنواع التصفية والفحص.
في المثال أعلاه، يمكن أن يكون التصحيح كما يلي:
$sql = "اختر المستخدم من قائمة المستخدمين حيث userid=".intval($_GET["uid"]);

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

(PHP 4 >= 4.3.0، PHP 5)

mysql_real_escape_string — يهرب من الأحرف الخاصة في سلسلة لاستخدامها في عبارة SQL

وصف

mysql_real_escape_string (سلسلة $unescaped_string [, المورد $link_identifier = NULL]): خيط

يفلت من الأحرف الخاصة في unscaped_string، مع الأخذ في الاعتبار مجموعة الأحرف الحالية للاتصال بحيث يكون من الآمن وضعها في mysql_query(). إذا كان سيتم إدراج البيانات الثنائية، فيجب استخدام هذه الوظيفة.

mysql_real_escape_string() تستدعي وظيفة مكتبة MySQL mysql_real_escape_string، والتي تسبق الخطوط المائلة العكسية للأحرف التالية: \x00, , \ ص, \ , " , " و \x1a.

يجب دائمًا استخدام هذه الوظيفة (مع بعض الاستثناءات) لجعل البيانات آمنة قبل إرسال استعلام إلى MySQL.

حذر

الأمان: مجموعة الأحرف الافتراضية

يجب تعيين مجموعة الأحرف إما على مستوى الخادم، أو باستخدام وظيفة API mysql_set_charset()لكي يؤثر mysql_real_escape_string() . راجع قسم المفاهيم في مجموعات الأحرف لمزيد من المعلومات.

حدود

unscaped_string

السلسلة التي يجب الهروب منها.

Link_identifier

اتصال MySQL. إذا لم يتم تحديد معرف الرابط، فسيتم فتح الرابط الأخير بواسطة mysql_connect()يفترض. إذا لم يتم العثور على مثل هذا الارتباط، فسيحاول إنشاء واحد كما لو كان mysql_connect()تم استدعاؤه بدون أي حجج. إذا لم يتم العثور على اتصال أو تأسيسه، فإن تحذير إلكترونييتم إنشاء خطأ في المستوى.

إرجاع القيم

إرجاع السلسلة التي تم الهروب منها، أو خطأ شنيععلى خطأ.

الأخطاء/الاستثناءات

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

أمثلة

المثال رقم 1 بسيط mysql_real_escape_string() مثال

//يتصل
$link = mysql_connect("mysql_host" , "mysql_user" , "mysql_password" )
أو يموت (mysql_error());

//استفسار
استعلام $ = sprintf ( "اختر * من المستخدمين حيث المستخدم = "%s" وكلمة المرور = "%s"",
mysql_real_escape_string($المستخدم)،
mysql_real_escape_string($password));
?>

مثال رقم 2 mysql_real_escape_string() يتطلب مثال اتصال

يوضح هذا المثال ما يحدث في حالة عدم وجود اتصال MySQL عند استدعاء هذه الوظيفة.

المثال أعلاه سيخرج شيئًا مشابهًا لما يلي:

تحذير: mysql_real_escape_string(): لا يوجد مثل هذا الملف أو الدليل في /this/test/script.php في السطر 5 تحذير: mysql_real_escape_string(): لا يمكن إنشاء رابط إلى الخادم في /this/test/script.php في السطر 5 bool(false) string(41) "اختر * من الممثلين حيث الاسم الأخير = """

المثال رقم 3: مثال على هجوم حقن SQL

// لم نتحقق من $_POST["password"]، فقد يكون أي شيء يريده المستخدم، على سبيل المثال:
$_POST [ "اسم المستخدم" ] = "إيدان" ;
$_POST [ "كلمة المرور" ] = "" OR ""="" ;

// الاستعلام عن قاعدة البيانات للتحقق مما إذا كان هناك أي مستخدمين متطابقين
$query = ( $_POST [ "اسم المستخدم" ]) " وكلمة المرور =" ( $_POST [ "كلمة المرور" ]) "" ;
mysql_query($query);

// هذا يعني أن الاستعلام المُرسل إلى MySQL سيكون:
صدى الاستعلام $؛
?>

تم إرسال الاستعلام إلى MySQL:

سيسمح هذا لأي شخص بتسجيل الدخول بدون كلمة مرور صالحة.

ملحوظات

مطلوب اتصال MySQL قبل الاستخدام mysql_real_escape_string() وإلا خطأ في المستوى تحذير إلكترونييتم إنشاء، و خطأ شنيعيتم إرجاع. إذا لم يتم تعريف link_identifier، فسيتم استخدام آخر اتصال MySQL.

ملحوظة: mysql_real_escape_string() لا يهرب % و _ . هذه هي أحرف البدل في MySQL إذا تم دمجها مع يحب, منحة، أو سحب او إبطال.

قبل 8 سنوات

مجرد وظيفة صغيرة تحاكي mysql_real_escape_string الأصلية ولكنها لا تحتاج إلى اتصال mysql نشط يمكن تنفيذها كوظيفة ثابتة في فئة قاعدة البيانات.

الدالة mysql_escape_mimic ($inp) (
إذا (is_array($inp))
إرجاع array_map (__METHOD__ , $inp );

إذا(!فارغ($inp ) && is_string ($inp )) (
إرجاع str_replace (array("\\" , "\0" , "\n" , "\r" , """ , """ , "\x1a" ), array("\\\\" , "\ \0" , "\\n" , "\\r" , "\\"" , "\\"" , "\\Z" ), $inp );
}

إرجاع $inp ;
}
?>

منذ 13 عاما

لاحظ أن mysql_real_escape_string لا يقوم بإضافة خطوط مائلة عكسية إلى \x00 و\n و\r و\x1a كما هو مذكور في الوثائق، ولكنه في الواقع يستبدل الحرف بتمثيل MySQL مقبول للاستعلامات (على سبيل المثال، \n يتم استبداله بـ "\ n"literal). (\، "، و" تم تهريبها كما هو موثق) هذا لا يغير الطريقة التي يجب أن تستخدم بها هذه الوظيفة، ولكن أعتقد أنه من الجيد معرفة ذلك.

منذ 6 سنوات

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

لذا، بدلاً من استخدام هذه الوظيفة المعطلة بشكل رهيب، استخدم البيانات البارامترية المعدة بدلاً من ذلك.

بصراحة، يجب اعتبار استخدام البيانات المقدمة من المستخدم لإنشاء عبارات SQL إهمالًا مهنيًا ويجب أن تتحمل المسؤولية من قبل صاحب العمل أو العميل لعدم استخدام البيانات المُعدة معلميًا.

ماذا يعني ذالك؟

وهذا يعني بدلاً من إنشاء عبارة SQL مثل هذا:

"INSERT INTO X (A) VALUES(".$_POST["a"].)"

يجب عليك استخدام دالة التحضير () الخاصة بـ mysqli لتنفيذ عبارة تبدو كما يلي:

"أدخل في قيم X (A) (؟)"

ملحوظة: هذا لا يعني أنه لا ينبغي عليك أبدًا إنشاء عبارات SQL ديناميكية. ما يعنيه هو أنه لا يجب عليك أبدًا استخدام البيانات المقدمة من المستخدم لإنشاء تلك البيانات. يجب تمرير أي بيانات مقدمة من المستخدم كمعلمات إلى العبارة بعد أن يتم تم إعدادها.

لذا، على سبيل المثال، إذا كنت تقوم بإنشاء إطار عمل صغير وتريد إجراء إدراج في جدول بناءً على معرف URI للطلب، فمن مصلحتك ألا تأخذ قيمة $_SERVER["REQUEST_URI"] (أو أي قيمة أخرى) جزء منه) وتسلسل ذلك مباشرةً مع استعلامك بدلاً من ذلك، يجب عليك تحليل جزء قيمة $_SERVER["REQUEST_URI"] الذي تريده، وتعيين ذلك من خلال نوع ما من الوظائف أو المصفوفة الترابطية إلى شخص غير مستخدم. القيمة المقدمة إذا لم ينتج التعيين أي قيمة، فأنت تعلم أن هناك خطأ ما في البيانات المقدمة من المستخدم.

لقد كان الفشل في اتباع ذلك سببًا لعدد من مشكلات حقن SQL في إطار عمل Ruby On Rails، على الرغم من أنه يستخدم عبارات معدة بارامترية. هذه هي الطريقة التي تم بها اختراق GitHub في وقت ما. لذلك، لا توجد لغة محصنة ضد هذه المشكلة. لهذا السبب تعد هذه أفضل الممارسات العامة وليست شيئًا خاصًا بـ PHP ولماذا يجب عليك اعتمادها حقًا.

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

منذ 9 سنوات

هناك ميزة مثيرة للاهتمام في المثال رقم 2 حول إدخال SQL: AND لها الأولوية على OR، لذلك يتم تنفيذ الاستعلام الذي تم إدخاله فعليًا كـ WHERE (user="aidan" AND كلمة المرور = "") أو ""=""، لذا بدلاً من ذلك من خلال إرجاع سجل قاعدة بيانات يتوافق مع اسم مستخدم عشوائي (في هذه الحالة "aidan")، فإنه سيُرجع في الواقع جميع سجلات قاعدة البيانات بدون ترتيب معين، لذلك قد يتمكن المهاجم من تسجيل الدخول بأي حساب، ولكن ليس بالضرورة باستخدام أي حساب السيطرة على الحساب الذي هو عليه.

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

// على سبيل المثال قيم المهاجم
$_POST [ "اسم المستخدم" ] = "" ؛
$_POST["كلمة المرور"] = "" أو المستخدم = "المسؤول" و "" = "";

// استعلام تالف
استعلام $ = "اختر * من المستخدمين حيث المستخدم ="$_POST [ اسم المستخدم ] " وكلمة المرور =" $_POST [ كلمة المرور ] "" ;

صدى الاستعلام $؛

// سيكون الاستعلام المرسل إلى MySQL كما يلي:
// SELECT * من المستخدمين حيث المستخدم = "" وكلمة المرور = "" أو المستخدم = "المسؤول" و "" ="؛
// والذي سيسمح لأي شخص بالوصول إلى الحساب المسمى "المسؤول"

?>

منذ سنة 1

@feedr
وشرحت مذكرته على النحو التالي:
$string = "asda\0sd\x1aas\\\\\\\\dasd\"asdasd\na\"\"sdasdad";
$array1 = array("\\\\\\\\"، "\0"، "\n"، "\r"، """، """، "\x1a");
$array2 = array("\\\\\\\\\\\\\\\\"، "\\\0"، "\\\n"، "\\\r"، "\\\ " "، "\\\"، "\\\Z")؛
صدى($سلسلة);
صدى (PHP_EOL)؛
ل($i=0; $i إذا (ط == 0)
$p = "/(؟آخر
$p = "/(؟صدى($i);
صدى($p);
صدى($array2[$i]);
$string = preg_replace($p, $array2[$i], $string);
صدى("\t");
صدى($سلسلة);
صدى (PHP_EOL)؛
}
صدى (PHP_EOL)؛
صدى($سلسلة);

منذ عامين

على حد تعبير سام في Numb Safari

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

لذا، بدلاً من استخدام هذه الوظيفة المعطلة بشكل رهيب، استخدم البيانات البارامترية المعدة بدلاً من ذلك.

بصراحة، استخدام البيانات المقدمة من المستخدم لإنشاء عبارات SQL يجب أن يعتبر إهمالًا مهنيًا ويجب أن تتحمل المسؤولية من قبل صاحب العمل أو العميل لعدم استخدام البيانات المعلمية المعدة.

سام عنده حق........

ومع ذلك، لا أعتقد أنه من المعقول إيقاف كل عمليات التعقيم ونقل المهمة ببساطة إلى البيانات البارامترية المعدة.

سيعرف مطور معين يعمل في موقف معين دائمًا المزيد عن المدخلات الصالحة (خاصة بهذا السياق).

إذا طلبت من المستخدم تمرير قيمة أعطيتها له بالفعل وأنت تعلم أن كل هذه القيم تبدأ بـ AB****** ويجب أن يكون طول السلسلة 7 أو 11 ولكن ليس بأي طول آخر، فهذا يعني أن لديك أساس المطهر المسبق الجيد - قد تشير الأطوال المسموح بها المختلفة للسلسلة إلى بيانات قديمة.

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

بهذه الطريقة لا يتم انسداد قاعدة البيانات الخاصة بي ببيانات غير آمنة أصبحت آمنة - فهي ببساطة لا يتم انسدادها وهو الأفضل.

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

بالإضافة إلى ما أستطيع أن أقرأه في الوثيقة الرسمية
==============================================

"الهروب وحقن SQL

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

وهذا يوحي لي أنه يتم تجنب الخطر في الأجزاء الداخلية من خلال المعالجة البديلة وليس عن طريق الإبطال.

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

وطالما تم تنفيذ عملية التعقيم بكفاءة دون التعرض لمخاطر إضافية، فإنني شخصيًا سألتزم بطبقات معينة من عمليات التعقيم ثم أستدعي البيانات المعدة.