جلوگیری از حملات XSS

0010-preventing-xss-attacks-featured-image
تیر ۱۱, ۱۳۹۶

در دو پست گذشته وبلاگ حمله XSS یا تزریق کد چیست؟ و مثال‌هایی از حملات XSS به بررسی حملات تزریق کد XSS و چندین نمونه از آنها پرداختیم. در این پست به بررسی راه‌های جلوگیری از حملات XSS می‌پردازیم.

بطور کلی، همانند کلیه‌ی حمله‌های هک و نفوذ، هیچگونه راه حل ۱۰۰ درصدی برای جلوگیری از حملات XSS وجود ندارد. اما میتوان با در نظر گرفتن موارد عموما ساده، جلوی عمده‌ی روش‌های مورد استفاده توسط هکر‌ها برای نفوذ را گرفت. هر دو حمله Stored XSS و Reflected XSS را می‌توان با اعتبارسنجی (Validation)‌ و گریختن (Escaping) مناسب در سمت سرور (Server-Side) دفع کرد. برای دفع حملات DOM Based XSS از روش های دیگری باید استفاده کرد که در آینده و در پستی جداگانه به آن‌ها خواهیم پرداخت. در ادامه این روش‌ها را باهم بررسی خواهیم کرد.

جلوگیری از حملات XSS از نوع Stored XSS و Reflected XSS

در این پست ما با صفحه‌ی HTML همانند یک قالب رفتار می‌کنیم، که دارای شکاف‌های (Slots) مختلفی می‌باشد که توسعه‌دهنده در آنها اجازه قرار دادن داده‌های غیرقابل اعتماد (Untrusted) را دارد. این شکاف‌هایی که در ادامه بررسی می‌شود، شامل تمامی بخش‌هایی که توسعه‌دهنده اجازه قرار دادن داده‌های غیرقابل اعتماد را دارد می‌شود. در نتیجه امکان قرار دادن داده‌های غیرقابل اعتماد در بقیه‌ی کد HTML وجود ندارد. این مدل برخورد، یک مدل لیست سفید (Whitelist) می‌باشد، که هرچیز دیگری جز موارد اجازه داده شده را منع می‌کند.

داده‌ی غیر قابل اعتماد (Untrusted Data) چیست؟
داده‌ی غیر قابل اعتماد، داده‌ای می‌باشد که شما در طول فعالیت و خدمت‌دهی برنامه‌اتان، از سمت کاربر دریافت میکنید. بطور مثال دیدگاه در مورد یک پست، فیلد‌های فرم تماس با ما و…

با در نظر گرفتن نحوه‌ی رفتار مرورگر‌ها در پایش و نمایش HTML، هر کدام از شکاف‌ها نیاز به قوانین امنیتی متفاوتی دارند. در نتیجه، هنگامی که شما،‌ بعنوان توسعه‌دهنده می‌خواهید در هرکدام از این شکاف‌ها داده‌های غیرقابل اعتمادی را قرار بدهید، باید گام‌های مشخصی را طی کنید تا مطمعن شوید که داده‌های افزوده شده نمی‌توانند زمینه‌ی اجرای کد در شکاف را بدست بیاورند.

در این پست ما به بررسی شکاف‌های پر استفاده و عمومی و قوانین امنیتی هرکدام برای قرار دادن داده‌های غیرقابل اعتماد در آن می‌پردازیم. کلیه‌ی قوانین معرفی شده برای شکاف‌ها، نتیجه‌ی بررسی‌های متفاوت در مرورگر‌های محبوب برای جلوگیری از XSS می‌باشد. در نتیجه، اگر توسعه‌دهنده می‌خواهد در شکاف‌هایی غیر از موارد معرفی شده داده‌ غیرقابل اعتماد قرار دهد، می‌بایست بطور دقیق آنها را برای پیدا کردن قوانین امنیتی مناسب و با در نظر گرفتن مرورگر‌های متفاوت بررسی کند.

چرا داده‌های غیرقابل اعتماد را تنها HTML Entity Encode نکنیم؟

استفاده از HTML entity encoding برای داده‌های غیر‌قابل اعتمادی که در body صفحه‌ی HTML یا تگ div قرار می‌دهید، کافی می‌باشد. همچنین برای قرار دادن داده‌های غیر‌قابل اعتماد در خاصیت‌ (Attributes)های تگ‌های HTML با مطعن شدن از قرار گرفتن ' یا " در اطراف آن نیز مناسب می‌باشد. اما استفاده از HTML entity encoding برای قرار دادن داده غیرقابل اعتماد درون تگ <script>، خاصیت‌های مربوط به وقایع (Events) همچون onmouseover، درون CSS و یا آدرس (URL) کافی نمی‌باشد. در نتیجه اگر از HTML entity encoding برای تمامی موارد داده‌های غیرقابل اعتماد بخواهید استفاده کنید، متاسفانه هنوز در مقابل حملات تزریق کد آسیب‌پذیر خواهید بود. در نتیجه می‌بایست با توجه به شکافی که داده‌های غیرقابل اعتماد را در آن قرار می‌دهید از روش‌های مناسب Escaping استفاده کنید.

شما می‌بایست از یک کتابخانه Encoding امنیتی مناسب استفاده کنید.

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

قوانین مقابله با حملات XSS

قوانینی که در ادامه به معرفی آنها خواهیم پرداخت، برای جلوگیری از تمامی از تمام حملات XSS در برنامه تعیین شده‌اند. اگرچه این قوانین اجازه‌ی آزادی عمل کامل در قرار دادن داده‌های غیرقابل اعتماد در HTML را نمی‌دهند، اما بخش زیادی از موارد مورد نیاز را در بر می‌گیرند. نیاز نیست که شما تمامی قوانین را برای برنامه خود انجام دهید. ممکن است برنامه شما تنها به قوانین یک و سه نیاز داشته باشد.

نکته‌ی مهم!
هرگز تنها کاراکتر هایی که در مثال‌های قوانین در ادامه  مورد استفاده قرار گرفته‌اند Escape نکنید. Escape کردن تنها موارد موجود در مثال‌ها کافی نمی‌باشد. بعبارت دیگر استفاده از رویکرد لیست سیاه (Blacklist) کافی نمی‌باشد. بلکه رویکرد لیست سفیدی که در قوانین زیر مورد استفاده قرار گرفته با دقت تمام انتخاب شده اند تا برنامه‌ی شما را حتی در مقابل حفره‌ها و آسیب‌پذیری‌های که در آینده در نتیجه تغییرات در مرورگر‌ها بوجود می‌آید محافظت کند.

#۰) قانون شماره‌ی صفر: هرگز داده‌های غیرقابل اعتماد را بجز در مکان‌های اجازه داده شده قرار ندهید.

همه چیز را رد کنید! هرگز داده‌ی غیرقابل اعتمادی را در HTML خود قرار ندهید، مگر آنکه در یکی از شکاف‌های معرفی شده در قوانین ۱# تا ۵# باشد. دلیل وجود قانون ۰# این است که در HTML بخش‌های زیادی وجود دارد و معرفی قوانین Escaping برای تمامی بخش‌ها باعث ایجاد پیچیدگی بیش از حد می‌شود. اما اگر اصرار دارید تا در بخش دیگری جز موارد معرفی شد داده غیرقابل اعتماد قرار دهید، حتما آن بخش را بصورت کامل و در مرورگر‌های مختلف بررسی کنید و به سادگی از کنار آن نگذرید. هرگز در بخش‌های زیر داده‌ی غیر قابل اعتماد قرار ندهید.

<script>...NEVER PUT UNTRUSTED DATA HERE...</script> Directly in a script
<!--...NEVER PUT UNTRUSTED DATA HERE...--> Inside an HTML comment
<div ...NEVER PUT UNTRUSTED DATA HERE...=test /> In an attribute name
<NEVER PUT UNTRUSTED DATA HERE... href="/test" /> In a tag name
<style>...NEVER PUT UNTRUSTED DATA HERE...</style> Directly in CSS

نکته‌ی بسیار مهم!
هرگز کد جاوااسکریپت را از یک منبع غیرقابل اعتماد قبول و اجرا نکنید. برای مثال، یک پارامتر بنام callback که حاوی کد Javascript می‌باشد و در نهایت توسط شما اجرا می‌شود. هیچ مقدار از Escapingای نمی‌تواند این مشکل را رفع کند.

#۱) قانون شماره‌ی یک: قرار دادن داده‌های غیرقابل اعتماد در المان‌های محتوا (Content Element) و معمولی HTML

قانون شماره یک، برای مواقعی می‌باشد که داده‌ی غیرقابل اعتمادی را بصورت مستقیم در body سند HTMLاتان قرار می‌دهید. این قانون همچنین شامل دیگر تگ‌های معمولی HTML همچون div, p, b, td و غیره… می‌شود. بیشتر فریم‌ورک‌های وب دارای توابعی برای  HTML escaping کاراکتر‌هایی که در ادامه می‌آید می‌باشند. البته این نوع از Escaping برای بقیه بخش‌های HTML کافی نمی‌باشد و شما می‌بایست دیگر قوانین را خودتان توسعه دهید.

<body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body>
<div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
any other normal HTML elements

لیست سفید پیشنهادی

کاراکترهای زیر را با استفاده از HTML entity encoding و برای جلوگیری از تغییر context عادی به contextای با قابلیت اجرا، همچون تگ‌های script و style و هچنین پاسخ‌دهنگان وقایع (Event Handlers)، حتما Escape کنید. استفاده از hex entities پیشنهاد می‌شود.

& --> &amp;
< --> &lt;
> --> &gt;
" --> &quot;
' --> &#x27; &apos; not recommended because its not in the HTML spec. &apos; is in the XML and XHTML specs.
/ --> &#x2F; Forward slash is included as it helps end an HTML entity


#۲) قانون شماره‌ی دو: قرار دادن داده‌های غیرقابل اعتماد درون خواص المان‌ها (Attributes)

قانون شماره‌ی دو، برای قرار دادن داده‌های غیرقابل اعتماد درون خواص  عادی المان‌ها همچون width, name, value و غیره… می‌باشد. این قانون نباید برای خواص دیگری همچون href, src, style و یا خاصیت‌های مربوط به وقایع (Events) همچون onmouseover مورد استفاده قرار گیرد.

نکته‌ی مهم!
خاصیت‌های مربوط به وقایع می‌بایست از قانون شماره سه مربوط به جاوااسکریپت پیروی کنند.

<div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div> Inside UNquoted attribute
<div attr='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'>content</div> Inside single quoted attribute
<div attr="...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">content</div> Inside double quoted attribute

لیست سفید پیشنهادی

بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌های که کد اسکی آنها کمتر از ۲۵۶ می‌باشد را به فرمت &#xHH;  و یا مقدار مترادف حروفی تبدیل کنید. اینکار برای جلوگیری خروج از تعریف خاصیت می‌باشد. به معنی دیگر، برای جلوگیری از بستن و پایان دادن خاصیت و ورود به یک خاصیت دیگر می‌باشد. دلیل اینکه این قانون بسیاری از کارکتر‌ها را حذف میکند و فقط اجازه‌ی عبور کارکتر‌های حروف و عدد را می‌دهد، این است که برای بسیاری از توسعه‌دهندگان، قرار ندادن ' یا " در اطراف محتوای خاصیت امری عادی می‌باشد. در صورتیکه، خواصی که محتوای آنها بخوبی با کاراکتر‌های ' یا "  محدود شده باشند، تنها با کارکتر نقل قول مترادف (اگر برای شروع پایان از " استفاده شده است، فقط با قرار دادن ") می‌توان از محتوای مربوط به خاصیت خارج شد. اما خاصیت‌هایی که محتوایشان نقل قول‌گذاری نشده باشند، به راحتی با استفاده از خط فاصله (space) و یا هرکدام از کاراکتر‌های % * + , - / ; < = > ^ |، می‌توان از محتوای خاصیت خارج شد.


#۳) قانون شماره‌ی سه: قرار دادن داده‌های غیرقابل اعتماد درون مقادیر داده جاوااسکریپت (Javascript Data Values)

قانون شماره سه، به کد‌های جاوااسکریپتی که بصورت داینامیک تولید واستفاده می‌شوند می‌پردازد. هم کد‌های درون بلاک script و هم کد‌های درون خاصیت‌های مربوط به وقایع (Event-Handler Attributes). تنها جایی که می‌توانید بصورت امن داده‌های غیر‌قابل اعتماد را قرار دهید، درون یک مقدار که با نقل قول محدود شده است می‌باشد. قرار دادن داده‌های غیر‌قابل اعتماد در دیگر بخش‌های جاوااسکریپت، بسیار خطرناک می‌باشد و به راحتی می‌توان با استفاده از کاراکترهای، که البته به این موارد اشاره شده محدود نمی‌باشند،  وارد context‌ای با قابلیت اجرا شد. کارکتر‌هایی همچون ; = + و یا خط فاصله.

<script>alert('...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...')</script> Inside a quoted string
<script>x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'</script> One side of a quoted expression
<div onmouseover="x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'"</div> Inside quoted event handler

در نظر داشته باشید، برخی از توابع جاوااسکریپت هستند که هرگز نمی‌توان با اطمینان کامل داده‌های غیرقابل اعتماد را بعنوان ورودی به آنها داد، حتی اگر بطور مناسب با استفاده از قوانین شماره سه Escape شده باشند. بطور مثال:

<script>
window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
</script>

لیست سفید پیشنهادی

بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌های که کد اسکی آنها کمتر از ۲۵۶ می‌باشد را به فرمت \xHH می‌بایست تغییر داد تا از ورود contextای خارج از مقادیر داده‌ای، همچون context اجرای کد و یا یک خاصیت دیگر جلوگیری کرد.

نکته‌ی مهم!
هرگز از راه‌حل های میانبر برای Escpae همچون استفاده از \" استفاده نکنید. چون ممکن است عبارت نقل قولی استفاده شده باعث سردرگمی پارسر HTML شود و بدرستی عمل نکند. همچنین این راه حل مینابر ممکن است باعث حمله‌ای شود که به escape-the-escape معروف می‌باشد. بگونه‌ای که حمله‌کننده مقدار \" را بفرستد که در نتیجه به \\" تبدیل شود که در نهایت به مقدار نقل قول تبدیل می‌شود و اجازه تغییر context را می‌دهد.

اگر یک خاصیت  مربوط به واقعه بخوبی نقل قول گذاری شده باشد، خروج از آن نیازمند به نقل قول متناسب می‌باشد که به سادگی و با Escape مناسب قابل انجام نمی‌باشد. اما خاصیت‌های بدون نقل قول با استفاده از کاراکتر‌های زیادی همچون خط فاصله، % * + , - / ; < = > ^  | قابل خروج می‌باشند. همچنین یک تگ </script>  می‌تواند یک بلاک اسکریپت را ببند حتی اگر درون یک رشته‌ی نقل قول‌گذاری شده باشه، به این دلیل که Parser مربوط به HTML قبل از Parser مربوط به Javascript اجرا می‌شود.


#۴) قانون شماره‌ی چهار: قرار دادن داده‌های غیرقابل اعتماد درون مقادیر ویژگی استایل (Style Property Values)

قانون شماره‌ی چهار، برای مواقعی می‌باشد که شما می‌خواهید داده‌های غیرقابل اعتماد را درون stylesheet و یا تگ style قرار بدهید. CSS می‌تواند برای حملات بی‌شماری مورد استفاده قرار بگیرد. در نتیجه، شما می‌بایست تنها از داده‌های غیرقابل اعتماد بعنوان مقدار ویژگی (Property Value) استفاده کنید. استفاده از داده‌های غیرقابل اعتماد در بقیه‌ی بخش‌های CSS ممنوع می‌باشد. شما باید از قرار دادن اینگونه داده‌ها بعنوان مقادیر ویژگی‌هایی همچون url, behavior, -moz-binding و غیره… خودداری کنید. همچنین نباید از این داده‌ها برای مقادیر خواصی که در مرورگر Internet Explorer بصورت Javascript اجرا می‌شوند (مقداری درون عبارت expression()) استفاده کنید.

<style>selector { property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...; } </style> property value
<style>selector { property : "...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE..."; } </style> property value
<span style="property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">text</span> property value

نکته‌ی مهم!
توجه داشته باشید که در CSS Context بخش‌هایی وجود دارد که هرگز نمی‌توان داده‌های غیرقابل اعتماد را بعنوان ورودی به آنها داد. حتی اگر با استفاده از قوانین شماره چهار بخوبی Escape شده باشند. باید مطمعن شوید که آدرس‌های URL حتما با http/https شروع شده باشند و نه با javascript. همچنین مقادیر هرگز با expression شروع نشده باشند. همچون مثال زیر:

{ background-url : "javascript:alert(1)"; } // and all other URLs
{ text-size: "expression(alert('XSS'))"; } // only in IE

لیست سفید پیشنهادی

بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌های که کد اسکی آنها کمتر از ۲۵۶ می‌باشد را به فرمت  \HH می‌بایست تغییر داد.

نکته‌ی مهم!
هرگز از راه‌حل های میانبر برای Escpae همچون استفاده از \" استفاده نکنید. چون ممکن است عبارت نقل قولی استفاده شده باعث سردرگمی Parser مربوط بهHTML شود و بدرستی عمل نکند. همچنین این راه حل مینابر ممکن است باعث حمله‌ای شود که به escape-the-escape معروف می‌باشد. بگونه‌ای که حمله‌کننده مقدار \" را بفرستد که در نتیجه به \\" تبدیل شود که در نهایت به مقدار نقل قول تبدیل می‌شود و اجازه تغییر context را می‌دهد.

اگر یک مقدار  مربوط به ویژگی بخوبی نقل قول گذاری شده باشد، خروج از آن نیازمند به نقل قول متناسب می‌باشد که به سادگی و با Escape مناسب قابل انجام نمی‌باشد. اما خاصیت‌های بدون نقل قول با استفاده از کاراکتر‌های زیادی همچون خط فاصله، % * + , - / ; < = > ^  | قابل خروج می‌باشند. همچنین یک تگ </style>  می‌تواند یک بلاک استایل را ببند حتی اگر درون یک رشته‌ی نقل قول‌گذاری شده باشه.

نکته‌ی بسیار مهم!
برای CSS می‌بایست کلیه‌ی داده‌های غیر‌قابل اعتماد بصورت سفت و سخت encode شده تا برای مقادیر ویژگی با و بدون نقل قول مناسب، قابلیت خروج از context و یا اجرا نداشته باشند.

#۵) قانون شماره‌ی پنج: قرار دادن داده‌های غیرقابل اعتماد درون مقادیر پارامتر آدرس (URL Parameter Values)

قانون شماره پنج، برای مواقعی می‌باشد که می‌خواهید داده‌های غیرقابل اعتماد را بعنوان پارامتر HTTP GET قرار دهید.

<a href="http://www.somesite.com?test=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">link</a >

لیست سفید پیشنهادی

بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌های که کد اسکی آنها کمتر از ۲۵۶ می‌باشد را به فرمت %HH می‌بایست تغییر داد. همچنین قرار دادن داده‌های غیرقابل اعتماد درون URLهایی که با data: نوشته می‌شوند هرگز نباید انجام شود. به این دلیل که هیچ راه حل مناسبی برای جلوگیری از حملاتی که باعث خروج از مقدار مربوط به URL میشوند، وجود ندارد. تمامی مقادیر میبایست نقل قول‌گذاری شوند. تمامی خاصیت‌های بدون نقل قول با استفاده از کاراکتر‌های زیادی همچون خط فاصله، % * + , - / ; < = > ^  | قابل خروج می‌باشند. همچنین entity encoding در این context بلا استفاده می‌باشد.

نکته‌ی بسیار مهم!
هرگز برای URLهای کامل و وابسته (relative) از قانون شماره‌ی پنج استفاده نکنید. فقط بعنوان پارامتر می‌توانید از قانون شماره‌ی پنج استفاده کنید. URLها میبایست بخوبی اعتبارسنجی شوند تا مطمعن شوید که حاوی پروتکل ناخواسته بخصوص لینک‌های Javascript نباشند. بعد از اعتبار سنجی، URLها می‌بایست با توجه به contextای که میخواهند وارد شوند، با توجه به قوانین یک تا پنج Escape شوند. بطور مثال مقادیر که توسط کاربر برای href یک تگ a وارد شده است می‌بایست طبق قانون دوم که مربوط به خواص المان‌ها می‌باشد escape شود.

#۶) قانون شماره‌ی شش: کد‌های HTML را با کتابخانه‌هایی که برای Sanitizeکردن نوشته شده‌اند Sanitizeکنید.

اگر برنامه شما از قطعه کد‌های HTML پشتیبانی می‌کند، داده‌های غیرقابل اعتمادی که شامل کد‌های HTML هستند (همچون کامنت‌های وردپرس)، اعتبارسنجی آنها برای قرار دادن در صفحه بسیار سخت می‌باشد. همچنین Encoding آنها نیز سختی می‌باشد، چون ممکن است تمامی یا بخشی از تگ‌هایی که اجازه وارد کردن آنها را به کاربر داده‌اید را از بین ببرد. در نتیجه شما به یک کتابخانه که می‌تواند کد HTML را پاک کند و اجازه‌ی حضور تگ‌های اجازه داده شده و امن را می‌دهد نیاز دارید.

برای زبان‌های برنامه نویسی مختلف می‌توان به کتابخانه‌های زیر اشاره کرد:

#۷) قانون شماره‌ی هفتم: جلوگیری از حملات DOM-based XSS

با توجه به اینکه حملات DOM-based XSS دارای قوانین جداگانه‌ای می‌باشند، برای جلوگیری از طولانی شدن مطلب قوانین مربوط به اینگونه حملات را در پستی جداگانه و در آینده معرفی خواهم کرد.

قوانین تکمیلی

علاوه بر قوانین اصلی که در بالا به آنها اشاره شد، چهار قانون تکمیلی و کمکی نیز می‌تواند به شما در امن‌تر کردن برنامه‌هایتان کمک کند.

#۱) قانون تکمیلی شماره‌ی یک: استفاده از پرچم HTTPOnly برای کوکی‌ها

با توجه به اینکه همواره هکر‌ها بدنبال راه‌های جدیدی برای نفوذ هستند، بهتر است با قرار دادن پرچم HTTPOnly برای کوکی‌هایتان، جلوی دسترسی به آنها از طریق Javascript را بگیرید.

#۲) قانون تکمیلی شماره‌ی دو: پیاده سازی Content Security Policy

این ویژگی، یک ویژگی سمت مرورگر می‌باشد و به مرورگر اجازه می‌دهد تا یک لیست سفید برای منابع موجود در برنامه‌ی وب شما ایجاد کند. منابعی همچون جاوااسکریپت، CSS، عکس‌ها و… نحوه‌ی قرار دادن CSP از طریق هدر‌ HTTP میباشد. بطور مثال CSP زیر:

Content-Security-Policy: default-src: 'self'; script-src: 'self' static.domain.tld

به مرورگر وب می‌فهماند که تمامی منابع را از مبدا صفحه‌ای که در حال نمایش است اجازه‌ی دریافت دارد. علاوه بر آن برای فایل‌های جاوااسکریپت می‌تواند از مبدا static.domain.tld نیز استفاده کند.

#۳) قانون تکمیلی شماره‌ی سه: استفاده از یک سیستم قالب با قابلیت Escape اتوماتیک

بسیاری از فریمورک‌های اپلیکیشن دارای سیستم‌های قالبی می‌باشند که بصورت اتوماتیک با توجه به context محتوای در حال افزوده شدن، آنرا Escape می‌کند. از آنها استفاده کنید!

#۴) قانون تکمیلی شماره‌ی چهار: استفاده از هدر جواب (Response Header) با مقدار X-XSS-Protection

این هدر جواب HTTP فیلتر مقابله با تزریق کد موجود در برخی از مرورگر‌های وب بروز رو فعال میکند. این فیلتر بصورت پیشفرض فعال می‌باشد. اما با ارسال این هدر در جواب، به مرورگر می‌فهمانید که اگر این فیلتر توسط کاربر غیر‌فعال شده باشد، برای وبسایت شما آنرا دوباره فعال کند و از آن استفاده کند.

جمع بندی

در این پست سعی شد که تمامی مواردی که برای جلوگیری از حملات تزریق کد از نوع Stored XSS و Reflected XSS می‌بایست توسعه‌دهنده در نظر بگیرد معرفی و بررسی شود. با اعمال قوانین صفر تا شش، و قوانین تکمیلی یک تا چهار، می‌توانید با اطمینان بالایی از امنیت برنامه خود مطعمن بشوید. در ادامه به جمع بندی موارد گفته شده در قوانین صفر تا شش بصورت جدول می‌پردازیم.

خلاصه قوانین جلوگیری از حمله XSS

نوع داده زمینه (Context) نمونه کد راه مقابله
رشته (String) بدنه HTML <span>UNTRUSTED DATA</span> استفاده از HTML Entity Encoding (قانون اول)
رشته (String) خاصیت‌های امن تگ HTML <input type="text" name="fname" value="UNTRUSTED DATA">
  • استفاده از قانون دوم
  • تنها اجازه قرار دادن داده‌های غیرقابل اعتماد در خاصیت‌های امن موجود در لیست سفید (در پایین جدول آمده است) را دارید.
  • اعتبار‌سنجی موکد خاصیت‌های خطرناک که در لیست سفید نیامده است.
رشته (String) پارامتر GET <a href="/site/search?value=UNTRUSTED DATA">clickme</a>  استفاده از قانون پنجم
رشته (String) آدرس URL غیرقابل اعتماد در خاصیت‌های src و href <a href="UNTRUSTED URL">clickme</a>
<iframe src="UNTRUSTED URL" />
  •  استاندارد سازی ورودی
  • اعتبارسنجی URL
  • تایین امن بودن URL
  • لیست سفیدی تنها شامل http/https در ابتدای URL (برای جلوگیری از استفاده از javascript در ابتدای URL)
  • استفاده از قانون دوم
رشته (String) مقدار خاصیت CSS <div style="width: UNTRUSTED DATA;">Selection</div>
  •  استفاده از قانون چهارم
  • استفاده از Hex encoding برای CSS
  • طراحی مناسب CSS
رشته (String) متغییر جاوااسکریپت <script>var currentValue='UNTRUSTED DATA';</script>
<script>someFunction('UNTRUSTED DATA');</script>
  •  اطمینان از وجود نقل قول اطراف مقدار متغییر
  • استفاده از Hex encoding و Unicode Encoding مناسب Javascript
  • اجتناب از مینابر برای Escape همچون \" یا \' یا \\
کد HTML بدنه HTML <div>UNTRUSTED HTML</div>  استفاده از قانون ششم
رشته (String) حمله DOM XSS <script>document.write("UNTRUSTED INPUT: " + document.location.hash);<script/>  استفاده از قوانین مناسب (در پست‌ جداگانه در آیینده معرفی خواهند شد)

 

خلاصه قوانین Encoding خروجی

نوع Encoding مکانیزم پیشنهادی
HTML Entity Encoding  تبدیل مقادیر زیر به مقدار متناظر روبرو

& -> &amp;

< -> &lt;

> -> &gt;

" -> &quot;

' -> &#x27;

/ -> &#x2F;

HTML Attribute Encoding بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌ها را به فرمت &#xHH;  می‌بایست تغییر داد. مقدار HH برابر با مقدار HEX کاراکتر می‌باشد.
URL Encoding  بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌ها را به فرمت %HH می‌بایست تغییر داد. مقدار HH برابر با مقدار HEX کاراکتر می‌باشد.
JavaScript Encoding   بجز کارکتر‌های حروف و عدد (Alphanumeric)، بقیه‌ی کارکتر‌ها را به فرمت \uXXXX می‌بایست تغییر داد. مقدار X برابر با مقدار Integer می‌باشد.
CSS Hex Encoding  برای CSS دو راه برای Escape وجود دارد. \XX و \XXXXXX . بدلیل مشکلاتی که در راه اول وجود دارد (می‌توان آنرا دور زد)، دو راه زیر پیشنهاد می‌شود:

۱- اگر می‌خواهید از راه اول (کوتاه‌تر) استفاده کنید، بعد از هر escpae یک خط فاصله اضافه کنید.

۲- یا بطور کلی از راه‌حل دوم استفاده کنید.

 

کلام آخر…

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

 

لینک‌ها و منابع