0% acharam este documento útil (0 voto)
3 visualizações20 páginas

03 - SQL Injection

A injeção de SQL é uma vulnerabilidade que permite a agentes maliciosos interferirem nos comandos SQL enviados ao banco de dados, possibilitando acesso a dados restritos ou a corrupção do banco. Isso ocorre quando a entrada do usuário não é devidamente tratada, permitindo que comandos SQL sejam injetados. Para prevenir essa vulnerabilidade, recomenda-se o uso de comandos SQL parametrizados e a limitação das entradas de dados.

Enviado por

guilhermehoegen
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
3 visualizações20 páginas

03 - SQL Injection

A injeção de SQL é uma vulnerabilidade que permite a agentes maliciosos interferirem nos comandos SQL enviados ao banco de dados, possibilitando acesso a dados restritos ou a corrupção do banco. Isso ocorre quando a entrada do usuário não é devidamente tratada, permitindo que comandos SQL sejam injetados. Para prevenir essa vulnerabilidade, recomenda-se o uso de comandos SQL parametrizados e a limitação das entradas de dados.

Enviado por

guilhermehoegen
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Injeção de SQL

(SQL Injection)
CWE-89: Improper Neutralization of
Special Elements used in an
SQL Command ('SQL Injection')
Injeção de SQL (SQL Injection)

• Agentes podem interferir nos comandos enviados ao banco


de dados pela aplicação, alterando a lógica de consultas para
obter dados que deveriam ser inacessíveis ou corromper o
banco de dados.

• Ocorre quando acessos ao banco de dados dependem da


entrada de dados pelo usuário.

• Quando a entrada de dados contém o caractere apóstrofo (‘),


a entrada do usuário pode ser interpretada como comando
SQL, ao invés de dados do usuário.
Injeção de SQL (SQL Injection)

Considerar uma aplicação que requer autenticação:


String sql = "SELECT * FROM USUARIOS" +
" WHERE LOGIN = '" + [Link]() +
"' AND PASSWORD = '" + [Link]() + "'";
try (Statement stmt = [Link]()) {
ResultSet rs = [Link](sql);
if (![Link]()) {
throw new UserInvalidException();
}

User user = new User();


[Link] = [Link]("login");
[Link] = [Link]("id");
return user;
} catch (SQLException e) {
[Link]();
}

Comando enviado SELECT * FROM USUARIOS


WHERE LOGIN = 'gilvanj@[Link]'
ao banco: AND PASSWORD = '1234567'
Injeção de SQL (SQL Injection)

Agora, considerar a seguinte entrada de dados


Sendo a instrução que cria o comando:
String sql = "SELECT * FROM USUARIOS" +
" WHERE LOGIN = '" + [Link]() +
"' AND PASSWORD = '" + [Link]() + "'";

Comando enviado ao banco:


SELECT * FROM USUARIOS
WHERE LOGIN = 'gilvanj@[Link]'; --'
AND PASSWORD = '1234567'

Ou seja, será executado:


SELECT * FROM USUARIOS
WHERE LOGIN = 'gilvanj@[Link]';
Injeção de SQL (SQL Injection)

Outra entrada possível:

Sendo a instrução que envia o comando:


String sql = "SELECT * FROM USUARIOS" +
" WHERE LOGIN = '" + [Link]() +
"' AND PASSWORD = '" + [Link]() + "'";

Esta entrada cria o seguinte comando SQL:


SELECT * FROM USUARIOS
WHERE LOGIN = 'a' or 1=1 --'
AND PASSWORD = '1234567'

Ou seja, será executado:


SELECT * FROM USUARIOS
WHERE LOGIN = 'a' or 1=1
Injeção de SQL (SQL Injection)
Considerar esta modelagem:

E uma aplicação para listar as folhas de pagamento do usuário corrente:


Sendo este o comando para listar a folha de pagamento:
String comando = "select * from folha_pagamento" +
" where funcionario_id = " +
getCurrentUser().getFuncionario().getId() +
" and competencia = '01/" + data + "'";

Esta entrada cria o seguinte comando SQL:


select * from folha_pagamento where funcionario_id = 2 and
competencia = '01/10/2021'
Injeção de SQL (SQL Injection)
Com esta entrada:
String comando = "select valor_bruto, valor_descontos" +
" from folha_pagamento" +
" where funcionario_id = " +
getCurrentUser().getFuncionario().getId() +
" and competencia = '01/" + data + "'";

10/2021’ or 1=1 --

Seria executado:
select valor_bruto, valor_descontos from folha_pagamento where funcionario_id = 2
and competencia = '01/10/2021' or 1=1--'
Injeção de SQL (SQL Injection)
Considerar esta entrada de dados:

a’; DELETE FROM USUARIOS; --

Esta entrada cria o seguinte comando SQL:


SELECT * FROM USUARIOS
WHERE LOGIN = 'a'; DELETE FROM USUARIOS; --'
AND PASSWORD = ''

Isto é, são executados estes comandos:


SELECT * FROM USUARIOS WHERE LOGIN = 'a';
DELETE FROM USUARIOS;
Injeção de SQL (SQL Injection)
Numa aplicação web, se a pilha de execução for retornada para o frontend, o
agente pode se aproveitar deste comportamento.
String comando = "select valor_bruto, valor_descontos" +
" from folha_pagamento" +
" where funcionario_id = " +
getCurrentUser().getFuncionario().getId() +
" and competencia = '01/" + data + "'";
Injeção de SQL (SQL Injection)

Foi acrescentado group by valor_bruto

(having 1=1 não precisa mais manter)


Injeção de SQL (SQL Injection)

Uma vez que se conhece a estrutura da tabela, o agente pode


alterar estruturas do banco de dados:

A API em Java aplica a alteração no


banco de dados, mas lança uma
; update folha_pagamento set valor_bruto = 8888 -- exceção.
[Link]: ResultSets múltiplos foram retornados pela consulta.
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]$0([Link])
at [Link]/[Link]([Link])
at [Link]/[Link]$[Link]([Link])
at [Link]/[Link]([Link])
Injeção de SQL (SQL Injection)

O agente pode também tentar utilizar comandos DDL (Data


definition language) para comprometer o banco de dados.

; drop table folha_pagamento; --

A API em Java aplica a alteração


no banco de dados, embora
lance uma exceção.
Injeção de SQL (SQL Injection)

• Um web site que permite listar dados de um pedido executa:


String comando = "SELECT * FROM PEDIDO WHERE ID = " +
[Link]("id");
ResultSet rs = [Link](comando);

• Exemplo de chamada esperada:


[Link]

• Ao chamar o web site poderia ser informado:


[Link] DATABASE DB

• O comando que será executado é:


SELECT * FROM PEDIDO WHERE ID = 15362;
DROP DATABASE DB
Injeção de SQL

• Exibir a pilha de execução para o usuário final pode introduzir um risco de


segurança em potencial.

• Por isso, é uma boa prática de desenvolvimento de sistema seguro:

Nunca expor detalhes do erro, tal como a pilha de


execução, aos usuários finais

• A pilha de execução deveria ser apresentada apenas em arquivos de log.

– Apresentar apenas mensagens amigáveis ao usuário final

• Esta vulnerabilidade está documentada no CWE-209 (Generation of Error


Message Containing Sensitive Information)
Injeção de SQL (SQL Injection)

• Os impactos com a injeção com SQL podem ser:


– Confidencialidade – Possibilita a leitura de dados que o usuário não
deveria ter acesso
– Integridade – É possível fazer alterações ou exclusão de informações
– Disponibilidade – Ao corromper estruturas de dados que
impossibilitem aos demais usuários de utilizar a aplicação
Injeção de SQL (SQL Injection)

O SGBD da Microsoft possui stored procedures que dão acesso a


funcionalidades fora do banco de dados:
• XP_CMDSHELL – Executa um comando da linha de comando
• XP_REGREAD – Lê chaves do registro do Windows
• XP_SERVICECONTROL – Acesso aos serviços
Recomendações para evitar injeção de SQL

• Limitar as entradas de dados,


– Através de lista branca: para impedir caracteres especiais
• Aceitar apenas os caracteres considerados válidos, recusando os demais
caracteres

• O usuário de banco de dados da aplicação deve possuir


privilégios reduzidos e que impeçam a execução de comandos
DDL .

• Utilizar comandos SQL parametrizados.


Parametrizar comandos SQL
Acesso sem usar comando parametrizado:
String sql = "SELECT * FROM USUARIOS" +
" WHERE LOGIN = '" + [Link]() +
"' AND PASSWORD = '" + [Link]() + "'";
try (Statement stmt = [Link]()) {
ResultSet rs = [Link](sql);
if ([Link]()) {
return true;
}
} catch (SQLException e) {
[Link]();
}

Acesso usando comando parametrizado:


String sql = "SELECT * FROM USUARIOS WHERE LOGIN = ? AND PASSWORD = ?";
try (PreparedStatement stmt = [Link](sql)) {
[Link](1, [Link]());
[Link](2, [Link]());
ResultSet rs = [Link]();
if ([Link]()) {
return true;
}
} catch (SQLException e) {
[Link]();
}
Parametrizar comandos SQL

Ao utilizar pesquisas parametrizadas, primeiro o comando é


enviado ao banco (sem valores absolutos de parâmetros).

"SELECT * FROM USUARIOS WHERE LOGIN = ? AND PASSWORD = ?"

gilvanj@[Link]’;-- (string vazia)


Injeção de SQL (SQL Injection)

• Comandos que utilizam o operador like podem receber


injeção de caracteres curingas (%, _).

• Em 2011, a prática de injeção de SQL foi responsável por


comprometer sistemas de organizações como Sony Pictures,
PBS, [Link] entre outras.

Você também pode gostar