در حال ویرایش تزریق اسکریپت(Cross Site Scripting)

از Secure Coding

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

این ویرایش را می‌توان خنثی کرد. لطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که می‌خواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثی‌سازی ویرایش را به پایان ببرید.

نسخهٔ فعلی متن شما
سطر ۱: سطر ۱:
این نوع آسیب پذیری سمت client است و با استفاده از تزریق اسکریپت در صحفات به وجود می آید.
 
  
به علت اجرای اسکریپت بر روی سیستم کاربران و تفاوت بین css که برای طراحی صفحات وب است به آن xss هم گفته می شود.
 
 
از عواقب این نوع حملات باعث دسترسی به مرورگر و یا حتی سیستم قربانی می شود.
 
 
3 نوع مختلف xss وجود دارد که عبارتنند از:
 
 
# reflected
 
 
درخواست زیر را در نظر بگیرید.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
https://insecure-website.com/search?term=gift
 
</pre>
 
</div>
 
 
درخواست پس از اجرا در صفحه وب به صورت زیر نمایش پیدا می کند.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<p>You searched for: gift</p>
 
</pre>
 
</div>
 
 
حال اگر مهاجم مقدار پارامتر term را به صورت زیر تغییر دهیم.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
 
</pre>
 
</div>
 
 
در صفحه وب مقدار به صورت زیر نمایش پیدا می کند.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<p>You searched for: <script>/* Bad stuff here... */</script></p>
 
</pre>
 
</div>
 
 
# stored
 
 
درخواست زیر را در نظر بگیرید.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
POST /post/comment HTTP/1.1
 
Host: vulnerable-website.com
 
Content-Length: 100
 
 
postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
 
</pre>
 
</div>
 
 
پس از اجرای درخواست مقدار پارامتر comment در پایگاه داده ذخیره و بر روی صفحه به صورت زیر چاپ می شود.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<p>This post was extremely helpful.</p>
 
</pre>
 
</div>
 
 
حال اگر مقدار پارامتر comment را به صورت زیر تغییر دهیم.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E
 
</pre>
 
</div>
 
 
مقدار بالا پس از ذخیره در پایگاه داده، هنگام بارگذاری صفحه به صورت زیر اجرا می شود.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<p><script>/* Bad stuff here... */</script></p>
 
</pre>
 
</div>
 
 
# dom
 
 
در جاوااسکریپت یک سری از توابع از نوع Source یا دریافت کننده و یک نوع از توابع از نوع Sink یا اجرا کننده است.
 
 
برخی از توابع از نوع Source:
 
 
* document.URL
 
* document.documentURI
 
* location.href
 
* location.search
 
* location.*
 
* window.name
 
* document.referrer
 
 
برخی از توابع از نوع Sink:
 
 
* document.write
 
* (element).innerHTML
 
* (element).src (in certain elements)
 
* Eval
 
* setTimout / setInterval
 
* execScript
 
 
با توجه به موارد بالا فرض کنید درخواستی به شکل زیر داریم.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
http://www.example.com/test.html#<script>alert(1)</script>
 
</pre>
 
</div>
 
 
محتوای صفحه اجرا کننده در خواست هم شامل کد زیر است.
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<script>
 
  document.write("<b>Current URL</b> : " + document.baseURI);
 
</script>
 
</pre>
 
</div>
 
 
با توجه کد بالا هنگام اجرای درخواست مقدار
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<script>alert(1)</script>
 
</pre>
 
</div>
 
 
توسط document.baseURI دریافت و در document.write اجرا می شود.
 
 
== روش های جلوگیری ==
 
 
=== روش های جلوگیری PHP ===
 
 
مثال 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<?php
 
  $name=$_GET['name'];
 
  print $name;
 
?>
 
</pre>
 
</div>
 
 
روش 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<?php
 
/*
 
* XSS filter
 
*
 
* This was built from numerous sources
 
* (thanks all, sorry I didn't track to credit you)
 
*
 
* It was tested against *most* exploits here: http://ha.ckers.org/xss.html
 
* WARNING: Some weren't tested!!!
 
* Those include the Actionscript and SSI samples, or any newer than Jan 2011
 
*
 
*
 
* TO-DO: compare to SymphonyCMS filter:
 
* https://github.com/symphonycms/xssfilter/blob/master/extension.driver.php
 
* (Symphony's is probably faster than my hack)
 
*/
 
 
function xss_clean($data)
 
{
 
        // Fix &entity\n;
 
        $data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
 
        $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
 
        $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
 
        $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
 
 
        // Remove any attribute starting with "on" or xmlns
 
        $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
 
 
        // Remove javascript: and vbscript: protocols
 
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
 
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
 
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
 
 
        // Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
 
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
 
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
 
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
 
 
        // Remove namespaced elements (we do not need them)
 
        $data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
 
 
        do
 
        {
 
                // Remove really unwanted tags
 
                $old_data = $data;
 
                $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
 
        }
 
        while ($old_data !== $data);
 
 
        // we are done...
 
        return $data;
 
}
 
  $name=xss_clean($_GET['name']);
 
  print $name;
 
?>
 
</pre>
 
</div>
 
 
=== روش های جلوگیری ASP.NET ===
 
 
مثال 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
/*
 
* https://gist.github.com/DinisCruz/3fa6893bc85a9fcacdf6
 
*/
 
  public static class HtmlControls_ExtensionMethods
 
    {
 
        public static string renderControl(this Control control)
 
        {
 
            var stringBuilder = new StringBuilder();
 
            using (var stringWriter = new StringWriter(stringBuilder))
 
                using (var htmlTextWriter = new HtmlTextWriter(stringWriter))
 
         
 
                    control.RenderControl(htmlTextWriter);
 
            return stringBuilder.str();
 
        }
 
 
    }
 
 
    [TestFixture]
 
    class XSS_Web_Controls
 
    {       
 
 
        [Test]
 
        public void HtmlTitle()
 
        {
 
            var html_Before = "<title>\r\n\t";
 
            var html_After  = "\r\n</title>";
 
 
            Func<string, string> render_Payload = (payload) =>
 
                {
 
                    var htmlTitle = new HtmlTitle {Text = payload};
 
                    return htmlTitle.renderControl();
 
                };
 
 
            Action<string> test_Payload = (payload) =>
 
                {
 
                    render_Payload(payload).assert_Is(html_Before + payload + html_After);
 
                };
 
 
            test_Payload("aa '\"> bb <b1> cc ");
 
            test_Payload("<script>alert(42)</script>");
 
            test_Payload("aaa</title></head><body><img src=xxx onerror=alert(42) />");           
 
        }
 
</pre>
 
</div>
 
 
روش 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
/*
 
* https://gist.github.com/DinisCruz/3fa6893bc85a9fcacdf6
 
*/
 
  public static class HtmlControls_ExtensionMethods
 
    {
 
        public static string render_Control(this Control control)
 
        {
 
            var stringBuilder = new StringBuilder();
 
            using (var stringWriter = new StringWriter(stringBuilder))
 
                using (var htmlTextWriter = new HtmlTextWriter(stringWriter))
 
         
 
                    control.RenderControl(htmlTextWriter);
 
            return stringBuilder.str();
 
        }
 
 
        public static string set_Text_and_Render_Control<T>(this T control, string text) where T : Control
 
        {
 
            control.invoke("set_Text", text);
 
            return control.render_Control();
 
        }
 
 
        public static T assert_Text_Render<T>(this T control, string html_Before, string html_After, string text) where T : Control
 
        {
 
            control.set_Text_and_Render_Control(text).assert_Is(html_Before + text + html_After);
 
            return control;
 
        }
 
    }
 
 
    [TestFixture]
 
    class XSS_Web_Controls
 
    {
 
        string payload_1 = "aa '\"> bb <b1> cc ";
 
        string payload_2 = "<script>alert(42)</script>";
 
        string payload_3 = "aaa</title></head><body><img src=xxx onerror=alert(42) />";
 
 
        [Test]
 
        public void HtmlTitle()
 
        {
 
            var html_Before = "<title>\r\n\t";
 
            var html_After  = "\r\n</title>";
 
           
 
 
            new HtmlTitle().assert_Text_Render(html_Before, html_After, payload_1)
 
                          .assert_Text_Render(html_Before, html_After, payload_2)
 
                          .assert_Text_Render(html_Before, html_After, payload_3);
 
           
 
        }
 
 
        [Test]
 
        public void Literal()
 
        {
 
            var html_Before = "";
 
            var html_After  = "";
 
 
            new Literal().assert_Text_Render(html_Before, html_After, payload_1)
 
                        .assert_Text_Render(html_Before, html_After, payload_2)
 
                        .assert_Text_Render(html_Before, html_After, payload_3);
 
 
        }
 
 
        [Test]
 
        public void LinkButton()
 
        {
 
            var html_Before = "<a>";
 
            var html_After  = "</a>";
 
 
            new LinkButton().assert_Text_Render(html_Before, html_After, payload_1)
 
                            .assert_Text_Render(html_Before, html_After, payload_2)
 
                            .assert_Text_Render(html_Before, html_After, payload_3);
 
        }
 
       
 
    }
 
</pre>
 
</div>
 
 
 
=== روش های جلوگیری JAVA ===
 
 
 
مثال 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
<html>
 
<head>
 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
<title>XSS Vulnerable</title>
 
</head>
 
<body>
 
<form action="xss-vuln.jsp" method="post">
 
Enter your name: <input type="text" name="name"><input type="submit">
 
</form>
 
 
<%
 
if(request.getMethod().equalsIgnoreCase("post"))
 
{
 
String name = request.getParameter("name");
 
if(!name.isEmpty())
 
{
 
out.println("<br>Hi "+name+". How are you?");
 
}
 
}
 
%>
 
 
</body>
 
</html>
 
</pre>
 
</div>
 
 
روش 1)
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<pre>
 
<%@page import="org.apache.commons.lang.StringEscapeUtils"%>
 
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 
Patch
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
<html>
 
<head>
 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
<title>XSS Patched</title>
 
</head>
 
<body>
 
<form action="xss-patch.jsp" method="post">
 
Enter your name: <input type="text" name="name"><input type="submit">
 
</form>
 
 
<%
 
if(request.getMethod().equalsIgnoreCase("post"))
 
{
 
String name = StringEscapeUtils.escapeHtml(request.getParameter("name"));
 
if(!name.isEmpty())
 
{
 
out.println("<br>Hi "+name+". How are you?");
 
}
 
}
 
%>
 
</body>
 
</html>
 
</pre>
 
</div>
 
 
 
[[category:تزریق اسکریپت(Cross Site Scripting)]]
 
[[category:آسیب پذیری بر پایه DOM]]
 

لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در Secure Coding ممکن است توسط دیگر مشارکت‌کنندگان تغییر یابند، ویرایش یا حذف شوند. اگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش شوند؛ بنابراین، آنها را اینجا ارائه نکنید.
شما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید (Secure Coding:حق تکثیر را برای جزئیات بیشتر ببینید). کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!

لغو راهنمای ویرایش‌کردن (در پنجرهٔ تازه باز می‌شود)