php $_post - ما الخطأ في استخدام $ _REQUEST[]؟




شرح form (13)

$_REQUEST ضارًا للسبب نفسه الذي غالبًا ما يتم تنفيذ تحويلات البيانات ذات التعقيد البسيط إلى المتوسط ​​في شفرة التطبيق بدلاً من الإعلان عنها في SQL: يمتص بعض المبرمجين.

على هذا النحو ، إذا كان أحد يميل إلى استخدام $_REQUEST كل مكان ، يمكنني القيام بأي شيء عبر GET يمكنني الوصول إليه عبر POST ، مما يعني إعداد علامات <img> على موقعي (الخبيث) الذي يسبب تسجيل دخول المستخدمين إلى وحدة التجارة الإلكترونية الخاصة بك للشراء في صمت ، أو يمكنني جعلهم ينقرون على الروابط التي تؤدي إلى أعمال خطيرة أو الكشف عن معلومات حساسة (ربما بالنسبة لي).

ومع ذلك ، فإن هذا يرجع إلى وجود مبرمج ، أو على الأقل خبرة ، مبرمج PHP الذي يرتكب أخطاء بسيطة. أولاً ، تعرف متى تكون البيانات من النوع المناسب. على سبيل المثال ، لدي خدمة ويب يمكنها إرجاع الردود في URLEncoding أو XML أو JSON. يقرر التطبيق كيفية تنسيق الاستجابة عن طريق التحقق من رأس HTTP_ACCEPT ، ولكن يمكن إجراؤها في أحدها بشكل محدد عن طريق إرسال معلمة format .

عند التحقق من محتوى معلمة التنسيق ، يمكن إرسالها عبر querystring أو postdata ، اعتمادًا على العديد من العوامل ، وليس أقلها ما إذا كانت تطبيقات الاستدعاء تريد "& format = json" مختلطة مع طلبها. في هذه الحالة ، يكون $_REQUEST مناسبًا جدًا لأنه يوفر لي الحاجة إلى كتابة شيء كالتالي:

$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);

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

كيفية استخدام $_REQUEST بأمان

  1. اعرف بياناتك : يجب أن يكون لديك بعض التوقعات فيما يتعلق بنوع البيانات التي ستحصل عليها ، لذلك قم بتعقيمها وفقًا لذلك. البيانات لقاعدة البيانات؟ addslashes() أو *_escape_string() . ذاهب لإظهار مرة أخرى إلى المستخدم؟ htmlspecialchars() أو htmlspecialchars() . نتوقع البيانات الرقمية؟ is_numeric() أو ctype_digit() . في الواقع ، تم filter_input() ووظائفه ذات الصلة لفعل أي شيء ما عدا فحص وتعقيم البيانات. استخدم هذه الأدوات دائمًا.
  2. لا تدخل بيانات superglobals التي قدمها المستخدم مباشرة . اعتاد على تعقيم بياناتك ، في كل مرة ، ونقل بياناتك لتنظيف المتغيرات ، حتى لو كانت مجرد $post_clean . بدلا من ذلك ، يمكنك فقط تنظيف مباشرة في superglobals ، ولكن السبب في الدعوة إلى استخدام متغير منفصل هو أن ذلك يجعل من السهل تحديد نقاط الضعف في التعليمات البرمجية ، حيث أن أي شيء يشير مباشرة إلى superglobal وليس مكافئ المعقم يعتبر خطأ خطير .
  3. اعرف من أين تأتي البيانات. بالإشارة إلى المثال الخاص بي من أعلاه ، من المعقول تماماً السماح بإرسال متغير تنسيق الاستجابة عبر GET أو POST. أسمح أيضًا بإرسال متغير "الإجراء" عبر أي من الطريقتين. ومع ذلك ، تحتوي الإجراءات نفسها على متطلبات محددة جدًا فيما يتعلق بـ "فعل HTTP" . وظائف ، على سبيل المثال ، التي تجعل التغييرات على البيانات المستخدمة من قبل الخدمة قد يتم إرسالها فقط عبر POST. قد يتم تقديم طلبات لأنواع معينة من البيانات غير ذات الامتيازات المنخفضة (مثل صور الخرائط التي تم إنشاؤها ديناميكيًا) استجابةً للطلبات الواردة من أي من الطريقتين.

في الختام ، تذكر هذه القاعدة البسيطة:

الأمن هو ما تفعله ، الناس!

تصحيح:

أوصي بشدة نصيحة bobince: إذا كنت تستطيع ، قم بتعيين المعلمة request_order في php.ini إلى "GP" ؛ أي ، لا يوجد مكون ملفات تعريف الارتباط. لا يوجد أي منطق منطقي تقريبًا لهذا في 98٪ من الحالات ، حيث أن بيانات ملفات تعريف الارتباط يجب عدم اعتبارها تقريبًا تقريبًا إلى سلسلة البحث أو في postdata.

PS ، حكاية!

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

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


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

أيضا ، إذا نظرت إلى العديد من اللغات الأخرى (ASP.NET على سبيل المثال) فإنها لا تميز بين المتغيرات GET و POST على الإطلاق.

ايتا :

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

أيضا ، يتم التحكم في الترتيب الذي يتم فيه تحميل المواد في REQUEST بواسطة معلمات التكوين في php.ini (variables_order و request_order). لذا ، إذا كان لديك نفس المتغير الذي تم تمريره عبر كل من POST و GET ، أي واحد يحصل بالفعل على REQUEST يعتمد على تلك الإعدادات الداخلية. قد يؤثر ذلك على قابلية النقل إذا كنت تعتمد على طلب معين وتم تكوين هذه الإعدادات بشكل مختلف عما تتوقعه.


لقد كنت أحفر من خلال بعض منشورات مجموعة الأخبار على PHP Internals وعثرت على مناقشة شيقة حول الموضوع. كان الخيط الأولي يتعلق بشيء آخر ، إلا أن ملاحظة ستيفان إيسر ، الخبير الأمني ​​(إن لم يكن) في عالم PHP ، حولت النقاش إلى الآثار الأمنية لاستخدام $ _REQUEST لبضع مشاركات.

نقلا عن ستيفان ايسر على PHP Internals

تعتبر $ _REQUEST واحدة من أكبر نقاط الضعف في التصميم في PHP. كل تطبيق يستخدم $ _REQUEST هو على الأرجح عرضة لمشاكل Delayed Cross Site Request Forgery. (وهذا يعني في الأساس أنه إذا كان هناك مثلاً ملف تعريف ارتباط اسمه (العمر) ، فستقوم دائمًا بالكتابة فوق محتوى GET / POST ، وبالتالي سيتم تنفيذ الطلبات غير المرغوب فيها)

وفي رد لاحق على نفس الموضوع

الأمر لا يتعلق بحقيقة أن شخصًا ما يمكنه صياغة GET أو POST ؛ متغيرات COOKIE. يتعلق الأمر بحقيقة أن COOKIE ستحل محل بيانات GET و POST في REQUEST.

لذلك ، يمكن أن أصاب المتصفح باستخدام ملف تعريف الارتباط الذي يقول على سبيل المثال الإجراء = الخروج ومن ذلك اليوم لا يمكنك استخدام التطبيق بعد الآن لأن REQUEST [action] سيكون الخروج إلى الأبد (حتى تحذف ملف تعريف الارتباط يدويًا).

وتصيبك مع COOKIE هو في غاية البساطة ...
أ) يمكنني استخدام XSS في أي تطبيق على نطاق فرعي
ب) حاول إعداد ملف تعريف ارتباط لـ * .co.uk أو * .co.kr عندما تمتلك نطاقًا واحدًا هناك؟
ج) عبر المجالات الأخرى أيا كانت ...

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

وعن طريق تعيين معرف جلسة غير قانوني في ملف تعريف ارتباط صالح لـ * .co.kr في متغير يسمى + PHPSESSID = غير قانوني ، يمكنك الاستمرار في تطبيق DOS PHP في كوريا باستخدام جلسات PHP ...

تستمر المناقشة لبضع مشاركات أكثر ومثيرة للاهتمام للقراءة.

كما ترى ، لا تكمن المشكلة الرئيسية في $ _REQUEST في أنه يحتوي على بيانات من $ _GET و $ _POST ، ولكن أيضًا من $ _COOKIE. اقترح بعض الأشخاص الآخرين في القائمة تغيير الترتيب الذي يتم به ملء $ _REQUEST ، على سبيل المثال ملئه بـ $ _COOKIE أولاً ، ولكن قد يؤدي ذلك إلى العديد من المشكلات المحتملة الأخرى ، على سبيل المثال مع معالجة الجلسة .

يمكنك حذف $ _COOKIES $ من _REQUEST عالمي على الرغم من ذلك ، بحيث لا يتم الكتابة فوقها بواسطة أي من المصفوفات الأخرى (في الواقع ، يمكنك تحديدها لأي مجموعة من محتوياتها القياسية ، مثل دليل PHP في الإعداد ini variable_order أخبرنا:

variable_order تعيين ترتيب التحليل المتغير EGPCS (بيئة ، إحضار ، نشر ، ملفات تعريف الارتباط ، والخادم). على سبيل المثال ، إذا تم تعيين variables_order على "SP" ، فسيؤدي PHP إلى إنشاء superglobals $ _SERVER و $ _POST ، ولكن لن ينشئ $ _ENV و $ _GET و $ _COOKIE. الإعداد إلى "" يعني عدم تعيين superglobals.

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

الآن قد تتساءل ، لماذا يوجد $ _REQUEST بعد كل شيء ولماذا لم تتم إزالته. وقد سئل هذا على PHP Internals كذلك. نقلا عن Rasmus Lerdorf حول سبب وجود $ _REQUEST؟ على PHP Internals

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

على أي حال ، نأمل أن تسليط بعض الضوء.


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

أشار شخص آخر أيضًا إلى أنك لا تريد أن يتم تجاوز جميع ملفات POST أو ملفات تعريف الارتباط بواسطة GET لأن هناك قواعد مختلفة للمواقع المشتركة لجميعهم ، على سبيل المثال ، إذا رجعت بيانات ajax أثناء استخدام $ _REQUEST ، فأنت عرضة إلى هجوم البرنامج النصي عبر الموقع.


Darren Cook: "منذ php 5.3 ، يشير php.ini الافتراضي إلى أن بيانات GET و POST فقط يتم وضعها في $_REQUEST . انظر php.net/request_order لقد تعثرت للتو في هذا التوافق مع الإصدارات السابقة عندما تتوقع أن تكون بيانات ملفات تعريف الارتباط في $_REQUEST لماذا لم تكن تعمل! "

واو ... لقد توقفت بعض النصوص الخاصة بي عن العمل بسبب الترقية إلى PHP 5.3 . فعل الشيء نفسه: افترض أنه سيتم تعيين ملفات تعريف الارتباط عند استخدام المتغير $_REQUEST . مع الترقية بالضبط توقفت عن العمل.

أدعو الآن قيم ملفات تعريف الارتباط بشكل منفصل باستخدام $_COOKIE["Cookie_name"] ...


قد يتم استخدامي فقط إذا كنت تريد استرداد عنوان url أو اسم المضيف الحالي ، ولكن لتحليل البيانات فعليًا من عنوان URL هذا ، مثل parmeters باستخدام الرمز & ، ربما لا تكون فكرة جيدة. بشكل عام ، لا تريد استخدام وصف مبهم لما تحاول القيام به. إذا كنت بحاجة إلى أن تكون محددًا حيث $ _REQUEST سيئ ، إذا لم تكن بحاجة إلى أن تكون محددًا ، فلا تتردد في استخدامه. انا افكر.


المرة الوحيدة التي تستخدم $_REQUEST ليست فكرة سيئة هي GET.

  • إذا كنت تستخدمه لتحميل قيم POST ، فأنت تخاطر بتزوير طلبات عبر المواقع
  • إذا كنت تستخدمه لتحميل قيم ملفات تعريف الارتباط ، فستخاطر مجددًا بتزوير طلبات عبر الموقع

وحتى مع GET ، يكون $_REQUEST أقصر في الكتابة من $_REQUEST ؛)


يجب أن تكون طلبات GET غير ثابتة وأن طلبات POST ليست عامة. وهذا يعني أنه يجب استخدام البيانات في $_GET و $_POST بطرق مختلفة.

إذا كان تطبيقك يستخدم بيانات من $_REQUEST ، فسوف يتصرف بنفس الطريقة لكل من طلبات GET و POST ، التي تنتهك مفهوم GET.


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


تشير $_REQUEST إلى كافة أنواع الطلبات (GET و POST وما إلى ذلك). هذا مفيد في بعض الأحيان ، ولكن عادة ما يكون من الأفضل تحديد الطريقة الصحيحة ($ _GET ، $ _POST الخ).


أعتقد أنه لا توجد مشكلة في $_REQUEST ، ولكن يجب أن نكون حذرين عند استخدامه لأنه مجموعة من المتغيرات من 3 مصادر (GPC).

أعتقد أن $_REQUEST ما زال متاحًا لجعل البرامج القديمة متوافقة مع إصدارات php الجديدة ، ولكن إذا بدأنا مشاريع جديدة (بما في ذلك المكتبات الجديدة) أعتقد أنه لا ينبغي لنا استخدام $_REQUEST بعد الآن لجعل البرامج أكثر وضوحًا. يجب علينا حتى التفكير في حذف استخدام $_REQUEST واستبداله بوظيفة ملحقة لجعل البرنامج أخف ، خاصة في معالجة البيانات النصية الكبيرة المقدمة ، حيث يحتوي $_REQUEST على نسخ من $_POST .

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}

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


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

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

PHP هي لغة براغماتية. لقد تم إنشاؤه من حاجة محددة لتكون قادرة على إنشاء صفحات ويب بسرعة (الاسم كان في الأصل لصفحة Home Pages) وتم تمديد اللغة حسب الحاجة. نظرًا لعدم وجود خلفية نظرية أو مبادئ تصميمية قوية تؤدي إلى إنشائها (لا توجد حتى مواصفة رسمية للغة) فهي أقل نظافة من العديد من اللغات الحديثة الأخرى. ومن الواضح أن ميزات مثل المعالجة الصحيحة للأحرف الأجنبية / أحرف unicode تضاف بعد ذلك ولا تتكامل بشكل صحيح مع بقية اللغة. هذا عدم الترتيب وعدم الدقة النظرية يجعل الكثير من الناس (وخاصة الأكاديميين) يكرهون اللغة وهذا قد يكون جزءًا من السبب الذي يجعل معلمك لا يعتبر PHP كلغة "حقيقية".

على الرغم من أن PHP جيد في ما صُمم من أجله ، وتستخدمه العديد من المواقع ، حتى المواقع الكبيرة جدًا مثل Facebook و Yahoo! و ويكيبيديا.





php methods form-submit