it-swarm-tr.com

Müşteriden potansiyel olarak tehlikeli bir Request.Form değeri tespit edildi

Bir kullanıcı web uygulamamdaki bir sayfada < veya > içeren bir şey yayınladığında, bu istisnayı atıyorum.

Bir istisna atma veya bir web uygulamasının tamamını çökertmenin akıllılığı hakkındaki tartışmaya girmek istemiyorum çünkü birileri bir metin kutusuna bir karakter girdi, ancak bununla baş etmek için zarif bir yol arıyorum.

İstisnaların yakalanması ve gösterilmesi

Bir hata oluştu, lütfen geri dönün ve tüm formunuzu tekrar yazın, ancak bu sefer lütfen kullanmayın <

bana yeterince profesyonel görünmüyor.

Doğrulama sonrası doğrulama (validateRequest="false") devre dışı bırakılması bu hatayı kesinlikle önleyecektir, ancak sayfayı bir dizi saldırıya karşı savunmasız bırakacaktır.

İdeal olarak: HTML kısıtlı karakterleri içeren bir geri gönderme gerçekleştiğinde, Form koleksiyonundaki bu değer otomatik olarak HTML kodlu olur Böylece metin kutumun .Text özelliği something & lt; html & gt; olur

Bunu bir işleyiciden yapabilmemin bir yolu var mı?

1379
Radu094

Gönderilen tüm verileri kodlamaya çalışarak yanlış açıdan saldırdığınızı düşünüyorum.

"<" ifadesinin, veritabanı alanı, yapılandırma, dosya, özet akışı gibi diğer dış kaynaklardan da gelebileceğini unutmayın. 

Ayrıca, "<" doğal olarak tehlikeli değildir. Yalnızca belirli bir bağlamda tehlikelidir: HTML çıktısına kodlanmamış dizeler yazarken (XSS nedeniyle).

Diğer bağlamlarda, farklı alt dizeler tehlikelidir, örneğin, bir bağlantıya kullanıcı tarafından sağlanan bir URL yazarsanız, "javascript:" alt dizesi tehlikeli olabilir. Öte yandan, tekli alıntı karakteri, SQL sorgularında dizeleri birleştirirken tehlikelidir, ancak bir formdan gönderilen veya bir veri tabanı alanından okunan adın bir parçasıysa, tamamen güvenlidir.

Alt satırda: Tehlikeli karakterler için rasgele girdilere filtre uygulayamazsınız, çünkü herhangi bir karakter doğru koşullar altında tehlikeli olabilir. Bazı özel karakterlerin tehlikeli olabileceği bir yerde kodlamalısınız, çünkü özel bir anlama sahip oldukları farklı bir alt dile geçerler. HTML'ye bir dize yazdığınızda, Server.HtmlEncode kullanarak HTML'de özel anlamı olan karakterleri kodlamanız gerekir. Dinamik bir SQL ifadesine bir dize iletirseniz, farklı karakterleri kodlamanız gerekir (veya daha iyisi, hazırlanmış ifadeleri veya benzerlerini kullanarak çerçevenin sizin için yapmasına izin verin).

[] Dizeleri HTML’ye geçirdiğiniz her yerde HTML kodladığınızdan emin olduktan sonra, validateRequest="false" dosyanızdaki <%@ Page ... %> yönergesinde .aspx değerini ayarlayın.

.NET 4'te biraz daha fazlasını yapmanız gerekebilir. Bazen web.config ( reference ) 'ye <httpRuntime requestValidationMode="2.0" />' da eklemek gerekir.

1028
JacquesB

ASP.NET MVC kullanıyorsanız, bu hatanın farklı bir çözümü var:

C # örneği:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

Visual Basic örneği:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
497
Zack Peterson

ASP.NET MVC’de (sürüm 3’ten başlayarak), modelinizdeki bir özelliğe AllowHtml niteliğini ekleyebilirsiniz.

Özelliğin istek doğrulamasını atlayarak isteğin, model ciltleme sırasında HTML işaretlemesi eklemesine izin verir.

[AllowHtml]
public string Description { get; set; }
384

.NET 4.0 kullanıyorsanız, bunu <system.web> etiketlerinin içine web.config dosyasına eklediğinizden emin olun:

<httpRuntime requestValidationMode="2.0" />

.NET 2.0'da, istek doğrulama yalnızca aspx isteklerine uygulanır. .NET 4.0'da bu all request içerecek şekilde genişletildi. Aşağıdakileri belirterek .aspx işlenirken XSS doğrulaması gerçekleştirerek only öğesine geri dönebilirsiniz:

requestValidationMode="2.0"

Aşağıdakileri belirterek istek doğrulama tamamen özelliğini devre dışı bırakabilirsiniz:

validateRequest="false"
206
JordanC

ASP.NET 4.0 için, tüm siteyi bir <location> öğesine yerleştirerek sitenin tamamı yerine belirli sayfalar için giriş olarak işaretlemeye izin verebilirsiniz. Bu, diğer tüm sayfalarınızın güvenli olmasını sağlar. .Code_ sayfanıza ValidateRequest="false" yerleştirmeniz gerekmez.

<configuration>
...
  <location path="MyFolder/.aspx">
    <system.web>
      <pages validateRequest="false" />
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
...
</configuration>

Bunu web.config'inizde kontrol etmek daha güvenlidir, çünkü hangi sayfaların giriş olarak işaretlemeye izin verdiğini bir site düzeyinde görebilirsiniz.

İstek doğrulamanın devre dışı bırakıldığı sayfalarda girişi programlı olarak doğrulamanız gerekiyor.

108
Carter Medlin

Önceki cevaplar harika, ancak kimse HTML/JavaScript enjeksiyonları için tek bir alanın nasıl onaylanacağını dışlayamadı. Önceki sürümleri bilmiyorum, ancak MVC3 Beta'da bunu yapabilirsiniz:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

Bu, hariç tutulanlar dışındaki tüm alanları doğrular. Bununla ilgili güzel olan şey, doğrulama niteliklerinizin hala alanı doğrulamasıdır, ancak "Müşteriden potansiyel olarak tehlikeli bir Request.Form değeri tespit edildi" istisnası almazsınız.

Bunu normal bir ifadeyi doğrulamak için kullandım. Normal ifadenin geçerli olup olmadığını görmek için kendi ValidationAttribute'imi yaptım. Düzenli ifadeler bir betiğe benzeyen bir şey içerebildiğinden, yukarıdaki kodu uyguladım - normal ifade hala geçerli olup olmadığını kontrol ediyor, ancak komut dosyası veya HTML içeriyorsa.

70
gligoran

ASP.NET MVC'de, web.config'de requestValidationMode = "2.0" ve validateRequest = "false" ayarlamanız ve denetleyici işleminize bir ValidateInput niteliği uygulamanız gerekir:

<httpRuntime requestValidationMode="2.0"/>

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

ve

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
48
ranthonissen

Yapabilirsiniz HTML kodlamak metin kutusu içeriği, ancak ne yazık ki bu istisnanın gerçekleşmesini engellemez. Tecrübelerime göre, etrafta bir yol yok ve sayfa doğrulamasını devre dışı bırakmak zorundasınız. Bunu söyleyerek yaparak: "Dikkatli olacağım, söz veriyorum."

45
Pavel Chuchuva

MVC için, giriş doğrulamasını ekleyerek yok sayın 

[ValidateInput (yalancı)]

denetleyicideki her bir eylemin üstünde.

42
A.Dara

Global.asax'ta bu hatayı yakalayabilirsiniz. Hala onaylamak istiyorum ama uygun bir mesaj göstereceğim. Aşağıda listelenen blogda, bunun gibi bir örnek vardı. 

    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex is HttpRequestValidationException)
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.Write(@"[html]");
            Response.End();
        }
    }

Başka bir sayfaya yönlendirmek de istisnaya makul bir cevap gibi görünüyor.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html

41
BenMaddox

Lütfen bazı .NET kontrollerinin çıktıları otomatik olarak HTML kodlayacağını unutmayın. Örneğin, bir TextBox denetiminde .Text özelliğini ayarlamak otomatik olarak kodlayacaktır. Bu, özellikle <'un &lt;'a, >'un &gt;'a ve &'nun &amp;'a dönüştürülmesi anlamına gelir. Bu yüzden bunu yaparken dikkatli olun ...

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

Ancak, HyperLink, Literal ve Label öğelerinin .Text özelliği HTML'yi kodlamaz, bu nedenle Server.HtmlEncode (); <script> window.location = "http://www.google.com"; </script> sayfanıza çıkmasını ve ardından yürütülmesini önlemek istiyorsanız, bu özelliklerde ayarlanan herhangi bir şeyin şarttır.

Neyin kodlanıp neyin toplanmadığını görmek için biraz deneme yapın.

33
Dominic Pettifer

Bu sorunun cevabı basittir:

var varname = Request.Unvalidated["parameter_name"];

Bu, belirli bir istek için doğrulamayı devre dışı bırakır.

31
flakomalo

Web.config dosyasına, etiketlerin içine httpRuntime öğesini requestValidationMode = "2.0" özniteliğiyle ekleyin. Ayrıca, sayfa öğesinde validateRequest = "false" özelliğini ekleyin.

Örnek:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
27
Mahdi jokar

ValidateRequest'i devre dışı bırakmak istemiyorsanız istisnadan kaçınmak için bir JavaScript işlevi uygulamanız gerekir. En iyi seçenek değil ama işe yarıyor.

function AlphanumericValidation(evt)
{
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
        ((evt.which) ? evt.which : 0));

    // User type Enter key
    if (charCode == 13)
    {
        // Do something, set controls focus or do anything
        return false;
    }

    // User can not type non alphanumeric characters
    if ( (charCode <  48)                     ||
         (charCode > 122)                     ||
         ((charCode > 57) && (charCode < 65)) ||
         ((charCode > 90) && (charCode < 97))
       )
    {
        // Show a message or do something
        return false;
    }
}

Sonra arkasındaki kodda, PageLoad olayında, aşağıdaki kodu kullanarak kontrolünüze özelliği ekleyin:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
23
YORENGOY

Görünen o ki, kimse henüz aşağıdan bahsetmedi, ancak sorunu benim için düzeltti. Ve kimse evet demeden önce Visual Basic ... evet.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %>

Herhangi bir olumsuz tarafı var mı bilmiyorum, ama benim için bu inanılmaz çalıştı.

20
Piercy

Başka bir çözüm:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}
17
Sel

Framework 4.0 kullanıyorsanız, web.config içindeki giriş (<pages validateRequest = "false" />)

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

Framework 4.5 kullanıyorsanız, web.config içindeki giriş (requestValidationMode = "2.0")

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/>
</system.web>

Eğer sadece tek bir sayfa istiyorsanız, aspx dosyasında ilk satırı şu şekilde koymalısınız:

<%@ Page EnableEventValidation="false" %>

zaten <% @ Page gibi bir şeye sahipseniz, gerisini ekleyin => EnableEventValidation="false"%>

Yapmamayı tavsiye ederim.

14
Durgesh Pandey

ASP.NET'te, bir istisnayı yakalayabilir ve arkadaşça bir mesaj görüntüleme veya başka bir sayfaya yönlendirme gibi bir şey yapabilir ... Doğrulamayı kendiniz halletme olasılığı da vardır ...

Arkadaşça mesajı göster:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}
13
Jaider

Bir modülde yapabilirsin sanırım; ama bu bazı soruları açık bırakıyor; girişi bir veritabanına kaydetmek istiyorsanız ne yapmalıyım? Birdenbire, şifreli verileri veritabanına kaydettiğiniz için, girdilerden güveniyor ve bu da muhtemelen kötü bir fikir. İdeal olarak, ham kodlanmamış verileri veritabanında saklar ve her seferinde kodlarsınız.

Korumayı sayfa başına bir seviyede devre dışı bırakmak ve ardından her seferinde kodlamak daha iyi bir seçenektir.

Server.HtmlEncode'u kullanmak yerine, daha yeni, daha eksiksiz Anti-XSS kitaplığına Microsoft ACE ekibinden bakmalısınız.

12
blowdart

Buradaki diğer çözümler Güzel, ancak arka kısımda, her bir Model özelliğine [AllowHtml] uygulamak, özellikle de iyi boyutta bir sitede 100'den fazla modeliniz varsa, çok büyük bir acı.

Benim gibi, bu (IMHO oldukça anlamsız) özelliğini site genelinden kapatmak istiyorsanız, temel denetleyicinizdeki Execute () yöntemini geçersiz kılabilirsiniz (zaten bir temel denetleyiciniz yoksa, bir tane yapmanızı öneririm) ortak işlevsellik uygulamak için oldukça yararlıdır).

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

Kullanıcı girişinden gelen görünümlere pompalanan her şeyi HTML kodladığınızdan emin olun (yine de ASP.NET MVC 3'teki Razor ile olan davranışı yine de, Html.Raw () kullanıyorsanız bazı garip sebepler dışında bu özelliği gerektirmemelidir.

10
magritte

Gerçekten, >, <, vb. Gibi özel karakterlere ihtiyacınız varsa, sayfa doğrulamasını devre dışı bırakın. Ardından, kullanıcı girişi görüntülendiğinde, verilerin HTML kodlu olduğundan emin olun. 

Sayfa doğrulamasında bir güvenlik açığı var, bu yüzden atlanabilir. Ayrıca, sayfa doğrulama işlemine yalnızca güvenilmemelidir.

Bkz .: http://web.archive.org/web/20080913071637/http://www.procheckup.com:80/PDFs/bypassing-dot-NET-ValidateRequest.pdf

9
woany

Sebeb olmak

ASP.NET varsayılan olarak siteler arası komut dosyası çalıştırma (XSS) ve SQL enjeksiyonlarına yol açabilecek potansiyel olarak güvenli olmayan içerikler için tüm giriş denetimlerini doğrular. Bu nedenle, yukarıdaki istisnayı atarak bu tür içeriklere izin vermez. Varsayılan olarak, bu kontrolün her geri gönderimde yapılmasına izin verilmesi önerilir.

Çözüm

Pek çok durumda, sayfanıza Zengin Metin Kutuları veya Zengin Metin Düzenleyicileri aracılığıyla HTML içeriği göndermeniz gerekir. Bu durumda, @Page yönergesindeki ValidateRequest etiketini false olarak ayarlayarak bu istisnayı önleyebilirsiniz.

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>

Bu, ValidateRequest bayrağını false olarak ayarladığınız sayfa için isteklerin doğrulanmasını devre dışı bırakır. Bunu devre dışı bırakmak istiyorsanız, web uygulamanız boyunca kontrol edin; web.config <system.web> bölümünüzde false olarak ayarlamanız gerekir.

<pages validateRequest ="false" />

.NET 4.0 veya daha yüksek çerçeveler için yukarıdakileri yapmak için <system.web> bölümüne aşağıdaki satırı da eklemeniz gerekir.

<httpRuntime requestValidationMode = "2.0" />

Bu kadar. Umarım bu yukarıdaki sorundan kurtulmanıza yardımcı olur.

Referans: ASP.Net Hatası: İstemciden potansiyel olarak tehlikeli bir Request.Form değeri tespit edildi

9
vakeel

.NET'te kodu çözülen verileri kodlamak için JavaScript kullanan bir çözüm buldum (ve jQuery gerektirmiyor).

  • Metin kutusunu ASP yerine bir HTML öğesi (textarea gibi) yapın.
  • Gizli bir alan ekleyin.
  • Aşağıdaki JavaScript işlevini başlığınıza ekleyin.

    işlev boo () { targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("userbox"); targetText.value = escape (sourceText.innerText); }

Senin textarea, boo () çağıran bir değişim ekleyin:

<textarea id="userbox"  onchange="boo();"></textarea>

Son olarak, .NET'te, kullanımı

string val = Server.UrlDecode(HiddenField1.Value);

Bunun tek yönlü olduğunun farkındayım - iki yöne ihtiyacınız varsa yaratıcı olmanız gerekir, ancak web.config dosyasını düzenleyemiyorsanız bu bir çözüm sunar.

İşte bir örnek (MC9000) geldi ve jQuery aracılığıyla kullanıldı:

$(document).ready(function () {

    $("#txtHTML").change(function () {
        var currentText = $("#txtHTML").text();
        currentText = escape(currentText); // Escapes the HTML including quotations, etc
        $("#hidHTML").val(currentText); // Set the hidden field
    });

    // Intercept the postback
    $("#btnMyPostbackButton").click(function () {
        $("#txtHTML").val(""); // Clear the textarea before POSTing
                               // If you don't clear it, it will give you
                               // the error due to the HTML in the textarea.
        return true; // Post back
    });


});

Ve işaretleme:

<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />

Bu harika çalışıyor. Bir bilgisayar korsanı JavaScript'i atlayarak göndermeye çalışırsa, hatayı görürler. Ayrıca bir veritabanında kodlanmış tüm bu verileri kaydedebilir, daha sonra (sunucu tarafında) unescape ve başka bir yerde göstermeden önce saldırıları ayrıştırıp kontrol edebilirsiniz.

9
Jason Shuler

Ben de bu hatayı alıyordum.

Benim durumumda, bir kullanıcı Rol Adına á aksanlı bir karakter girmiştir (ASP.NET üyelik sağlayıcısı ile ilgili olarak).

Rol adını, Kullanıcılara bu rol için bir yöntem verdim ve $.ajax post isteği başarısızlıkla sonuçlandı ...

Bunu sorunu çözmek için yaptım:

Yerine

data: { roleName: '@Model.RoleName', users: users }

Bunu yap

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

Bu numarayı @Html.Raw yaptı.

Rol adını HTML değeri roleName="Cadastro b&#225;s" olarak alıyordum. HTML varlığı &#225; olan bu değer ASP.NET MVC tarafından engellendi. Şimdi roleName parametre değerini olması gerektiği gibi alıyorum: roleName="Cadastro Básico" ve ASP.NET MVC motoru artık isteği engellemeyecek.

9
Leniel Maccaferri

Özel karakterleri değiştirmek için JavaScript'in escape (string) işlevini de kullanabilirsiniz. Ardından sunucu tarafında geri almak için Server. URLDecode (string) kullanın.

Bu yolla giriş doğrulama özelliğini kapatmanız gerekmez ve diğer programcılar için dizenin HTML içeriğine sahip olabileceği daha açık olacaktır.

7
Trisped

İstemediğiniz karakterleri kontrol etmek için her geri göndermeden önce JavaScript'i kullandım:

<asp:Button runat="server" ID="saveButton" Text="Save" CssClass="saveButton" OnClientClick="return checkFields()" />

function checkFields() {
    var tbs = new Array();
    tbs = document.getElementsByTagName("input");
    var isValid = true;
    for (i=0; i<tbs.length; i++) {
        if (tbs(i).type == 'text') {
            if (tbs(i).value.indexOf('<') != -1 || tbs(i).value.indexOf('>') != -1) {
                alert('<> symbols not allowed.');
                isValid = false;
            }
        }
    }
    return isValid;
}

Sayfama verilen veri çoğunlukla veri girişidir ve geri gönderme yapan çok az öğe vardır, ancak en azından verileri korunur.

6
Ryan

Bunlar sadece "<" ve ">" (çift tırnak işaretinin kendisi değil) karakterler olduğu ve bunları <input value = "this" /> güvendesiniz (<textarea> this one </textarea> için elbette savunmasız kalacaksınız). Bu durumunuzu kolaylaştırabilir, ancak herhangi bir şey için daha fazlası için yayınlanan diğer çözümlerden birini kullanın.

4
Paweł Hajdan

Kullanıcılarınıza <ve> kullanımlarının kullanılmayacağını söylemek istiyorsanız, ancak tüm formun önceden işlenmesini/geri gönderilmesini (ve tüm girdileri kaybetmeden) istemezsiniz Bu (ve belki de potansiyel olarak tehlikeli diğer) karakterleri taramak için alanın çevresinde doğrulayıcı?

4
Captain Toad

Gibi bir şey kullanabilirsiniz:

var nvc = Request.Unvalidated().Form;

Daha sonra, nvc["yourKey"] çalışmalıdır.

4
Ady Levy

Önerilerden hiçbiri benim için çalıştı. Zaten bu özelliği tüm web sitesi için kapatmak istemedim çünkü% 99'unda kullanıcıların web formlarına HTML yerleştirmesini istemiyorum. Bu çalışmayı kullanan tek kişi benim olduğum için, kendi yöntemimi yeni yarattım. Giriş kodunu HTML koduna dönüştürür ve veritabanına eklerim.

4
Mike S.

Özel Model Binder'da HTML kodlama alanını otomatik olarak yapabilirsiniz. Benim çözümüm biraz farklı, ModelState'e hata koydum ve alanın yakınında hata mesajı gösterdim. Otomatik olarak kodlamak için bu kodu değiştirmek kolaydır. 

 public class AppModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            try
            {
                return base.CreateModel(controllerContext, bindingContext, modelType);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }
        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
            PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            try
            {
                return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }

        protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
        {
            var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
            if (valueProviderCollection != null)
            {
                ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            }

            string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
                     bindingContext.ModelMetadata.DisplayName);

            bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
        }
    }

Application_Start'ta:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

Yalnızca form alanları için çalıştığını unutmayın. Tehlikeli değer denetleyici modeline geçmedi, ancak ModelState'te saklandı ve hata mesajı ile yeniden görüntülenebilir. 

URL’deki tehlikeli karakterler şu şekilde kullanılabilir:

private void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpContext httpContext = HttpContext.Current;

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        var httpCode = httpException.GetHttpCode();
        switch (httpCode)
        {
            case (int)HttpStatusCode.BadRequest /* 400 */:
                if (httpException.Message.Contains("Request.Path"))
                {
                    httpContext.Response.Clear();
                    RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
                    requestContext.RouteData.Values["action"] ="InvalidUrl";
                    requestContext.RouteData.Values["controller"] ="Error";
                    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
                    IController controller = factory.CreateController(requestContext, "Error");
                    controller.Execute(requestContext);
                    httpContext.Server.ClearError();
                    Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
                }
                break;
        }
    }
}

ErrorController: 

public class ErrorController : Controller
 {
   public ActionResult InvalidUrl()
   {
      return View();
   }
}   
3
Sel

Sitenizi tehlikeli girdilerden korumak için Server.HtmlEncode yöntemini kullanmalısınız.

Daha fazla bilgi burada

3
bastos.sergio

Sel'in cevabı 'a yaptığım yorumda belirtildiği gibi, bu bizim özel istek doğrulayıcımızın uzantısıdır.

public class SkippableRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        if (collectionKey != null && collectionKey.EndsWith("_NoValidation"))
        {
            validationFailureIndex = 0;
            return true;
        }

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}
2
Walden Leverich

Model bağlama özelliğini kullanmayan, her parametreyi Request.Form'dan ayıklayan, giriş metninin zarar vermeyeceğinden emin olanlar için başka bir yol daha var. Harika bir çözüm değil ama işi yapacak. 

Müşteri tarafından, uri olarak kodla ve gönder.
Örneğin: 

encodeURIComponent($("#MsgBody").val());  

Sunucu tarafından kabul edip uri olarak kodunu çöz.
Örneğin: 

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form["MsgBody"]) : 
null;  

veya 

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Uri.UnescapeDataString(HttpContext.Current.Request.Form["MsgBody"]) : 
null; 

lütfen UrlDecode ve UnescapeDataString arasındaki farkları arayın.

2
Wahid Masud

Son fakat en az değil, lütfen ASP.NET Veri Bağlama denetimlerinin veri bağlama sırasında otomatik olarak kodlama değerlerine dikkat edin. Bu ItemTemplate içindeki tüm ASP.NET denetimlerinin (TextBox, Label vb.) Varsayılan davranışını değiştirir. Aşağıdaki örnek göstermektedir (ValidateRequest false olarak ayarlanmıştır):

aspx

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
    <form runat="server">
        <asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                <asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
                <asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
            </ItemTemplate>
        </asp:FormView>
    </form> 

arkasındaki kod

public partial class _Default : Page
{
    S s = new S();

    protected void Button1_Click(object sender, EventArgs e)
    {
        s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
        FormView1.DataBind();
    }

    public S FormView1_GetItem(int? id)
    {
        return s;
    }
}

public class S
{
    public string Text { get; set; }
}
  1. Dava gönderme değeri: &#39;

Label1.Text değeri: &#39;

TextBox2.Text değeri: &amp;#39;

  1. Dava gönderme değeri: <script>alert('attack!');</script>

Label1.Text değeri: <script>alert('attack!');</script>

TextBox2.Text değeri: &lt;script&gt;alert(&#39;attack!&#39;);&lt;/script&gt;

1
dpant

Hala web formlarında kaldıklarımız için, sadece bir alandaki onaylamayı devre dışı bırakmanıza izin veren aşağıdaki çözümü buldum! (Tüm sayfa için onu devre dışı bırakmaktan nefret ederim.)

VB.NET:

Public Class UnvalidatedTextBox
    Inherits TextBox
    Protected Overrides Function LoadPostData(postDataKey As String, postCollection As NameValueCollection) As Boolean
        Return MyBase.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form)
    End Function
End Class

C #:

public class UnvalidatedTextBox : TextBox
{
    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        return base.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form);
    }
}

Şimdi sadece <prefix:UnvalidatedTextBox id="test" runat="server" /> yerine <asp:TextBox kullanın ve tüm karakterlere izin vermelidir (bu, şifre alanları için mükemmeldir!)

1
Peter

Bu sorunun form gönderme ile ilgili olduğunu biliyorum, ancak başka durumlarda bu hatayı alan kişiler için bazı bilgiler eklemek istiyorum. Ayrıca, bir web servisini uygulamak için kullanılan bir işleyicide de oluşabilir. 

Web istemcinizin ajax kullanarak POST veya PUT istekleri gönderdiğini ve web hizmetinize json veya xml metin veya ham veri (dosya içeriği) gönderdiğini varsayalım. Web servisinizin İçerik Tipi başlığından herhangi bir bilgi alması gerekmediğinden, JavaScript kodunuz bu başlığı ajax isteğinize göre ayarlamamıştır. Ancak bu başlığı bir POST/PUT ajax isteğinde ayarlamazsanız, Safari bu başlığı ekleyebilir: "Content-Type: application/x-www-form-urlencoded". İPhone'da Safari 6'da, ancak diğerlerinin Safari sürümleri/işletim sistemi veya Chrome'da da aynı olabileceğini gözlemledim. Bu nedenle, bu İçerik Tipi başlığını alırken, .NET Framework'ün bir kısmı, istek gövdesi veri yapısının, bir HttpRequestValidationException istisnası oluşturmazken ve bir html form gönderme işlemine karşılık geldiğini varsayar. Yapmanız gereken ilk şey, açık bir şekilde her zaman bir POST/PUT ajax isteğinde form MIME türünden başka birşeye İçerik Türü üstbilgisini ayarlamaktır.

Ayrıca bu ayrıntıyı da keşfettim:
Bu durumlarda, kodunuz HttpRequest.Params koleksiyonuna erişmeye çalıştığında HttpRequestValidationException istisnası artar. Ancak, şaşırtıcı bir şekilde, bu istisna, HttpRequest.ServerVariables koleksiyonuna eriştiğinde artmaz. Bu, bu iki koleksiyonun neredeyse aynı görünse de, birinin güvenlik kontrolleri yoluyla talep verilerine eriştiğini ve diğerinin istemediğini gösteriyor.

1
figolu

Her zamanki durum olan .Net 4.0 ve sonrasında, aşağıdaki ayarı system.web dosyasına koyun

<system.web>
     <httpRuntime requestValidationMode="2.0" />
1
Kiran Chaudhari

benim durumumda, asp: Textbox control (Asp.net 4.5) kullanarak validateRequest="false" .__ için tüm sayfayı ayarlamak yerine. 

<asp:TextBox runat="server" ID="mainTextBox"
            ValidateRequestMode="Disabled"
 ></asp:TextBox>

istisnaya neden olan Metin kutusunda.

0
maozx

Bir çözüm

Son doğrulama işlemini kapatmak istemiyorum (validateRequest = "false"). Öte yandan, masum bir kullanıcının <x veya başka bir şey yazması nedeniyle uygulamanın çökmesi kabul edilemez. 

Bu nedenle bir ön kontrol yapan bir istemci tarafı javascript işlevi (xssCheckValidates) yazdım. Bu fonksiyon, form verilerini kaydetme denemesi olduğunda çağrılır:

<form id="form1" runat="server" onsubmit="return xssCheckValidates();">

İşlev oldukça basittir ve geliştirilebilir ancak görevini yerine getirir.

Lütfen bunun amacının sistemi hacklemeden korumak değil, kullanıcıları kötü bir deneyimden korumak olduğunu unutmayın. Sunucuda yapılan istek onayı hala açıktır ve bu (sistemin yapabileceği ölçüde) sistemin korumasının bir parçasıdır. 

Burada "bir parçası" deme sebebi, yerleşik talep doğrulamasının yeterli olmayabileceğini duyduğum için, tam korumayı sağlamak için başka tamamlayıcı araçlar gerekli olabilir. Fakat yine de burada sunduğum javascript işlevi, sistemi korumakla ilgili hiçbir şey işlevine sahiptir. Kullanıcıların kötü bir deneyime sahip olmayacağından emin olmak için yalnızca kullanılır.

Burada deneyebilirsiniz:

    function xssCheckValidates() {
      var valid = true;
      var inp = document.querySelectorAll(
          "input:not(:disabled):not([readonly]):not([type=hidden])" +
          ",textarea:not(:disabled):not([readonly])");
      for (var i = 0; i < inp.length; i++) {
        if (!inp[i].readOnly) {
          if (inp[i].value.indexOf('<') > -1) {
            valid = false;
            break;
          }
          if (inp[i].value.indexOf('&#') > -1) {
            valid = false;
            break;
          }
        }
      }
      if (valid) {
        return true;
      } else {
        alert('In one or more of the text fields, you have typed\r\nthe character "<" or the character sequence "&#".\r\n\r\nThis is unfortunately not allowed since\r\nit can be used in hacking attempts.\r\n\r\nPlease edit the field and try again.');
        return false;
      }
    }
<form onsubmit="return xssCheckValidates();" >
  Try to type < or &# <br/>
  <input type="text" /><br/>
  <textarea></textarea>
  <input type="submit" value="Send" />
</form>

0
Magnus

Server.HtmlEncode("yourtext"); öğesini kullanın

0
Voigt

Bunun hakkında çok şey yazıldığını görüyorum ... ve bunun bahsettiğini görmedim . Bu, .NET Framework 4.5'ten beri kullanılabilmektedir.

Bir kontrol için ValidateRequestMode ayarı harika bir seçenektir .. __ Bu sayede sayfadaki diğer kontroller hala korunmaktadır. Hiçbir web.config değişikliği gerekmez.

 protected void Page_Load(object sender, EventArgs e)
    {
             txtMachKey.ValidateRequestMode = ValidateRequestMode.Disabled;
    }
0
Chris Catignani