الدليل النهائي لـ XSS

دليل لهجمات البرمجة عبر المواقع. كيف يعملون؟ كيف يمكنك منعهم؟

ما هو XSS ، المعروف أيضًا باسم Cross Site Scripting؟

XSS هو المصطلح الذي نستخدمه لتحديد نوع معين من الهجوم حيث يمكن استخدام موقع الويب (موقع الويب الخاص بك ، إذا لم تنتبه) كمتجه لمهاجمة مستخدميه ، بسبب التسليم غير الآمن لمدخلات المستخدم.

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

باستخدام هذه الثغرة الأمنية ، يمكنهم سرقة معلومات المستخدم.

بناءً على كيفية استغلال ثغرة XSS ، لدينا 3 أنواع رئيسية من هجمات XSS:

  • XSS المستمر
  • ينعكس XSS
  • XSS القائمة على DOM

لماذا XSS خطير؟

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

هذا خطير جدا.

نظرًا لإهمالك في إصلاح ثغرة XSS ، يمكن استخدام موقعك كناقل للهجوم وتكون معلومات المستخدمين لديك في خطر.

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

هل XSS مشكلة في الواجهة الأمامية أو الخلفية؟

انه الاثنين. إنها مشكلة معمارية لموقع الويب تتضمن كل من الواجهة الأمامية والخلفية.

مثال على هجوم XSS

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

لنفترض أن لديك مدونة ، وأنك تسمح للمستخدمين بالتعليق في المدونة. إذا قبلت بشكل أعمى أي محتوى يدخله المستخدمون ، فيمكن لمستخدم ضار محاولة إدخال مقتطف JavaScript ، في أبسط أشكاله المضمنة في<script></script>. على سبيل المثال<script>alert('test')</script>.

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

لقد استخدمت ملفalert()لتقديم مثال ، ولكن كما هو مذكور أعلاه ، يمكن للمستخدم إدخال أي نوع من البرامج النصية. في هذه المرحلة ، تم اختراق الموقع.

ما هو استمرار XSS؟

XSS المستمر هو أحد الأنواع الثلاثة من XSS التي نجدها في البرية. إنها تلك التي وصفتها أعلاه في مثال منشور المدونة.

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

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

ما هو انعكاس XSS؟

XSS المنعكس هو وسيلة لاستغلال ثغرة أمنية في موقعك على الفور من خلال تزويد المستخدم النهائي برابط يحتوي على نص بداخله.

بهذه الطريقة ، يوفر المهاجم ارتباطًا مشابهًا لـ

yoursite.com/?example=<script>alert('test')</script>

If your site uses the example GET variable to perform something and display it on the page, and you don’t check and sanitize its value, now that script will be executed by the user’s browser.

A typical example is a search form. It might live in the /search URL and you might accept the search term using the GET term variable.

You might display the You searched for <term> string when someone searches for it. Now, if you didn’t sanitize the value, you now have a problem.

Spam/phishing emails are a common medium for this XSS attack. Of course, the bigger and more important the site, the more frequently hackers will try to hack it.

What is DOM-based XSS?

With persistent XSS, the attacking code must be sent to the server, where it can be (and hopefully it is) sanitized. With reflected XSS, the same is true.

DOM-based XSS is a kind of XSS where the malicious code is never sent to the server. It’s common for this to happen by using the fragment part of a URL, or by referencing document.URL/document.location.href. Some examples you find online don’t really work any more because modern browsers automatically escape JS in the address bar for us. They only work if you unescape it, which is kind of scary (don’t do it!).

Here’s a simple working example. Say you have a page listening on http://127.0.0.1:8081/testxss.html. Your client-side JavaScript looks at the test variable passed in the fragment part of the URL:

http://127.0.0.1:8081/testxss.html#test=something

The #test=something value is never send to the server. It’s only local. Persistent/reflected XSS would not work. But say your script accesses that value using:

const pos = document.URL.indexOf("test=") + 5;
const value = document.URL.substring(document.URL.indexOf("test=") + 5, document.URL.length)

and you write it directly into the DOM:

document.write(value)

All is fine, until someone calls the URL like this:

http://127.0.0.1:8081/testxss.html#test=

Now, thanks to the automatic escaping that happens by referencing document.URL nothing should happen in this specific case.

You’d get

%3Cscript%3Ealert('x')%3C/script%3E

printed to the page. The value is escaped, so it’s not interpreted as HTML.

But if for some reason you unescape the document.URL value, you have a problem now, as the JavaScript is run. Any JS can be run on your users browsers.

On older browser, this was a much bigger problem, since they didn’t auto-escape JS put into the address bar.

Are static sites vulnerable to XSS?

Yes! Any kind of site, actually. Because being static does not mean there is no information loaded from other sources. For example you might roll your own form or comments, even without a database.

Or, we might have a search functionality that accepts input from an HTTP GET or POST variable. You are not immune just by not having a database.

How can we prevent XSS?

There are 3 techniques we can use:

  • encoding
  • validation
  • CSP

Encoding is done to escape the data. Doing so, the browser will not interpret the JavaScript because, for example, <script> will be encoded to %3Cscript%3E.

Encoding, as a general rule, should be always done.

Server-side frameworks commonly provide helper functions to provide this functionality to you.

In client-side JavaScript we use a different encoding mechanism depending on the use case.

If you need to add content to an HTML element, the best way is to assign the user-generated input to that element using the textContent property. The browser will do all the escaping for you:

document.querySelector('#myElement').textContent = theUserGeneratedInput

If you need to create an element use document.createTextNode():

const el = document.createTextNode(theUserGeneratedInput)

If you need to add content to an HTML attribute, use the setAttribute() method of the element:

document.querySelector('#myElement').setAttribute('attributeName', theUserGeneratedInput)

If you need to add content to the URL, use the window.encodeURIComponent() function:

window.location.href = window.location.href + '?test=' + window.encodeURIComponent(theUserGeneratedInput)

Validation is usually done when you cannot use escaping to filter the input. A common example is a CMS that lets the user define the content of the page in HTML. You can’t escape that.

You either use a blacklisting or whitelisting strategy for validation. The difference is that with blacklisting you decide which tags you want to disallow. With whitelisting you decide which tags you want to allow. Whitelisting is safer because blacklisting is prone to errors, complex and also not future-proof.

CSP means Content Security Policy. It’s a new standard implemented by browsers to enforce only executing JavaScript code coming from secure and trusted sources, and you can disallow running inline JavaScript in your code. The kind of JavaScript that allowed the above XSS exploits, for example.

CSP is enabled by the Web Server, by adding the Content‑Security‑Policy HTTP Header when serving the page.


More security tutorials: