it-swarm-eu.dev

Z klienta byla zjištěna potenciálně nebezpečná hodnota Request.Form

Pokaždé, když uživatel napíše stránku obsahující < nebo > na stránce v mé webové aplikaci, dostanu tuto výjimku.

Nechci jít do diskuse o chytrosti vhazování výjimky nebo pádu celé webové aplikace, protože někdo zadal znak do textového pole, ale hledám elegantní způsob, jak to zvládnout.

Zachycení výjimky a zobrazení

Došlo k chybě, vraťte se prosím znovu a znovu zadejte celý formulář, ale tentokrát prosím nepoužívejte <

nezdá se mi to dost profesionální.

Deaktivace post validace (validateRequest="false") se této chybě určitě vyhne, ale ponechá stránku zranitelnou vůči řadě útoků.

V ideálním případě: Pokud se příspěvek vrátí, který obsahuje znaky s omezeným kódem HTML, bude zaúčtovaná hodnota ve sbírce formulářů automaticky zakódována ve formátu HTML. Vlastnost .Text mého textového pole bude tedy something & lt; html & gt;

Je to způsob, jak to můžu udělat od psovoda?

1379
Radu094

Myslím, že na něj útočíte ze špatného úhlu pokusem o zakódování všech odeslaných dat.

Všimněte si, že "<" může také pocházet z jiných vnějších zdrojů, jako je databázové pole, konfigurace, soubor, zdroj a tak dále. 

Dále, "<" není ve své podstatě nebezpečné. Je to nebezpečné pouze v určitém kontextu: při psaní řetězců, které nebyly kódovány do výstupu HTML (kvůli XSS).

V jiných kontextech jsou různé dílčí řetězce nebezpečné, například pokud do odkazu vložíte adresu URL zadanou uživatelem, může být dílčí řetězec "javascript:" nebezpečný. Znak jednorázové nabídky na druhé straně je nebezpečný při interpolaci řetězců v SQL dotazech, ale naprosto bezpečný, pokud je součástí názvu odeslaného z formuláře nebo čteného z databázového pole.

Pointa je: nemůžete filtrovat náhodné vstupy pro nebezpečné znaky, protože každá postava může být za správných okolností nebezpečná. Měli byste kódovat v místě, kde se některé specifické znaky mohou stát nebezpečnými, protože přecházejí do jiného sub-jazyka, kde mají zvláštní význam. Při psaní řetězce HTML, měli byste kódovat znaky, které mají zvláštní význam v HTML pomocí Server.HtmlEncode. Pokud předáte řetězec dynamickému příkazu SQL, měli byste zakódovat různé znaky (nebo lépe, nechte to udělat rámec pro vás pomocí připravených příkazů nebo podobně).

Kdy jste si jisti, že HTML kódujete všude, kam předáte řetězce do HTML, pak nastavte validateRequest="false" ve směrnici <%@ Page ... %> ve vašem souboru .aspx.

V .NET 4 budete možná muset udělat něco víc. Někdy je také nutné přidat <httpRuntime requestValidationMode="2.0" /> do web.config ( reference ).

1028
JacquesB

Pokud používáte technologii ASP.NET MVC, je toto řešení odlišné.

Ukázka C #:

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

Ukázka jazyka:

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

V prostředí ASP.NET MVC (počínaje verzí 3) můžete přidat atribut AllowHtml atribut do vlastnosti v modelu.

Umožňuje požadavku zahrnout značení HTML během vazby modelu přeskakováním ověření platnosti požadavku.

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

Pokud používáte rozhraní .NET 4.0, ujistěte se, že jste tento soubor přidali do souboru web.config uvnitř značek <system.web>:

<httpRuntime requestValidationMode="2.0" />

V aplikaci .NET 2.0 bylo ověření požadavků použito pouze na požadavky aspx. V prostředí .NET 4.0 bylo rozšířeno o všechny požadavky. Při zpracování .aspx se můžete vrátit k pouze provádění ověření XSS zadáním:

requestValidationMode="2.0"

Požadavek validovat zcela můžete zakázat zadáním:

validateRequest="false"
206
JordanC

Pro prostředí ASP.NET 4.0 můžete povolit značení jako vstup pro určité stránky namísto celého webu tak, že jej vložíte do elementu <location>. Tím zajistíte, že všechny ostatní stránky budou v bezpečí. Nemusíte vkládat ValidateRequest="false" do vaší stránky .aspx.

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

To je bezpečnější kontrolovat to uvnitř vašeho web.config, protože vy můžete vidět na úrovni místa které strany dovolí značení jako vstup.

Stále musíte programově ověřit vstup na stránkách, kde je zakázáno ověření požadavku.

108
Carter Medlin

Předchozí odpovědi jsou skvělé, ale nikdo neřekl, jak vyloučit jedno pole z validace pro HTML/JavaScript injekce. Nevím o předchozích verzích, ale v MVC3 Beta to můžete udělat:

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

To stále potvrzuje všechna pole kromě vyloučené. Pěkná věc na tom je, že vaše validační atributy stále potvrzují pole, ale vy prostě nedostanete hodnotu „Potenciálně nebezpečná Request.Form byla zjištěna z výjimek klienta“.

Použil jsem to pro ověření regulárního výrazu. Udělal jsem vlastní ValidationAttribute, abych zjistil, zda je regulární výraz platný nebo ne. Protože regulární výrazy mohou obsahovat něco, co vypadá jako skript, který jsem použil výše uvedený kód - regulární výraz se stále kontroluje, pokud je platný nebo ne, ale ne, pokud obsahuje skripty nebo HTML.

70
gligoran

V prostředí ASP.NET MVC musíte nastavit webovou stránku requestValidationMode = "2.0" a validateRequest = "false" a do akce řadiče použít atribut ValidateInput:

<httpRuntime requestValidationMode="2.0"/>

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

a

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

Můžete HTML kódovat obsah textového pole, ale bohužel to nezastaví výjimku z děje. Podle mých zkušeností neexistuje žádná cesta kolem, a vy musíte zakázat ověřování stránek. Tím říkáte: "Budu opatrný, slibuji."

45
Pavel Chuchuva

Pro MVC ignorujte validaci vstupu přidáním 

[ValidateInput (false)]

nad každou akcí v kontroleru.

42
A.Dara

Tuto chybu můžete zachytit v Global.asax. Stále chci ověřit, ale zobrazit odpovídající zprávu. Na níže uvedeném blogu byl k dispozici takový vzorek. 

    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();
        }
    }

Přesměrování na jinou stránku také vypadá jako rozumná odpověď na výjimku.

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

41
BenMaddox

Mějte na paměti, že některé .NET ovládací prvky automaticky kódují výstup. Například nastavení vlastnosti .Text na ovládací prvek TextBox jej automaticky zakóduje. To konkrétně znamená převod < do &lt;, > do &gt; a & do &amp;. Takže buďte opatrní, když to děláte ...

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

Vlastnost .Text pro HyperLink, Literal a Label však HTML kódování věcí, takže obtékání Server.HtmlEncode (); kolem čehokoliv, co je nastaveno na těchto vlastnostech, je nutnost, pokud chcete zabránit tomu, aby <script> window.location = "http://www.google.com"; </script> vystupovalo na vaši stránku a následně bylo provedeno.

Udělejte trochu experimentování, abyste zjistili, co se zakóduje a co ne.

33
Dominic Pettifer

Odpověď na tuto otázku je jednoduchá:

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

To by zakázalo ověření pro konkrétní požadavek.

31
flakomalo

V souboru web.config v rámci tagů vložte prvek httpRuntime s atributem requestValidationMode = "2.0". Do elementu stránek také přidejte atribut validateRequest = "false".

Příklad:

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

Pokud nechcete zakázat funkci ValidateRequest, musíte provést funkci JavaScript, abyste se vyhnuli výjimce. Není to nejlepší volba, ale funguje to.

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;
    }
}

Potom v kódu za, na události PageLoad přidejte atribut do ovládacího prvku s dalším kódem:

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

Zdá se, že nikdo dosud neuvedl níže, ale opravuje to pro mě. A než někdo řekne, že je to Visual Basic ... yuck.

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

Nevím, jestli jsou nějaké nevýhody, ale pro mě to fungovalo úžasně.

20
Piercy

Dalším řešením je:

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

Pokud používáte framework 4.0, pak položka v souboru web.config (<pages validateRequest = "false" />)

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

Pokud používáte framework 4.5, pak záznam v souboru web.config (requestValidationMode = "2.0")

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

Pokud chcete pouze jednu stránku, měli byste v souboru aspx umístit první řádek takto:

<%@ Page EnableEventValidation="false" %>

pokud už máte něco jako <% @ Page, tak přidejte zbytek => EnableEventValidation="false"%>

Doporučuji to nedělat.

14
Durgesh Pandey

V prostředí ASP.NET můžete zachytit výjimku a udělat s ní něco, jako je zobrazení přátelské zprávy nebo přesměrování na jinou stránku ... Také existuje možnost, že ověření můžete provést sami ...

Zobrazit přátelskou zprávu:

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

Myslím, že to můžete udělat v modulu; ale ponechává otevřené některé otázky; co když chcete uložit vstup do databáze? Náhle proto, že ukládáte zakódovaná data do databáze, z toho nakonec důvěřujete, což je pravděpodobně špatný nápad. V ideálním případě ukládat surové unencoded data v databázi a kódování pokaždé.

Zakázání ochrany na úrovni stránky a kódování pokaždé je lepší volbou.

Spíše než pomocí Server.HtmlEncode byste se měli podívat na novější, úplnější Anti-XSS knihovnu z týmu Microsoft ACE.

12
blowdart

Další řešení zde jsou Nice, ale je to trochu královské bolesti vzadu, aby bylo nutné aplikovat [AllowHtml] na každý jednotlivý model majetku, zejména pokud máte více než 100 modelů na slušné velikosti stránky.

Pokud se mi líbí, chcete tuto funkci (IMHO docela nesmyslnou) vypnout z webu, můžete přepsat metodu Execute () ve vašem základním řadiči (pokud ještě nemáte základní ovladač, doporučuji, abyste si ho vytvořili, mohou být velmi užitečný pro použití běžných funkcí).

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

Jen se ujistěte, že jste HTML kódování všeho, co je čerpáno do zobrazení, která přišla z uživatelského vstupu (je to výchozí chování v ASP.NET MVC 3 s Razor stejně, takže pokud z nějakého bizarního důvodu používáte Html.Raw () by neměla tuto funkci vyžadovat.

10
magritte

Pokud opravdu potřebujete speciální znaky jako >, <, atd., Deaktivujte ověření stránky. Poté se ujistěte, že při zobrazení uživatelského vstupu jsou data kódována HTML. 

Při ověřování stránky je chyba zabezpečení, takže ji lze obejít. Také validace stránky by se neměla spoléhat pouze na.

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

9
woany

Způsobit

ASP.NET standardně ověřuje všechny vstupní ovládací prvky pro potenciálně nebezpečný obsah, který může vést k křížovému skriptování (XSS) a SQL injekcím . Takový obsah tak znemožňuje tím, že vyvolá výše uvedenou výjimku. Ve výchozím nastavení se doporučuje, aby se tato kontrola prováděla na každém zpětném hlášení.

Řešení

Při mnoha příležitostech je třeba odeslat obsah HTML na stránku prostřednictvím textových textových polí nebo editorů RTF. V tomto případě se můžete vyhnout této výjimce nastavením značky ValidateRequest v direktivě @Page na hodnotu false.

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

To zakáže ověření požadavků pro stránku, kterou jste nastavili na hodnotu ValidateRequest. Chcete-li tuto funkci vypnout, zkontrolujte v celé webové aplikaci. v sekci web.config <system.web> ji musíte nastavit na hodnotu false

<pages validateRequest ="false" />

Pro .NET 4.0 nebo vyšší frameworks budete muset také přidat následující řádek v sekci <system.web>, abyste provedli výše uvedenou práci.

<httpRuntime requestValidationMode = "2.0" />

A je to. Doufám, že vám to pomůže zbavit se výše uvedeného problému.

Odkaz: Chyba ASP.Net: potenciálně nebezpečná hodnota Request.Form byla zjištěna z klienta

9
vakeel

Našel jsem řešení, které používá JavaScript pro kódování dat, která jsou dekódována v .NET (a nevyžaduje jQuery).

  • Namísto ASP nastavte textové pole jako element HTML (jako textarea).
  • Přidat skryté pole.
  • Přidejte následující funkci JavaScript do záhlaví.

    function boo () { targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("uživatelská schránka" targetText.value = escape (sourceText.innerText); }

Do textarea zahrňte onchange, která volá boo ():

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

Nakonec, v .NET, použijte

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

Jsem si vědom (a), že se jedná o jednosměrnou cestu - pokud budete potřebovat obousměrnou cestu, budete muset získat kreativu, ale toto řešení poskytuje řešení, pokud nemůžete upravit web.config

Zde je příklad I (MC9000), který byl vytvořen a používán přes jQuery:

$(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
    });


});

A značení:

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

To funguje skvěle. Pokud se hacker pokouší posílat přes obejít JavaScript, uvidí chybu. Můžete také uložit všechna tato data zakódovaná do databáze, pak ji zrušit (na straně serveru) a před zobrazením jinde analyzovat a kontrolovat útoky.

9
Jason Shuler

Dostával jsem tuto chybu taky.

V mém případě uživatel zadal znak s diakritikou á v názvu role (týkající se poskytovatele členství ASP.NET).

Jméno role předávám metodě, která uděluje uživatelům tuto roli a požadavek $.ajax post selhal bídně ...

Udělal jsem to pro vyřešení problému:

Namísto

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

Udělej to

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

@Html.Raw udělal trik.

Dostal jsem jméno role jako hodnotu HTML roleName="Cadastro b&#225;s". Tato hodnota s entitou HTML &#225; byla blokována technologií ASP.NET MVC. Nyní dostanu hodnotu parametru roleName tak, jak by měla být: roleName="Cadastro Básico" a motor ASP.NET MVC požadavek již nezablokuje.

9

Také můžete použít funkci escape (string) jazyka JavaScript pro nahrazení speciálních znaků. Na straně serveru pak server přepne zpět na hodnotu Server . URLDecode (string) .

Tímto způsobem nemusíte vypnout ověření vstupu a bude jasnější pro ostatní programátory, že řetězec může mít obsah HTML.

7
Trisped

Před každým zpětným odesláním jsem zkontroloval znaky, které jste nechtěli, například:

<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;
}

Udělené mé stránce je většinou zadávání dat a existuje jen velmi málo prvků, které provádějí zpětné odeslání, ale alespoň jejich data zůstanou zachována.

6
Ryan

Pokud se jedná o pouze "<" a ">" (a nikoli o samotnou dvojitou uvozovku), znaky a používáte je v kontextu jako <input value = "this" />, vy 're safe (zatímco pro <textarea> this one </textarea> byste byli samozřejmě zranitelní). To může vaši situaci zjednodušit, ale pro cokoliv více použijte jedno z dalších řešení.

4
Paweł Hajdan

Pokud se právě snažíte říci svým uživatelům, že <a> nemají být používány VUT, nechcete, aby celý formulář zpracovávaný/odesílaný zpět (a ztratil veškerý vstup) předtím, než byste mohli jednoduše dát do Validator kolem pole na obrazovce pro ty (a možná i jiné potenciálně nebezpečné) postavy?

4
Captain Toad

Můžete použít něco jako:

var nvc = Request.Unvalidated().Form;

Později by nvc["yourKey"] mělo fungovat.

4
Ady Levy

Žádný z návrhů pro mě nepracoval. Nechtěl jsem tuto funkci vypnout pro celou webovou stránku, protože 99% času nechci, aby moji uživatelé umístili HTML na webové formuláře. Právě jsem vytvořil vlastní práci kolem metody, protože jsem jediný, kdo používá tuto konkrétní aplikaci. Převedu vstup do HTML v kódu za ním a vložte jej do mé databáze.

4
Mike S.

Můžete automaticky kódovat pole HTML ve vlastním modelu Binder. Moje řešení některé jiné, jsem dal chybu v ModelState a zobrazit chybové hlášení v blízkosti pole. Je snadné změnit tento kód pro automatické kódování 

 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);
        }
    }

V aplikaci Application_Start:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

Všimněte si, že funguje pouze pro pole formuláře. Nebezpečná hodnota není předána modelu regulátoru, ale uložena v ModelState a může být znovu zobrazena na formuláři s chybovým hlášením. 

Nebezpečné znaky v adrese URL mohou být zpracovány tímto způsobem:

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;
        }
    }
}

ChybaController: 

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

Měli byste použít metodu Server.HtmlEncode k ochraně webu před nebezpečným vstupem.

Více informací zde

3
bastos.sergio

Jak je uvedeno v mém komentáři k odpovědi - Selova odpověď , toto je naše rozšíření o validátor požadavku.

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

Pro ty, kteří nepoužívají model vazby, kteří jsou extrahování každý parametr z Request.Form, kteří jsou si jisti, že vstupní text způsobí žádné škody, existuje jiný způsob. Není to skvělé řešení, ale bude to fungovat. 

Z klientské strany jej zakódujte jako uri a odešlete.
např: 

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

Ze strany serveru jej akceptujte a dekódujte jako uri.
např: 

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

nebo 

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

podívejte se prosím na rozdíly mezi UrlDecode a UnescapeDataString

2
Wahid Masud

V neposlední řadě upozorňujeme, že ASP.NET Data Binding ovládá automaticky hodnoty encode během vazby dat. To změní výchozí chování všech ovládacích prvků ASP.NET (TextBox, Label atd.) Obsažených v ItemTemplate. Následující příklad ukazuje (ValidateRequest je nastaveno na hodnotu false):

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> 

kód za

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. Hodnota pro odeslání případu: &#39;

Label1.Text hodnota: &#39;

TextBox2.Text hodnota: &amp;#39;

  1. Hodnota předložení případu: <script>alert('attack!');</script>

Label1.Text hodnota: <script>alert('attack!');</script>

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

1
dpant

Pro ty z nás stále uvízl na webových formulářů jsem našel následující řešení, které vám umožní pouze zakázat ověření na jednom poli! (Nerad bych ho zakázal pro celou stránku.)

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);
    }
}

Nyní stačí použít <prefix:UnvalidatedTextBox id="test" runat="server" /> namísto <asp:TextBox a mělo by umožnit všechny znaky (toto je ideální pro pole s hesly!)

1
Peter

Vím, že tato otázka se týká zasílání formulářů, ale rád bych doplnil některé podrobnosti o lidech, kteří tuto chybu obdrželi za jiných okolností. Mohlo by také dojít na obslužném programu používaném k implementaci webové služby. 

Předpokládejme, že váš webový klient odešle požadavky POST nebo PUT pomocí ajax a pošle do vaší webové služby text json nebo xml nebo raw data (obsah souboru). Vzhledem k tomu, že vaše webová služba nemusí získat žádné informace z hlavičky typu Content-Type, váš kód JavaScript tento záhlaví nenastavil na vaši žádost ajax. Pokud však tento záhlaví nenastavíte na požadavek POST/PUT ajax, může Safari přidat toto záhlaví: "Content-Type: application/x-www-form-urlencoded". Zjistil jsem, že na Safari 6 na iPhone, ale ostatní verze Safari/OS nebo Chrome může udělat totéž. Takže při přijímání této záhlaví Content-Type některé části .NET Framework předpokládají, že struktura dat požadavku těla odpovídá odeslání formuláře html, zatímco není a vzrostla výjimka HttpRequestValidationException. První věc, kterou musíte udělat, je samozřejmě vždy nastavit Content-Type záhlaví na jakýkoliv jiný než formulářový MIME typ na POST/PUT ajax žádost, i když je to pro vaši webovou službu zbytečné.

Také jsem objevil tento detail:
Za těchto okolností je výjimka HttpRequestValidationException zvýšena, když se kód pokusí o přístup ke kolekci HttpRequest.Params. Překvapivě však tato výjimka není zvýšena, když přistupuje ke kolekci HttpRequest.ServerVariables. To ukazuje, že zatímco tyto dvě sbírky se zdají být téměř identické, přistupuje k datům požadavku prostřednictvím bezpečnostních kontrol a druhá ne.

1
figolu

V .Net 4.0 a dále, což je obvyklý případ, vložte následující nastavení do system.web

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

v mém případě pomocí asp: Textbox control (Asp.net 4.5) namísto nastavení celé stránky pro validateRequest="false"

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

na textovém poli, které způsobilo výjimku.

0
maozx

Použít Server.HtmlEncode("yourtext");

0
Voigt

Vidím, že o tom je hodně napsáno ... a toto jsem neviděl. Toto je k dispozici od .NET Framework 4.5

ValidateRequestMode nastavení pro ovládací prvek je skvělá volba. Tímto způsobem jsou ostatní ovládací prvky na stránce stále chráněny. Nejsou potřeba žádné změny web.config.

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