Quadro de segurança: Validação de entrada | Atenuações
Desabilitar scripts XSLT para todas as transformações usando folhas de estilo não confiáveis
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Segurança XSLT, propriedade XsltSettings.EnableScript |
Passos | XSLT suporta scripts dentro de folhas de estilo usando o <msxml:script> elemento . Isso permite que funções personalizadas sejam usadas em uma transformação XSLT. O script é executado sob o contexto do processo que executa a transformação. O script XSLT deve ser desabilitado quando estiver em um ambiente não confiável para impedir a execução de código não confiável. Se estiver usando o .NET: o script XSLT está desabilitado por padrão, no entanto, você deve garantir que ele não tenha sido explicitamente habilitado por meio da XsltSettings.EnableScript propriedade. |
Exemplo
XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false
Exemplo
Se você estiver usando o MSXML 6.0, o script XSLT será desabilitado por padrão; no entanto, você deve garantir que ele não tenha sido explicitamente habilitado por meio da propriedade de objeto DOM XML AllowXsltScript.
doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false
Exemplo
Se você estiver usando o MSXML 5 ou inferior, o script XSLT está habilitado por padrão e você deve desativá-lo explicitamente. Defina a propriedade do objeto DOM XML AllowXsltScript como false.
doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.
Certifique-se de que cada página que possa conter conteúdo controlável pelo usuário desative a deteção automática de MIME
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Segurança do IE8 Parte V - Proteção abrangente |
Passos | Para cada página que possa conter conteúdo controlável pelo usuário, você deve usar o cabeçalho Cada tipo de arquivo entregue a partir de um servidor Web tem um tipo MIME associado (também chamado de tipo de conteúdo) que descreve a natureza do conteúdo (ou seja, imagem, texto, aplicativo, etc.) O cabeçalho X-Content-Type-Options é um cabeçalho HTTP que permite aos desenvolvedores especificar que seu conteúdo não deve ser detetado por MIME. Este cabeçalho foi projetado para mitigar ataques MIME-Sniffing. Suporte para este cabeçalho foi adicionado no Internet Explorer 8 (IE8) Somente os usuários do Internet Explorer 8 (IE8) se beneficiarão do X-Content-Type-Options. Versões anteriores do Internet Explorer atualmente não respeitam o cabeçalho X-Content-Type-Options O Internet Explorer 8 (e posterior) são os únicos navegadores importantes a implementar um recurso de desativação de deteção de MIME. Se e quando outros navegadores importantes (Firefox, Safari, Chrome) implementarem recursos semelhantes, esta recomendação será atualizada para incluir sintaxe para esses navegadores também |
Exemplo
Para habilitar o cabeçalho necessário globalmente para todas as páginas do aplicativo, siga um destes procedimentos:
- Adicione o cabeçalho no arquivo web.config se o aplicativo estiver hospedado pelo IIS (Serviços de Informações da Internet) 7
<system.webServer>
<httpProtocol>
<customHeaders>
<add name=""X-Content-Type-Options"" value=""nosniff""/>
</customHeaders>
</httpProtocol>
</system.webServer>
- Adicione o cabeçalho através do Application_BeginRequest global
void Application_BeginRequest(object sender, EventArgs e)
{
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
}
- Implementar módulo HTTP personalizado
public class XContentTypeOptionsModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += newEventHandler(context_PreSendRequestHeaders);
}
#endregion
void context_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
if (application == null)
return;
if (application.Response.Headers[""X-Content-Type-Options ""] != null)
return;
application.Response.Headers.Add(""X-Content-Type-Options "", ""nosniff"");
}
}
- Você pode habilitar o cabeçalho necessário somente para páginas específicas adicionando-o a respostas individuais:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
Proteger ou desativar a resolução de entidade XML
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Expansão de entidade XML, Ataques e defesas de negação de serviço XML, Visão geral de segurança do MSXML, práticas recomendadas para proteger o código MSXML, referência do protocolo NSXMLParserDelegate, resolução de referências externas |
Passos | Embora não seja amplamente utilizado, há um recurso do XML que permite que o analisador XML expanda entidades de macro com valores definidos dentro do próprio documento ou de fontes externas. Por exemplo, o documento pode definir uma entidade "companyname" com o valor "Microsoft", de modo que sempre que o texto "&companyname;" aparecer no documento, ele seja automaticamente substituído pelo texto Microsoft. Ou, o documento pode definir uma entidade "MSFTStock" que faz referência a um serviço Web externo para buscar o valor atual do estoque da Microsoft. Em seguida, sempre que "&MSFTStock;" aparece no documento, ele é automaticamente substituído pelo preço atual das ações. No entanto, essa funcionalidade pode ser abusada para criar condições de negação de serviço (DoS). Um invasor pode aninhar várias entidades para criar uma bomba XML de expansão exponencial que consome toda a memória disponível no sistema. Como alternativa, ele pode criar uma referência externa que transmite uma quantidade infinita de dados ou que simplesmente trava o thread. Como resultado, todas as equipes devem desabilitar totalmente a resolução de entidade XML interna e/ou externa se seu aplicativo não usá-la, ou limitar manualmente a quantidade de memória e o tempo que o aplicativo pode consumir para a resolução da entidade, se essa funcionalidade for absolutamente necessária. Se a resolução de entidade não for exigida pelo seu aplicativo, desative-a. |
Exemplo
Para o código do .NET Framework, você pode usar as seguintes abordagens:
XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
// for .NET 4
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);
Observe que o valor padrão de ProhibitDtd
in é true, mas in XmlTextReader
XmlReaderSettings
é false. Se você estiver usando XmlReaderSettings, você não precisa definir ProhibitDtd como true explicitamente, mas é recomendado por uma questão de segurança que você faça. Observe também que a classe XmlDocument permite a resolução de entidade por padrão.
Exemplo
Para desabilitar a resolução de entidade para XmlDocuments, use a sobrecarga do método Load e defina as propriedades apropriadas no argumento XmlReader para desabilitar a resolução, conforme ilustrado no código a XmlDocument.Load(XmlReader)
seguir:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
Exemplo
Se a desativação da resolução de entidade não for possível para seu aplicativo, defina a propriedade XmlReaderSettings.MaxCharactersFromEntities para um valor razoável de acordo com as necessidades do seu aplicativo. Isso limitará o impacto de potenciais ataques DoS de expansão exponencial. O código a seguir fornece um exemplo dessa abordagem:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);
Exemplo
Se você precisar resolver entidades embutidas, mas não precisar resolver entidades externas, defina a propriedade XmlReaderSettings.XmlResolver como null. Por exemplo:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);
Observe que no MSXML6, ProhibitDTD é definido como true (desabilitando o processamento DTD) por padrão. Para o código Apple OSX/iOS, há dois analisadores XML que você pode usar: NSXMLParser e libXML2.
Aplicativos que utilizam http.sys executam verificação de canonicalização de URL
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | N/A |
Passos | Qualquer aplicativo que use http.sys deve seguir estas diretrizes:
|
Certifique-se de que os controles apropriados estejam em vigor ao aceitar arquivos de usuários
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Carregamento irrestrito de ficheiros, Tabela de assinaturas de ficheiros |
Passos | Os ficheiros carregados representam um risco significativo para as aplicações. O primeiro passo em muitos ataques é obter algum código para o sistema a ser atacado. Em seguida, o ataque só precisa encontrar uma maneira de executar o código. Usar um upload de arquivo ajuda o invasor a realizar a primeira etapa. As consequências do upload irrestrito de arquivos podem variar, incluindo a aquisição completa do sistema, um sistema de arquivos ou banco de dados sobrecarregado, ataques de encaminhamento para sistemas back-end e desfiguração simples. Depende do que o aplicativo faz com o arquivo carregado e, especialmente, onde ele está armazenado. A validação do lado do servidor dos carregamentos de ficheiros está em falta. Os seguintes controlos de segurança devem ser implementados para a funcionalidade de Carregamento de Ficheiros:
|
Exemplo
Para obter o último ponto sobre a validação de assinatura de formato de arquivo, consulte a classe abaixo para obter detalhes:
private static Dictionary<string, List<byte[]>> fileSignature = new Dictionary<string, List<byte[]>>
{
{ ".DOC", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } } },
{ ".DOCX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
{ ".PDF", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
{ ".ZIP", new List<byte[]>
{
new byte[] { 0x50, 0x4B, 0x03, 0x04 },
new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x55 },
new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
new byte[] { 0x50, 0x4B, 0x05, 0x06 },
new byte[] { 0x50, 0x4B, 0x07, 0x08 },
new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 }
}
},
{ ".PNG", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
{ ".JPG", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 }
}
},
{ ".JPEG", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 }
}
},
{ ".XLS", new List<byte[]>
{
new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
new byte[] { 0xFD, 0xFF, 0xFF, 0xFF }
}
},
{ ".XLSX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
{ ".GIF", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } }
};
public static bool IsValidFileExtension(string fileName, byte[] fileData, byte[] allowedChars)
{
if (string.IsNullOrEmpty(fileName) || fileData == null || fileData.Length == 0)
{
return false;
}
bool flag = false;
string ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
{
return false;
}
ext = ext.ToUpperInvariant();
if (ext.Equals(".TXT") || ext.Equals(".CSV") || ext.Equals(".PRN"))
{
foreach (byte b in fileData)
{
if (b > 0x7F)
{
if (allowedChars != null)
{
if (!allowedChars.Contains(b))
{
return false;
}
}
else
{
return false;
}
}
}
return true;
}
if (!fileSignature.ContainsKey(ext))
{
return true;
}
List<byte[]> sig = fileSignature[ext];
foreach (byte[] b in sig)
{
var curFileSig = new byte[b.Length];
Array.Copy(fileData, curFileSig, b.Length);
if (curFileSig.SequenceEqual(b))
{
flag = true;
break;
}
}
return flag;
}
Certifique-se de que os parâmetros de segurança de tipo sejam usados no Aplicativo Web para acesso a dados
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | N/A |
Passos | Se você usar a coleção Parameters, o SQL tratará a entrada como um valor literal em vez de como código executável. A coleção Parameters pode ser usada para impor restrições de tipo e comprimento nos dados de entrada. Valores fora do intervalo acionam uma exceção. Se os parâmetros SQL seguros para tipos não forem usados, os invasores poderão executar ataques de injeção incorporados na entrada não filtrada. Use parâmetros seguros de tipo ao construir consultas SQL para evitar possíveis ataques de injeção de SQL que podem ocorrer com entrada não filtrada. Você pode usar parâmetros seguros de tipo com procedimentos armazenados e com instruções SQL dinâmicas. Os parâmetros são tratados como valores literais pelo banco de dados e não como código executável. Os parâmetros também são verificados quanto ao tipo e comprimento. |
Exemplo
O código a seguir mostra como usar parâmetros seguros de tipo com o SqlParameterCollection ao chamar um procedimento armazenado.
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
No exemplo de código anterior, o valor de entrada não pode ser maior do que 11 caracteres. Se os dados não estiverem em conformidade com o tipo ou comprimento definido pelo parâmetro, a classe SqlParameter lançará uma exceção.
Use classes de vinculação de modelo separadas ou listas de filtros de vinculação para evitar a vulnerabilidade de atribuição em massa do MVC
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | MVC5, MVC6 |
Atributos | N/A |
Referências | Atributos de metadados, Vulnerabilidade e mitigação de segurança de chave pública, Guia completo para atribuição em massa no MVC ASP.NET, Introdução ao EF usando MVC |
Passos |
|
Codifique saídas da Web não confiáveis antes da renderização
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, Web Forms, MVC5, MVC6 |
Atributos | N/A |
Referências | Como evitar scripts entre sites no ASP.NET, Scripts entre sites, XSS (Cross Site Scripting) Prevenção Cheat Sheet |
Passos | O script entre sites (comumente abreviado como XSS) é um vetor de ataque para serviços online ou qualquer aplicativo/componente que consome entrada da Web. As vulnerabilidades XSS podem permitir que um invasor execute scripts na máquina de outro usuário por meio de um aplicativo Web vulnerável. Scripts maliciosos podem ser usados para roubar cookies e, de outra forma, adulterar a máquina de uma vítima através de JavaScript. O XSS é impedido validando a entrada do usuário, garantindo que ela esteja bem formada e codificando antes de ser processada em uma página da Web. A validação de entrada e a codificação de saída podem ser feitas usando a Biblioteca de Proteção da Web. Para código gerenciado (C#, VB.NET, etc.), use um ou mais métodos de codificação apropriados da Biblioteca de Proteção da Web (Anti-XSS), dependendo do contexto em que a entrada do usuário é manifestada: |
Exemplo
* Encoder.HtmlEncode
* Encoder.HtmlAttributeEncode
* Encoder.JavaScriptEncode
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode
* Encoder.XmlEncode
* Encoder.XmlAttributeEncode
* Encoder.CssEncode
* Encoder.LdapEncode
Executar validação de entrada e filtragem em todas as propriedades do modelo de tipo de cadeia de caracteres
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, MVC5, MVC6 |
Atributos | N/A |
Referências | Adicionando validação, validando dados de modelo em um aplicativo MVC, princípios orientadores para seus aplicativos MVC ASP.NET |
Passos | Todos os parâmetros de entrada devem ser validados antes de serem usados no aplicativo para garantir que o aplicativo seja protegido contra entradas de usuários mal-intencionados. Valide os valores de entrada usando validações de expressão regular no lado do servidor com uma estratégia de validação de lista permitida. Entradas/parâmetros de usuário não higienizados passados para os métodos podem causar vulnerabilidades de injeção de código. Para aplicativos Web, os pontos de entrada também podem incluir campos de formulário, QueryStrings, cookies, cabeçalhos HTTP e parâmetros de serviço Web. As seguintes verificações de validação de entrada devem ser realizadas após a vinculação do modelo:
|
A higienização deve ser aplicada em campos de formulário que aceitam todos os caracteres, por exemplo, editor de rich text
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Codificar entrada não segura, HTML Sanitizer |
Passos | Identifique todas as marcas de marcação estáticas que você deseja usar. Uma prática comum é restringir a formatação a elementos HTML seguros, como Antes de gravar os dados, codifice-os HTML. Isso torna qualquer script mal-intencionado seguro, fazendo com que ele seja tratado como texto, não como código executável.
A página nas referências desativa ASP.NET validação de solicitação definindo HtmlSanitizer é uma biblioteca .NET para limpar fragmentos HTML e documentos de construções que podem levar a ataques XSS. Ele usa o AngleSharp para analisar, manipular e renderizar HTML e CSS. O HtmlSanitizer pode ser instalado como um pacote NuGet, e a entrada do usuário pode ser passada através de métodos de limpeza HTML ou CSS relevantes, conforme aplicável, no lado do servidor. Por favor, note que a higienização como um controle de segurança deve ser considerada apenas como uma última opção. A validação de entrada e a codificação de saída são consideradas melhores controles de segurança. |
Não atribua elementos DOM a coletores que não tenham codificação incorporada
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | N/A |
Passos | Muitas funções JavaScript não fazem codificação por padrão. Ao atribuir entrada não confiável a elementos DOM por meio de tais funções, pode resultar em execuções de script entre sites (XSS). |
Exemplo
Seguem-se exemplos inseguros:
document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);
Não use, em vez disso, use innerHtml
innerText
. Da mesma forma, em vez de $("#elm").html()
, use $("#elm").text()
Valide se todos os redirecionamentos dentro do aplicativo estão fechados ou feitos com segurança
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | A estrutura de autorização do OAuth 2.0 - Redirecionadores abertos |
Passos | O design do aplicativo que requer redirecionamento para um local fornecido pelo usuário deve restringir os possíveis destinos de redirecionamento a uma lista "segura" predefinida de sites ou domínios. Todos os redirecionamentos no aplicativo devem ser fechados/seguros. Para:
|
Implementar validação de entrada em todos os parâmetros de tipo de cadeia de caracteres aceitos pelos métodos Controller
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, MVC5, MVC6 |
Atributos | N/A |
Referências | Validando dados de modelo em um aplicativo MVC, princípios orientadores para seus aplicativos MVC ASP.NET |
Passos | Para métodos que aceitam apenas o tipo de dados primitivo, e não modelos como argumento, a validação de entrada usando Expressão Regular deve ser feita. Aqui Regex.IsMatch deve ser usado com um padrão regex válido. Se a entrada não corresponder à Expressão Regular especificada, o controle não deve prosseguir e um aviso adequado sobre falha de validação deve ser exibido. |
Definir o tempo limite superior para o processamento de expressões regulares para evitar DoS devido a expressões regulares incorretas
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, Web Forms, MVC5, MVC6 |
Atributos | N/A |
Referências | Propriedade DefaultRegexMatchTimeout |
Passos | Para garantir ataques de negação de serviço contra expressões regulares mal criadas, que causam muitos retrocessos, defina o tempo limite padrão global. Se o tempo de processamento demorar mais do que o limite superior definido, isso lançará uma exceção de tempo limite. Se nada estiver configurado, o tempo limite será infinito. |
Exemplo
Por exemplo, a configuração a seguir lançará um RegexMatchTimeoutException, se o processamento demorar mais de 5 segundos:
<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />
Evite usar Html.Raw em visualizações do Razor
Cargo | Detalhes |
---|---|
Componente | Aplicação Web |
Fase SDL | Criar |
Tecnologias aplicáveis | MVC5, MVC6 |
Atributos | N/A |
Referências | N/A |
Passo | ASP.NET WebPages (Razor) executam codificação HTML automática. Todas as cadeias de caracteres impressas por nuggets de código incorporado (@ blocks) são automaticamente codificadas em HTML. No entanto, quando HtmlHelper.Raw o método é invocado, ele retorna a marcação que não é codificada em HTML. Se Html.Raw() o método auxiliar for usado, ele ignorará a proteção de codificação automática que o Razor fornece. |
Exemplo
Segue-se um exemplo inseguro:
<div class="form-group">
@Html.Raw(Model.AccountConfirmText)
</div>
<div class="form-group">
@Html.Raw(Model.PaymentConfirmText)
</div>
</div>
Não utilize Html.Raw()
a menos que necessite de apresentar marcação. Este método não executa a codificação de saída implicitamente. Use outros auxiliares de ASP.NET, por exemplo, @Html.DisplayFor()
Não use consultas dinâmicas em procedimentos armazenados
Cargo | Detalhes |
---|---|
Componente | Base de dados |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | N/A |
Passos | Um ataque de injeção de SQL explora vulnerabilidades na validação de entrada para executar comandos arbitrários no banco de dados. Isso pode ocorrer quando seu aplicativo usa entrada para construir instruções SQL dinâmicas para acessar o banco de dados. Isso também pode ocorrer se o código usar procedimentos armazenados que são passados cadeias de caracteres que contêm entrada bruta do usuário. Usando o ataque de injeção de SQL, o invasor pode executar comandos arbitrários no banco de dados. Todas as instruções SQL (incluindo as instruções SQL em procedimentos armazenados) devem ser parametrizadas. As instruções SQL parametrizadas aceitarão caracteres que têm significado especial para SQL (como aspas simples) sem problemas porque são fortemente tipados. |
Exemplo
Segue-se um exemplo de Procedimento Armazenado dinâmico inseguro:
CREATE PROCEDURE [dbo].[uspGetProductsByCriteria]
(
@productName nvarchar(200) = NULL,
@startPrice float = NULL,
@endPrice float = NULL
)
AS
BEGIN
DECLARE @sql nvarchar(max)
SELECT @sql = ' SELECT ProductID, ProductName, Description, UnitPrice, ImagePath' +
' FROM dbo.Products WHERE 1 = 1 '
PRINT @sql
IF @productName IS NOT NULL
SELECT @sql = @sql + ' AND ProductName LIKE ''%' + @productName + '%'''
IF @startPrice IS NOT NULL
SELECT @sql = @sql + ' AND UnitPrice > ''' + CONVERT(VARCHAR(10),@startPrice) + ''''
IF @endPrice IS NOT NULL
SELECT @sql = @sql + ' AND UnitPrice < ''' + CONVERT(VARCHAR(10),@endPrice) + ''''
PRINT @sql
EXEC(@sql)
END
Exemplo
A seguir está o mesmo procedimento armazenado implementado com segurança:
CREATE PROCEDURE [dbo].[uspGetProductsByCriteriaSecure]
(
@productName nvarchar(200) = NULL,
@startPrice float = NULL,
@endPrice float = NULL
)
AS
BEGIN
SELECT ProductID, ProductName, Description, UnitPrice, ImagePath
FROM dbo.Products where
(@productName IS NULL or ProductName like '%'+ @productName +'%')
AND
(@startPrice IS NULL or UnitPrice > @startPrice)
AND
(@endPrice IS NULL or UnitPrice < @endPrice)
END
Certifique-se de que a validação do modelo seja feita em métodos de API da Web
Cargo | Detalhes |
---|---|
Componente | API da Web |
Fase SDL | Criar |
Tecnologias aplicáveis | MVC5, MVC6 |
Atributos | N/A |
Referências | Validação de modelo em ASP.NET API Web |
Passos | Quando um cliente envia dados para uma API da Web, é obrigatório validar os dados antes de fazer qualquer processamento. Para ASP.NET APIs da Web que aceitam modelos como entrada, use anotações de dados em modelos para definir regras de validação nas propriedades do modelo. |
Exemplo
O código a seguir demonstra o mesmo:
using System.ComponentModel.DataAnnotations;
namespace MyApi.Models
{
public class Product
{
public int Id { get; set; }
[Required]
[RegularExpression(@"^[a-zA-Z0-9]*$", ErrorMessage="Only alphanumeric characters are allowed.")]
public string Name { get; set; }
public decimal Price { get; set; }
[Range(0, 999)]
public double Weight { get; set; }
}
}
Exemplo
No método de ação dos controladores de API, a validade do modelo deve ser explicitamente verificada, conforme mostrado abaixo:
namespace MyApi.Controllers
{
public class ProductsController : ApiController
{
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
// Do something with the product (not shown).
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
}
}
Implementar a validação de entrada em todos os parâmetros de tipo de cadeia de caracteres aceitos pelos métodos da API da Web
Cargo | Detalhes |
---|---|
Componente | API da Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, MVC 5, MVC 6 |
Atributos | N/A |
Referências | Validando dados de modelo em um aplicativo MVC, princípios orientadores para seus aplicativos MVC ASP.NET |
Passos | Para métodos que aceitam apenas o tipo de dados primitivo, e não modelos como argumento, a validação de entrada usando Expressão Regular deve ser feita. Aqui Regex.IsMatch deve ser usado com um padrão regex válido. Se a entrada não corresponder à Expressão Regular especificada, o controle não deve prosseguir e um aviso adequado sobre falha de validação deve ser exibido. |
Certifique-se de que os parâmetros de segurança de tipo sejam usados na API da Web para acesso a dados
Cargo | Detalhes |
---|---|
Componente | API da Web |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | N/A |
Passos | Se você usar a coleção Parameters, o SQL tratará a entrada como um valor literal em vez de como código executável. A coleção Parameters pode ser usada para impor restrições de tipo e comprimento nos dados de entrada. Valores fora do intervalo acionam uma exceção. Se os parâmetros SQL seguros para tipos não forem usados, os invasores poderão executar ataques de injeção incorporados na entrada não filtrada. Use parâmetros seguros de tipo ao construir consultas SQL para evitar possíveis ataques de injeção de SQL que podem ocorrer com entrada não filtrada. Você pode usar parâmetros seguros de tipo com procedimentos armazenados e com instruções SQL dinâmicas. Os parâmetros são tratados como valores literais pelo banco de dados e não como código executável. Os parâmetros também são verificados quanto ao tipo e comprimento. |
Exemplo
O código a seguir mostra como usar parâmetros seguros de tipo com o SqlParameterCollection ao chamar um procedimento armazenado.
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
No exemplo de código anterior, o valor de entrada não pode ser maior do que 11 caracteres. Se os dados não estiverem em conformidade com o tipo ou comprimento definido pelo parâmetro, a classe SqlParameter lançará uma exceção.
Usar consultas SQL parametrizadas para o Azure Cosmos DB
Cargo | Detalhes |
---|---|
Componente | Banco de Dados de Documentos do Azure |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico |
Atributos | N/A |
Referências | Anunciando a parametrização SQL no Azure Cosmos DB |
Passos | Embora o Azure Cosmos DB ofereça suporte apenas a consultas somente leitura, a injeção de SQL ainda é possível se as consultas forem construídas concatenando com a entrada do usuário. Pode ser possível que um usuário obtenha acesso a dados que não deveria estar acessando dentro da mesma coleção criando consultas SQL mal-intencionadas. Use consultas SQL parametrizadas se as consultas forem construídas com base na entrada do usuário. |
Validação de entrada do WCF por meio da vinculação de esquema
Cargo | Detalhes |
---|---|
Componente | WCF |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, NET Framework 3 |
Atributos | N/A |
Referências | MSDN |
Passos | A falta de validação leva a diferentes tipos de ataques de injeção. A validação de mensagem representa uma linha de defesa na proteção do seu aplicativo WCF. Com essa abordagem, você valida mensagens usando esquemas para proteger as operações do serviço WCF contra ataques de um cliente mal-intencionado. Valide todas as mensagens recebidas pelo cliente para protegê-lo de ataques de um serviço mal-intencionado. A validação de mensagens torna possível validar mensagens quando as operações consomem contratos de mensagens ou contratos de dados, o que não pode ser feito usando validação de parâmetros. A validação de mensagens permite criar lógica de validação dentro de esquemas, proporcionando mais flexibilidade e reduzindo o tempo de desenvolvimento. Os esquemas podem ser reutilizados em diferentes aplicativos dentro da organização, criando padrões para representação de dados. Além disso, a validação de mensagens permite proteger as operações quando elas consomem tipos de dados mais complexos envolvendo contratos que representam a lógica de negócios. Para executar a validação de mensagens, primeiro crie um esquema que represente as operações do seu serviço e os tipos de dados consumidos por essas operações. Em seguida, você cria uma classe .NET que implementa um inspetor de mensagens de cliente personalizado e um inspetor de mensagens de despachante personalizado para validar as mensagens enviadas/recebidas de/para o serviço. Em seguida, implemente um comportamento de ponto de extremidade personalizado para habilitar a validação de mensagens no cliente e no serviço. Finalmente, você implementa um elemento de configuração personalizado na classe que permite expor o comportamento do ponto de extremidade personalizado estendido no arquivo de configuração do serviço ou do cliente" |
WCF- Validação de entrada através de inspetores de parâmetros
Cargo | Detalhes |
---|---|
Componente | WCF |
Fase SDL | Criar |
Tecnologias aplicáveis | Genérico, NET Framework 3 |
Atributos | N/A |
Referências | MSDN |
Passos | A validação de entrada e dados representa uma importante linha de defesa na proteção do seu aplicativo WCF. Você deve validar todos os parâmetros expostos nas operações de serviço WCF para proteger o serviço contra ataques de um cliente mal-intencionado. Por outro lado, você também deve validar todos os valores de retorno recebidos pelo cliente para protegê-lo de ataques de um serviço mal-intencionado O WCF fornece diferentes pontos de extensibilidade que permitem personalizar o comportamento de tempo de execução do WCF criando extensões personalizadas. Os Inspetores de Mensagens e os Inspetores de Parâmetros são dois mecanismos de extensibilidade usados para obter maior controle sobre os dados que passam entre um cliente e um serviço. Você deve usar inspetores de parâmetros para validação de entrada e usar inspetores de mensagens somente quando precisar inspecionar toda a mensagem que entra e sai de um serviço. Para executar a validação de entrada, você criará uma classe .NET e implementará um inspetor de parâmetros personalizado para validar parâmetros em operações em seu serviço. Em seguida, você implementará um comportamento de ponto de extremidade personalizado para habilitar a validação no cliente e no serviço. Finalmente, você implementará um elemento de configuração personalizado na classe que permite expor o comportamento do ponto de extremidade personalizado estendido no arquivo de configuração do serviço ou do cliente |