none
MVC Ajax Post işleminde güvenlik açığı RRS feed

  • Soru

  • Merhaba Arkdaşlar,

    gerek mvc de olsun gerek webform larda  webmothod olarak kullanılan ajax post işlemlerinde kaynağı görüntülediğimizde url kısmında nereye ve datasınd da ne gönderdiğimiz görülüyor bu bir güvenlik açığı oluşturur mu ? eğer oluşturuyorsa da nasıl bu görünümü kapatabiliriz.. 

    mesela şöyle bir script ta :

    <script type="text/javascript">
        $(function() {
            $("#button").click(function() {
     
                var Isim = $("#isim").val();
     
                var veriler = { isim: Isim };
     
                $.ajax({
                    type: "post",
                    url: '@Url.Action("KayitYap", "Home")',
                    data: veriler,
                    dataType: "json",
                    success: function(msg) {
                        alert(msg);
                    },
                    error: function(msg) {
                        alert(msg);
                    }
                });
            });
        });
    </script>


    Controller da ki KayitYap methoduna isim alınarak kayıt yapılıyor ve bu yukarıdaki script  browser ın kaynağını görüntüle yapıldığında bildiğiniz üzere görülebiliyor bunu nasıl engelleyebiliriz...

    teşekkürler...




    • Düzenleyen fsem 25 Şubat 2014 Salı 10:41
    25 Şubat 2014 Salı 10:40

Yanıtlar

  • AntiForgeryToken inceleyebilirsiniz. Bu özellik sayesinde kriptolu bir veri cookie olarak browsere gönderilir ve her requestte kontrol edilir. 

    Bu sistemde kodun görünmesi engellenmez. Yapı, farklı uygulamalardan gelen taleplerin önüne geçilmesi şeklinde olur. Yani o scriptin sunucudaki karşılığını sadece bizim response gönderdiğimiz client çağırabilir.



    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com
    MCC


    25 Şubat 2014 Salı 11:20
    Moderatör

Tüm Yanıtlar

  • Bunu JavaScript kullanmadan direk Code Behind tarafında (web formlarda) yada MVC'de direk html tarafında yaparsan, kaynağı görüntülede gözükmez. 

    Yada genel olarak metot tanımlayarak, sadece bu metotları çağırırsan, sorun olmaz.


    Microsoft bu servisi kullanıcılarına yardım etme, Microsoft urunleri ve teknolojileriyle ilgili bilgi bankasını genişletme amacıyla ucretsiz sunmaktadır. Bu icerik olduğu gibi benim tarafımdan hazırlanmış olup Microsoft tarafından herhangi bir sorumluluk ustlenildiği anlamına gelmez. Iletişim: Mail Gönder

    25 Şubat 2014 Salı 11:19
    Moderatör
  • AntiForgeryToken inceleyebilirsiniz. Bu özellik sayesinde kriptolu bir veri cookie olarak browsere gönderilir ve her requestte kontrol edilir. 

    Bu sistemde kodun görünmesi engellenmez. Yapı, farklı uygulamalardan gelen taleplerin önüne geçilmesi şeklinde olur. Yani o scriptin sunucudaki karşılığını sadece bizim response gönderdiğimiz client çağırabilir.



    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com
    MCC


    25 Şubat 2014 Salı 11:20
    Moderatör
  • teşekkür ederim değerli cevaplarınız için..
    Önay hocam dediğiniz gibi araştırdım şöyle bi paylaşımda bulunulmuş yani bu aşşağıda yazdıklarımı uygulayınca xss açığı ortadan kalkmış mı oluyor tam anlayamadım. 

    önce view 'e bu kodu yazdım
    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
    {
        @Html.AntiForgeryToken()
    }

    sonrasında gene aynı view 'de script içerisine
    .
    .
    .
    var form = $('#__AjaxAntiForgeryForm');
                    var token = $('input[name="__RequestVerificationToken"]', form).val();
    
                    $.ajax({
                        type: "post",
                        beforeSend: function (request) {
                            request.setRequestHeader("X-XSRF-Token", token);},
                        url: '@Url.Action("KayitYap", "Home")',
                        data:{ 
                                __RequestVerificationToken: token, k: veriler},
                        dataType: "json",
                        success: function (msg) {.....}
      });
    </script>
    sonrasında nette bulduğum filters içerisine böyle bir class ekledim
    public class ValidateHttpAntiForgeryToken : ActionFilterAttribute, IActionFilter
        {
            void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
            {
                var request = filterContext.RequestContext.HttpContext.Request;
                try
                {
                    if (IsAjaxRequest(request))
                    {
                        ValidateRequestHeader(request);
                    }
                    else
                    {
                        AntiForgery.Validate();
                    }
                }
                catch (Exception ex)
                {
                    filterContext.Result = new HttpUnauthorizedResult("Yetki Yok");
                }
                this.OnActionExecuting(filterContext);
            }
            private bool IsAjaxRequest(HttpRequestBase request)
            {
                var headerValue = request.Headers["X-Requested-With"];
                if (headerValue != null)
                {
                    return String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
                }
                return false;
            }
    
            private void ValidateRequestHeader(HttpRequestBase request)
            {
                var headers = request.Headers;
                var cookie = request.Cookies.Get(AntiForgeryConfig.CookieName);
                if (cookie == null)
                    throw new InvalidOperationException(String.Format("Missing {0} cookie", AntiForgeryConfig.CookieName));
                var headerVal = headers.Get("X-XSRF-Token");
                AntiForgery.Validate(cookie.Value, headerVal);
            }
        }

    controller da ise
    [HttpPost]
            [ValidateAntiForgeryToken] //bunu ekledim
            public ActionResult KayitYap(kullanicilar k)
            {......}

    son olarakta web.config içerisine <system.web> tagları içine machineKey ekledim.

    sayfa kaynağında hidden olarak

    <form action="/Home/KayitYap" id="__AjaxAntiForgeryForm" method="post"><input name="__RequestVerificationToken" type="hidden" value="I-m78DCGL7YYpbfy8op99ib9OxxKMNlRCsB6U7wxrBirO06IcF3Wqtr8ryM7JkdXgz80W6Rf5cs8Bki3Img04d_lGniNzAiMkia1AZR2XY2Gyc3an4jjQ2" /></form>

    şeklinde bir çıktı oluştu.. Şimdi bu şekilde güvenlik sağlanmış oldu mu ki bunun testini nasıl yapabilirim
    tekrardan çok teşekkür ederim.. iyi çalışmlar...









    25 Şubat 2014 Salı 12:50
  • testini şöyle yapabilirsin; 

    yeni bir console application ekle solutiona, WebClient ya da HttpWebRequest ile url'ye veri post et. kayıt oluyorsa açık kapanmamaıştır, etmiyorsa ☺


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com
    MCC

    25 Şubat 2014 Salı 14:43
    Moderatör
  • @Html.AntiForgeryToken() varken veri yolladığımda 

    An unhandled exception of type 'System.Net.WebException' occurred in System.dll
    Additional information: The remote server returned an error: (500) Internal Server Error.

    şeklinde hata verdi.. Aynı şekilde @Html.AntiForgeryToken() kapatıp normal ajax post varken console dan veri yolladığımda ekliyor..

    Önay hocam teşekkür ederim sayenizde yeni birşey öğrenmiş oldum...
    25 Şubat 2014 Salı 15:37