كيف أقوم بترميز HTML لجميع المخرجات في تطبيق ويب؟

StackOverflow https://stackoverflow.com/questions/58694

  •  09-06-2019
  •  | 
  •  

سؤال

أريد منع هجمات XSS في تطبيق الويب الخاص بي.لقد وجدت أن ترميز HTML للمخرجات يمكن أن يمنع هجمات XSS حقًا.المشكلة الآن هي كيف يمكنني تشفير كل مخرجات HTML في تطبيقي؟هل هناك طريقة لأتمتة هذا؟

إنني أقدر الإجابات الخاصة بـ JSP وASP.net وPHP.

هل كانت مفيدة؟

المحلول

لا تريد تشفير كل HTML، بل تريد فقط ترميز HTML لأي إدخال مستخدم تقوم بإخراجه.

بالنسبة إلى لغة PHP: htmlentities و htmlspecialchars

نصائح أخرى

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

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

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

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

بالنسبة إلى JSPs، يمكنك الحصول على كعكتك وتناولها أيضًا، باستخدام العلامة c:out، التي تفلت من XML افتراضيًا.هذا يعني أنه يمكنك الارتباط بخصائصك كعناصر أولية:

<input name="someName.someProperty" value="<c:out value='${someName.someProperty}' />" />

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

إحدى الطرق اللطيفة التي استخدمتها للهروب من كل مدخلات المستخدم هي كتابة مُعدِّل لـ Smarty الذي يهرب من جميع المتغيرات التي تم تمريرها إلى القالب؛باستثناء تلك التي تم إرفاق |unescape بها.وبهذه الطريقة، فإنك تمنح HTML حق الوصول فقط إلى العناصر التي تمنحها حق الوصول إليها بشكل صريح.

لم يعد لدي هذا المعدل؛ولكن يمكن العثور على نفس الإصدار تقريبًا هنا:

http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html

في الإصدار الجديد من Django 1.0، يعمل هذا بنفس الطريقة تمامًا، جاي :)

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

في ASP.Net يتم ذلك باستخدام Server.HtmlEncode(string) .

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

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

echo "blah";

يستخدم

myecho('blah');

يمكنك أيضًا الحصول على معلمة ثانية تقوم بإيقاف الهروب إذا كنت في حاجة إليها.

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

إذا قمت بالفعل بتشفير HTML لكل مخرجات، فسيرى المستخدم نصًا عاديًا لـ <html>بدلاً من تطبيق ويب فعال.

يحرر:إذا قمت بتشفير كل إدخال بتنسيق HTML، فستواجه مشكلة في قبول كلمة المرور الخارجية التي تحتوي على < وما إلى ذلك.

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

PHP هي اللغة المفضلة لدي عندما يتعلق الأمر بتطوير الويب، لذا أعتذر عن التحيز في إجابتي.

كيران.

يمتلك OWASP واجهة برمجة تطبيقات لطيفة لتشفير مخرجات HTML، إما لاستخدامها كنص HTML (على سبيل المثال.فقرة أو <textarea> المحتوى) أو كقيمة للسمة (على سبيل المثال.ل <input> العلامات بعد رفض النموذج):

encodeForHTML($input) // Encode data for use in HTML using HTML entity encoding
encodeForHTMLAttribute($input) // Encode data for use in HTML attributes.

يتم استضافة المشروع (إصدار PHP) ضمن http://code.google.com/p/owasp-esapi-php/ ومتاح أيضًا لبعض اللغات الأخرى، على سبيل المثال..شبكة.

تذكر أنه يجب عليك التشفير كل شئ (ليس فقط إدخال المستخدم)، و في وقت متأخر ممكن (ليس عند التخزين في قاعدة البيانات ولكن عند إخراج استجابة HTTP).

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

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

Var dsFirstName, uhsFirstName : String;

Begin

uhsFirstName := request.queryfields.value['firstname'];

dsFirstName := dsHtmlToDB(uhsFirstName);

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top