Um valor Request.Form potencialmente perigoso foi detectado no cliente

1471

Sempre que um usuário publica algo que contenha <ou >em uma página no meu aplicativo da Web, eu recebo essa exceção.

Não quero entrar na discussão sobre a esperteza de lançar uma exceção ou travar um aplicativo Web inteiro porque alguém inseriu um caractere em uma caixa de texto, mas estou procurando uma maneira elegante de lidar com isso.

Interceptando a exceção e mostrando

Ocorreu um erro. Volte e digite novamente todo o formulário, mas desta vez não use <

não parece profissional o suficiente para mim.

Desabilitar a pós-validação ( validateRequest="false") definitivamente evitará esse erro, mas deixará a página vulnerável a vários ataques.

Idealmente: quando ocorrer uma postagem com caracteres restritos em HTML, esse valor publicado na coleção Form será automaticamente codificado em HTML. Portanto, a .Textpropriedade da minha caixa de texto serásomething & lt; html & gt;

Existe uma maneira de fazer isso de um manipulador?

Radu094
fonte
68
Observe que você pode obter esse erro se tiver nomes de entidades HTML (& amp;) ou números de entidades (& # 39;) em sua entrada também.
de Drew Noakes
18
Bem, como é minha pergunta, sinto que posso definir qual é realmente o ponto: travar um processo de aplicativo inteiro e retornar uma mensagem de erro genérica porque alguém digitou '<' é um exagero. Especialmente porque você sabe que a maioria das pessoas simplesmente 'validateRequest = false' para se livrar dela, reabrindo assim a vulnerabilidade
Radu094 18/14
7
@DrewNoakes: os nomes das entidades (& amp;) não parecem ser um problema de acordo com os meus testes (testados no .Net 4.0), embora os números das entidades (& # 39;) falhem na validação (como você disse). Se você desmontar o método System.Web.CrossSiteScriptingValidation.IsDangerousString usando o .Net Reflector, verá que o código procura especificamente tags html (começando com <) e números de entidade (começando com & #)
Gyum Fox
5
Crie um novo site no VS2014 usando o projeto MVC padrão e execute-o. Clique no link de registro, adicione qualquer email e use "<P455-0r [!" como a senha. Mesmo erro imediato, sem tentar fazer nada malicioso, o campo da senha não será exibido, portanto não será um ataque XSS, mas a única maneira de corrigi-lo é remover completamente a validação com o ValidateInput (false) ? A sugestão AllowHtml não funciona nessa situação, ainda explodiu com o mesmo erro. Um valor Request.Form potencialmente perigoso foi detectado no cliente (Senha = "<P455-0r [!").
26515 stephenbayer
TL; DR colocado <httpRuntime requestValidationMode="2.0" />em web.config

Respostas:

1080

Eu acho que você está atacando do ângulo errado, tentando codificar todos os dados publicados.

Observe que um " <" também pode vir de outras fontes externas, como um campo de banco de dados, uma configuração, um arquivo, um feed e assim por diante.

Além disso, " <" não é inerentemente perigoso. Só é perigoso em um contexto específico: ao escrever strings que não foram codificadas na saída HTML (por causa do XSS).

Em outros contextos, as sub-strings diferentes são perigosas, por exemplo, se você gravar um URL fornecido pelo usuário em um link, a sub-string " javascript:" pode ser perigosa. O caractere de aspas simples, por outro lado, é perigoso ao interpolar seqüências de caracteres em consultas SQL, mas é perfeitamente seguro se fizer parte de um nome enviado de um formulário ou lido de um campo de banco de dados.

A linha inferior é: você não pode filtrar entradas aleatórias para caracteres perigosos, porque qualquer caractere pode ser perigoso nas circunstâncias corretas. Você deve codificar no ponto em que alguns caracteres específicos podem se tornar perigosos porque eles se cruzam para um sub-idioma diferente, onde possuem significado especial. Ao escrever uma seqüência de caracteres em HTML, você deve codificar caracteres com significado especial em HTML, usando Server.HtmlEncode. Se você passar uma string para uma instrução SQL dinâmica, codifique caracteres diferentes (ou melhor, deixe a estrutura fazer isso por você usando instruções preparadas ou similares).

Quando você tiver certeza de que codifica HTML em todos os lugares em que passa as strings para HTML, defina validateRequest="false"a <%@ Page ... %>diretiva no .aspx(s) arquivo (s).

No .NET 4, você pode precisar fazer um pouco mais. Às vezes é necessário adicionar também <httpRuntime requestValidationMode="2.0" />ao web.config ( referência ).

JacquesB
fonte
74
Para aqueles que chegam atrasados: validateRequest = "false" entra na diretiva de Página (primeira linha do seu arquivo .aspx)
MGOwen 20/10/10
56
Dica: Coloque <httpRuntime requestValidationMode="2.0" />uma tag de local para evitar a proteção útil fornecida pela validação do restante do site.
Brian
298
No MVC3, isso está [AllowHtml]na propriedade model.
Jeremy Holovacs 09/09/11
2
Para desativá-lo globalmente para o MVC 3, você também precisa GlobalFilters.Filters.Add(new ValidateInputAttribute(false));do Application_Start().
18712 Alex
15
@MGOwen você também pode adicionar a diretiva de página ao web.config via <pages validateRequest="false" />in <system.web />. Fazer isso aplicará a propriedade a todas as páginas.
Oliver-clare
504

Existe uma solução diferente para esse erro se você estiver usando o ASP.NET MVC:

Amostra C #:

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

Exemplo do Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
Zack Peterson
fonte
o problema pode surgir quando for necessário em uma página de todo o aplicativo
3
Você também pode adicionar o atributo [ValidateInput (false)] no nível da classe. Se você adicioná-lo à sua classe de controlador base, ele será aplicado a todas as ações do método do controlador.
Shan Plourde 29/05
@ Zack Obrigado pela solução. Por outro lado, estou me perguntando se [AllowHtml]é melhor que ValidateInput(false), porque [AllowHtml]é definido imediatamente para uma propriedade, ou seja, campo Editor, e sempre que é usado, não há necessidade de usá-lo para várias ações. O que você sugere?
Jack
@Zack Peterson É seguro usar? Nenhum problema de segurança?
Shrey Pav
417

No ASP.NET MVC (iniciando na versão 3), você pode adicionar o AllowHtmlatributo a uma propriedade no seu modelo.

Ele permite que uma solicitação inclua a marcação HTML durante a ligação do modelo ignorando a validação da solicitação da propriedade.

[AllowHtml]
public string Description { get; set; }
Anthony Johnston
fonte
12
Muito melhor fazer isso declarativamente do que no controlador!
Andiih 9/03/12
29
A única resposta correta! desativar a validação na ação do controlador é hacky. E para desativar a validação no nível do aplicativo, os desenvolvedores devem ser interrompidos!
TRAILMAX
Isso desapareceu no MVC 4?
granadaCoder
1
Qual é a diferença entre ValidateInput(false)e AllowHtml? Qual é a vantagem de um sobre o outro? Quando eu gostaria de usar em AllowHtmlvez de ValidateInput(false)? Em que eu quero usar ValidateInput(false)mais AllowHtml? Quando eu gostaria de usar os dois? Faz sentido usar os dois?
23616 Ian Boyd
3
ValidateInput está no método, AllowHtml está na propriedade do modelo - assim você só permitir que a pessoa que você espera ter html - não todos
Anthony Johnston
213

Se você estiver no .NET 4.0, adicione isso no seu arquivo web.config dentro das <system.web>tags:

<httpRuntime requestValidationMode="2.0" />

No .NET 2.0, a validação de solicitação é aplicada apenas a aspxsolicitações. No .NET 4.0, isso foi expandido para incluir todas as solicitações. Você pode reverter para apenas executar a validação XSS ao processar .aspx, especificando:

requestValidationMode="2.0"

Você pode desativar totalmente a validação de solicitação especificando:

validateRequest="false"
JordanC
fonte
30
Dentro das <system.web>tags.
Hosam Aly
8
Coloquei isso no web.config, mas ainda com o erro "Um valor Request.Form potencialmente perigoso"
Filip
20
Parece que <httpRuntime requestValidationMode = "2.0" /> funciona apenas quando a estrutura 2.0 está instalada na máquina. E se a estrutura 2.0 não estiver instalada, mas apenas a estrutura 4.0 estiver instalada?
Samuel
Isso funcionou totalmente para mim. Nenhuma das etapas do documento nas outras respostas foi necessária (incluindo validateRequest = "false")!
tom Redfern
112

Para o ASP.NET 4.0, você pode permitir a marcação como entrada para páginas específicas, em vez de todo o site, colocando tudo em um <location>elemento. Isso garantirá que todas as suas outras páginas estejam seguras. Você NÃO precisa colocar ValidateRequest="false"na sua página .aspx.

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

É mais seguro controlar isso dentro do seu web.config, porque você pode ver no nível do site quais páginas permitem a marcação como entrada.

Você ainda precisa validar programaticamente a entrada nas páginas em que a validação de solicitação está desativada.

Carter Medlin
fonte
Mais informações sobre requestValidationMode = 2 | 4 aqui: msdn.microsoft.com/en-us/library/…
GlennG
Infelizmente, isso não funcionará com o ASP.net 2.0 como está. Remova a linha httpRuntime e ela funcionará.
Fandango68
Eu adicionei um aviso lembrando as pessoas para validar manualmente a entrada quando a validação está desativada.
Carter Medlin
72

As respostas anteriores são ótimas, mas ninguém disse como excluir um único campo da validação de injeções de HTML / JavaScript. Eu não sei sobre versões anteriores, mas no MVC3 Beta você pode fazer isso:

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

Isso ainda valida todos os campos, exceto o excluído. O bom disso é que seus atributos de validação ainda validam o campo, mas você simplesmente não recebe as exceções "Um valor Request.Form potencialmente perigoso foi detectado no cliente".

Eu usei isso para validar uma expressão regular. Eu fiz meu próprio ValidationAttribute para ver se a expressão regular é válida ou não. Como expressões regulares podem conter algo que se parece com um script, apliquei o código acima - a expressão regular ainda está sendo verificada se é válida ou não, mas não se contém scripts ou HTML.

gligoran
fonte
10
Infelizmente, parece que o recurso Excluir foi removido do MVC 3 RTW :(
Matt Greer
2
Também não foi incluído no MVC 4
wilsjd 27/06/2013
9
Use [AllowHtml]nas propriedades do modelo em vez de [ValidateInput]na Ação para obter o mesmo resultado final.
Mrchief
2
@Christof Note que minha resposta é de 5 anos. Não me deparei com esse problema há muito tempo, então pode haver maneiras muito melhores de lidar com ele. Em relação a essas duas opções, acho que depende da sua situação. Talvez você exponha esse modelo em mais de uma ação e, em alguns lugares, o HTML seja permitido ou não. Nesse caso, [AllowHtml]não é uma opção. Eu recomendo verificar este artigo: weblogs.asp.net/imranbaloch/… , mas também é um pouco antigo e pode estar desatualizado.
gligoran
1
Ainda existe uma maneira de excluir parâmetros de métodos específicos da validação, confira minha resposta aqui: stackoverflow.com/a/50796666/56621 #
Alex
51

No ASP.NET MVC, você precisa definir requestValidationMode = "2.0" e validateRequest = "false" no web.config e aplicar um atributo ValidateInput à sua ação do controlador:

<httpRuntime requestValidationMode="2.0"/>

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

e

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
ranthonissen
fonte
2
Para mim, validateRequest="false"não era necessário, apenas #requestValidationMode="2.0"
red redn
requestValidationMode = "2.0" ainda gera o erro com dados codificados em HTML. Nenhuma solução, exceto a base64, codifica tudo e envia-a junto.
MC9000
48

Você pode codificar em HTML o conteúdo da caixa de texto, mas infelizmente isso não impedirá que a exceção aconteça. Na minha experiência, não há maneira de contornar, e você precisa desativar a validação da página. Ao fazer isso, você está dizendo: "Terei cuidado, prometo".

Pavel Chuchuva
fonte
43

Para MVC, ignore a validação de entrada adicionando

[ValidateInput (false)]

acima de cada ação no controlador.

A.Dara
fonte
Isso não parece funcionar no caso de chegar ao método do controlador por meio de uma rota configurada.
PandaWood 24/03
Na verdade, a explicação técnica, é que isso só funciona quando o personagem ofender está na "string de consulta" ... se ele está no caminho da solicitação, atributo de validação não faz trabalho
PandaWood
42

Você pode capturar esse erro no Global.asax. Ainda quero validar, mas mostre uma mensagem apropriada. No blog listado abaixo, uma amostra como esta estava disponível.

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

Redirecionar para outra página também parece ser uma resposta razoável à exceção.

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

BenMaddox
fonte
40

A resposta a esta pergunta é simples:

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

Isso desabilitaria a validação para a solicitação específica.

flakomalo
fonte
1
Aplicável apenas ao ASP.NET 4.5 (e, presumivelmente, o que vier depois). O Pre 4.5 não suporta isso.
Beska
3
Eu gostaria de poder subir dessa maneira. Estou usando o .NET 4.5 e é exatamente isso que eu precisava, pois não estou usando o MVC e não posso alterar o web.config.
precisa
1
Sim, mas e se você estiver usando o .Net 2? Alguns de nós não têm escolha
Fandango68
isso obtém parâmetros POST ou GET?
precisa saber é
Você está dizendo que isso impede uma exceção que já foi lançada? Ou o .net 4.5 atrasa a exceção e a validação até que os dados sejam realmente lidos a partir do Request?
ebyrob
34

Lembre-se de que alguns controles .NET codificarão automaticamente a saída em HTML. Por exemplo, definir a propriedade .Text em um controle TextBox a codificará automaticamente. Isso significa especificamente converter <em &lt;, >em &gt;e &em &amp;. Portanto, tenha cuidado ao fazer isso ...

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

No entanto, a propriedade .Text para HyperLink, Literal e Label não codificará as coisas, portanto, agrupando Server.HtmlEncode (); qualquer coisa que esteja sendo definida nessas propriedades é essencial se você deseja impedir <script> window.location = "http://www.google.com"; </script>que a saída seja enviada para sua página e posteriormente executada.

Faça uma pequena experiência para ver o que é codificado e o que não é.

Peter Mortensen
fonte
29

No arquivo web.config, nas tags, insira o elemento httpRuntime com o atributo requestValidationMode = "2.0". Adicione também o atributo validateRequest = "false" no elemento pages.

Exemplo:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
Mahdi jokar
fonte
1
Para mim, validateRequest = "false" não era necessário, apenas requestValidationMode = "2.0"
tom redfern
3
A seção "páginas" deve estar dentro da seção "system.web".
Carter Medlin
resposta perigosa, mais uma vez.
MC9000
Eu precisava dos dois. Obrigado
Jack
23

Se você não deseja desativar o ValidateRequest, precisa implementar uma função JavaScript para evitar a exceção. Não é a melhor opção, mas funciona.

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

Em seguida, no código por trás, no evento PageLoad, adicione o atributo ao seu controle com o próximo código:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
Peter Mortensen
fonte
4
Isso ainda deixará o aplicativo vulnerável a solicitações POST inventadas. Um usuário comum terá problemas para inserir caracteres como:: ou aspas, mas um hacker comum não terá problemas para POSTAR dados malformados para o servidor. Eu vodificaria esse caminho.
Radu094 26/10/09
13
@ Radu094: Esta solução permite que você mantenha ValidateRequest = true, o que significa que os hackers ainda atingirão esse muro. Vote para cima, pois isso deixa você menos vulnerável do que desativar o ValidateRequest.
precisa saber é o seguinte
21

Parece que ninguém mencionou o abaixo ainda, mas isso resolve o problema para mim. E antes que alguém diga sim, é Visual Basic ... eca.

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

Não sei se existem desvantagens, mas para mim isso foi incrível.

Piercy
fonte
Obras de formulários web c # ou VB
TheAlbear
19

Outra solução é:

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;
    }
}
Sel
fonte
Agradável! Não tinha conhecimento da capacidade de substituir o Validador de solicitação. Em vez de apenas dizer "ok" como você, estendi essa ideia para não validar os campos que terminam em "_NoValidation" como o nome. Código abaixo.
Walden Leverich
Walden Leverich, para fazer isso, veja [AllowHtml] attribure
Sel
Sim, sim, em um ambiente MVC que funcionaria. Mas em um aplicativo de formulários da web, não tenho um modelo para fazer isso. :-)
Walden Leverich
15

Se você estiver usando a estrutura 4.0, a entrada no web.config (<pages validateRequest = "false" />)

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

Se você estiver usando a estrutura 4.5, a entrada no web.config (requestValidationMode = "2.0")

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

Se você deseja apenas uma única página, no arquivo aspx, você deve colocar a primeira linha como esta:

<%@ Page EnableEventValidation="false" %>

se você já tem algo como <% @ Page, adicione o restante => EnableEventValidation="false" %>

Eu recomendo não fazer isso.

Durgesh Pandey
fonte
13

No ASP.NET, você pode capturar a exceção e fazer algo a respeito, como exibir uma mensagem amigável ou redirecionar para outra página ... Além disso, existe a possibilidade de lidar com a validação sozinho ...

Exibir mensagem amigável:

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

Eu acho que você poderia fazer isso em um módulo; mas isso deixa em aberto algumas perguntas; e se você quiser salvar a entrada em um banco de dados? De repente, porque você está salvando dados codificados no banco de dados, acaba confiando na entrada dele, o que provavelmente é uma má idéia. Idealmente, você armazena dados não codificados brutos no banco de dados e na codificação sempre.

Desabilitar a proteção em um nível por página e depois codificar cada vez é uma opção melhor.

Em vez de usar Server.HtmlEncode, verifique a biblioteca Anti-XSS mais nova e completa da equipe do Microsoft ACE.

blowdart
fonte
12

Causa

Por padrão, o ASP.NET valida todos os controles de entrada para conteúdos potencialmente inseguros que podem levar a scripts entre sites (XSS) e injeções de SQL . Portanto, ele não permite esse conteúdo, lançando a exceção acima. Por padrão, é recomendável permitir que essa verificação ocorra em cada postagem.

Solução

Em muitas ocasiões, você precisa enviar conteúdo HTML para sua página por meio de Rich TextBoxes ou Rich Text Editors. Nesse caso, você pode evitar essa exceção definindo a tag ValidateRequest na @Pagediretiva como false.

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

Isso desativará a validação de solicitações para a página em que você definiu o sinalizador ValidateRequest como false. Se você deseja desativar isso, verifique em todo o aplicativo da web; você precisará configurá-lo como false na seção web.config <system.web>

<pages validateRequest ="false" />

Para estruturas .NET 4.0 ou superiores, você também precisará adicionar a seguinte linha na seção <system.web> para fazer o trabalho acima.

<httpRuntime requestValidationMode = "2.0" />

É isso aí. Espero que isso ajude você a se livrar da questão acima.

Referência por: ASP.Net Erro: Um valor Request.Form potencialmente perigoso foi detectado no cliente

vakeel
fonte
10

Encontrei uma solução que usa JavaScript para codificar os dados, que é decodificado no .NET (e não requer jQuery).

  • Torne a caixa de texto um elemento HTML (como textarea) em vez de um ASP.
  • Adicione um campo oculto.
  • Adicione a seguinte função JavaScript ao seu cabeçalho.

    função boo () {targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("userbox"); targetText.value = escape (sourceText.innerText); }

Na sua área de texto, inclua uma alteração que chame boo ():

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

Por fim, no .NET, use

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

Estou ciente de que é unidirecional - se você precisar de duas vias, precisará ser criativo, mas isso fornece uma solução se você não pode editar o web.config

Aqui está um exemplo que eu (MC9000) criei e usei via 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
    });


});

E a marcação:

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

Isso funciona muito bem. Se um hacker tentar postar através do JavaScript, ele verá o erro. Você também pode salvar todos esses dados codificados em um banco de dados e, em seguida, desencaixá-los (no lado do servidor) e analisar e verificar se há ataques antes de exibir em outro local.

Jason Shuler
fonte
Esta é uma boa solução. É uma forma manual adequado para controlar a si mesmo e não invalida todo o site ou página
Fandango68
Certifique-se de usar uma marcação HTML, não um controle ASP.Net (por exemplo, sem runat = "server") para a área de texto e use o controle oculto do ASP.Net para o oculto. Esta é a melhor solução que eu já vi sem comprometer nada. Naturalmente, você deseja analisar seus dados para XSS, SQL Injection no lado do servidor, mas pelo menos pode postar HTML
MC9000 13/15
escape(...)pode demorar muito tempo. No meu caso, a marcação foi um arquivo XML inteiro (2 MB). Você pode perguntar: "Por que você não usa <input type="file"...e ... eu concordo com você :) #
The Red Pea
10

As outras soluções aqui são ótimas, no entanto, é um pouco doloroso na parte traseira ter que aplicar [AllowHtml] a todas as propriedades Model, especialmente se você tiver mais de 100 modelos em um site de tamanho decente.

Se como eu, você deseja desativar esse recurso (IMHO, sem sentido) fora do local, você pode substituir o método Execute () no seu controlador de base (se você ainda não tiver um controlador de base, sugiro que faça um, eles podem ser bastante útil para aplicar funcionalidades comuns).

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

Apenas verifique se você está codificando em HTML tudo o que é bombeado para as visualizações que vieram da entrada do usuário (de qualquer maneira, é o comportamento padrão do ASP.NET MVC 3 com Razor, a menos que, por algum motivo bizarro, você esteja usando Html.Raw (), não deve exigir esse recurso.

magritte
fonte
9

Eu também estava recebendo esse erro.

No meu caso, um usuário inseriu um caractere acentuado áem um Nome da função (referente ao provedor de associação do ASP.NET).

Eu passo o nome da função para um método para conceder aos usuários essa função e a $.ajaxsolicitação de postagem estava falhando miseravelmente ...

Eu fiz isso para resolver o problema:

Ao invés de

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

Faça isso

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

@Html.Raw fez o truque.

Eu estava recebendo o nome da função como valor HTML roleName="Cadastro b&#225;s". Este valor com a entidade HTML &#225;estava sendo bloqueado pelo ASP.NET MVC. Agora eu recebo o roleNamevalor do parâmetro da maneira que deveria ser: roleName="Cadastro Básico"e o mecanismo ASP.NET MVC não bloqueará mais a solicitação.

Leniel Maccaferri
fonte
9

Desativar a validação da página se você realmente precisa os caracteres especiais como, >,, <, etc. Em seguida, garantir que, quando a entrada do usuário é exibido, os dados é codificado em HTML.

Há uma vulnerabilidade de segurança na validação da página, para que possa ser ignorada. Também não se deve confiar apenas na validação da página.

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

woany
fonte
O link está quebrado.
Peter Mortensen
7

Você também pode usar a função de escape (string) do JavaScript para substituir os caracteres especiais. Em seguida, no lado do servidor, use Server. URLDecode (string) para alternar novamente.

Dessa forma, você não precisa desativar a validação de entrada e ficará mais claro para outros programadores que a string pode ter conteúdo HTML.

Trisped
fonte
7

Acabei usando JavaScript antes de cada postagem para verificar os caracteres que você não queria, como:

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

Concedido que minha página é principalmente entrada de dados, e há muito poucos elementos que fazem postbacks, mas pelo menos seus dados são retidos.

Ryan
fonte
Deve haver colchetes grandes em vez de colchetes pequenos. Como `if (tbs [i] .type == 'text') {` no lugar de `if (tbs (i) .type == 'text') {`
Shilpa Soni
5

Você pode usar algo como:

var nvc = Request.Unvalidated().Form;

Mais tarde, nvc["yourKey"]deve funcionar.

Ady Levy
fonte
Obrigado, sua resposta economizou muito do meu tempo
habib
4

Desde que sejam apenas caracteres "<" e ">" (e não as próprias aspas duplas) e você os esteja usando em contextos como <input value = " this " />, você estará seguro (enquanto que para <textarea > este </textarea> você seria vulnerável, é claro). Isso pode simplificar sua situação, mas, para algo mais, use uma das outras soluções publicadas.

Paweł Hajdan
fonte
4

Se você está apenas querendo dizer aos seus usuários que <e> não devem ser usados, MAS, você não deseja que todo o formulário seja processado / postado de volta (e perca toda a entrada) antecipadamente, você não pode simplesmente colocar um validador ao redor do campo para rastrear esses caracteres (e talvez outros potencialmente perigosos)?

Capitão Sapo
fonte
post disse "validador" por favor
mxmissile 06/02
4

Nenhuma das sugestões funcionou para mim. Eu não queria desativar esse recurso para todo o site, porque 99% do tempo não quero que meus usuários coloquem HTML em formulários da web. Acabei de criar meu próprio método de trabalho, pois sou o único a usar esse aplicativo em particular. Eu converto a entrada para HTML no código por trás e a insiro no meu banco de dados.

Mike S.
fonte