برای جلوگیری از XSS یا Cross Site Scripting و مقابله با حملات تزریق کد چندین راهکار وجود دارد که در این مقاله به آن ها می پردازیم. نکاتی که اینجا بیان می کنیم می تواند در جلوگیری کردن از حمله XSS مفید باشد، همراه داتیس نتورک باشید.
همانطور که در مقاله “XSS چیست؟” گفتیم، این باگ نتیجه فیلتر نکردن ورودی/خروجی ها در سمت سرور است.
به ورودی/خروجیها اعتماد نکنید.
برای جلوگیری از حملات XSS به هیچ وجه به دادههای ورودی کاربران اعتماد نکید. حتی درصورتی که دادهها را فیلتر کنید، به هیچ وجه آنها را در قسمتهای زیر قرار ندهید:
باور کنید گذاشتن دادهها در این قسمتها اصلاً لازم نیست. بجای آن میتوانید از اعمال مقایساتی استفاده کرده سپس دادههای ثابت (نه ورودی کاربر) را قرار دهید.
هر چیزی که چاپ میکنید را فیلتر یا اسکیپ کنید.
قبل از نشان دادن یا چاپ کردن مقادیر ورودی کاربر (یا مقادیری که کاربر قبلاً ثبت کرده است)، حتماً آنها را Escape کنید. اسکیپ کردن دادههای HTML این امکان را فراهم میکند تا چیزی که قرار است چاپ شود، توسط مرورگر به عنوان کد HTML شناخته نشده و فقط به عنوان یک متن عادی نشان داده شود.
در این گونه موارد قبل از هر چیزی، کاراکتر اینکدینگ (Character Encoding) خود را مشخص کنید. معمولاً UTF-8 یا ISO-8859-1. این مورد بسیار مهم است زیرا بدون مشخص کردن اینکدینگ ممکن است اسکریپت ما مثلاً به XSS هایی تحت اینکدینگ UTF-7 آسیب پذیر باشند.
در ادامه، خروجیای که قرار است چاپ شود را فیلتر یا اسکیپ کنید.
نکته: حتی با انتخاب کاراکتر ست و فیلتر و اسکیپ کردن خروجی با استفاده از توابع زیر، به هیچ وجه ورودیهایی با اسکریپت خالص را نشان ندهید. در برخی از تگها و خواص آنها، امکان اجرا شدن آن اسکریپت وجود خواهد داشت. در این گونه موارد بهتر است از encodeForJavaScript کتابخانه ESAPI استفاده کنید.
در زبان ASPX:
در ASP.NET یا ASPX هم ابتدا کاراکتر ست را مشخص میکنیم:
<%@ Page RequestEncoding="utf-8" ResponseEncoding="utf-8" %>
سپس با استفاده از تابع خروجی را اسکیپ میکنیم:
safe_output = HttpUtility.HtmlEncode(untrusted_output); Response.Write(safe_output);
در زبان PHP:
ابتدا کاراکتر ست ای را که با آن کار میکنیم و قرار است مرورگر کاربر ما از آن استفاده کند را مشخص میکنیم:
header('Content-Type: text/plain; charset=utf-8');
حال با استفاده از توابع htmlspecialchars یا htmlentities خروجی خود را فیلتر کنید:
$safe_output = htmlentities($untrusted_output, ENT_QUOTES | ENT_HTML401, 'UTF-8'); echo "<div>$safe_output</div>";
مقادیر جاوا اسکریپت را هم فیلتر و اسکیپ کنید.
در جلوگیری از حملات XSS همانطور که گفته شد، فیلتر یا اسکیپ کردن جاوا اسکریپت با HTML متفاوت است و نباید از توابع بالا برای فیلتر کردن کدهای جاوا اسکریپت استفاده نمود. برای اسکیپ کردن مقادیر جاوا اسکریپت بهترین کار استفاده از تابع encodeForJavaScript در کتابخانه ESAPI استفاده کنید. با این حال، میتوانیم روشهای زیر را نیز به کار گیریم.
مثل قانون دوم، در همه جا ما کاراکتر ست را برای مرورگر کاربر تعریف میکنیم. برای کوتاه کردن کدها، این قسمت را دیگر نخواهیم نوشت.
در زبان ASPX:
<script type="text/javascript"> var safe_output = <%=HttpUtility.JavaScriptStringEncode(untrusted_output) %>; // این تابع امن است </script>
در زبان PHP:
مثلاً اگر لازم است جاوا اسکریپتی را که حاوی مقادیر غیرقابل اعتماد است را چاپ کنید، بهتر است از تابع json_encode که به صورت UTF-8 اینکد میکند، استفاده کنید:
<script type="text/javascript"> var unsafe_output = '<?= addslashes($untrusted_output) ?>'; // این تابع آسیب پذیر است var safe_output = <?= json_encode($untrusted_output) ?>; // این تابع امن است </script>
URLهای مشکوک را فیلتر کنید.
اگر در قسمتی از کدهای HTML خود هنگام ارسال به کاربران، آدرسی وجود داشت که توسط کاربری مشخص میشود، حتماً قبل از نشان دادن آن، فیلترش کنید.
در زبان ASPX:
safe_URL = HttpUtility.UrlEncode(untrusted_URL); Response.Write(safe_URL);
در زبان PHP:
$safe_URL = htmlspecialchars(urlencode($untrusted_URL)); echo '<a href="http://example.com/place/"' . $safe_URL . '">Click On Me</a>';
همیشه کاراکتر ست را مشخص کنید.
چه با PHP کار کنید و چه با ASPX و چه زبانهای دیگر، همیشه به یاد داشته باشید که مشخص کردن کاراکتر ست (معمولاً UTF-8) برای صفحات HTML هم در هدر پاسخ درخواست و هم در کدهای HTML بسیار مهم است.
از X-XSS-Protection استفاده کنید.
این یک هدر است که در پاسخ به درخواست مرورگر ارسال میشود. مرورگرهای مدرن قابلیتهای متعددی در مقابله با حملات XSS دارند که معمولاً به صورت پیشفرض فعال است. کار از محکم کاری عیب نمیکند، پس این هدر را به صورت فعال به مرورگر کاربر بفرستید.
HttpOnly کوکیها را فعال کنید.
با فعال کردن فلگ HttpOnly کوکیها فقط با درخواستهای HTTP ارسال خواهند شد و در این مسیر، حمله کننده با باگ XSS هم نخواهد توانست به کوکیهایی که با HttpOnly علامت گذاری شده اند دسترسی داشت.
اگر از iframe استفاده میکنید، آن را محدود کنید.
برخی از مرورگرها مانند اینترنت اکسپلورر با دادن مقدار restricted به خاصیت security در تگ iframe، صفحه آی-فرم را به صورت موقت در لیست صفحات منع شده قرار داده و به صورت پیشفرض، اسکریپتی از آن صفحه را اجرا نمیکند. این آپشن میتواند تا حدودی امنیت XSS از طریق iframe ها را تامین کند.
از Content Security Policy استفاده کنید.
این هدر که در پاسخ درخواست مرورگر ارسال میشود، به مرورگر لیست سفیدی (White List) از آدرسهایی که مرورگر اجازه دانلود منابعی مانند کدهای جاوا اسکریپت، استایل شیتها (CSS)، تصاویر و … را دارد، میدهد. بدین ترتیب جلوی بسیاری از XSS های مبتنی بر منابع خارجی گرفته میشود.
امیدواریم نکات ذکر شده در جلوگیری از حملات XSS به شما کمک کند.
منبع: