Que personagens são realmente capazes de causar a injecção de SQL em mysql

todos sabemos que devemos usar declarações preparadas ou as regras de substituição/formatação apropriadas para evitar a injecção de sql em nossas aplicações.

No entanto, ao dar uma olhada na lista de literais de caracteres de MySQL, notei que ela inclui os seguintes caracteres:

  • {[1] } um carácter ASCII NUL (0x00).
  • \' um único carácter de citação (').
  • {[5] } uma citação dupla (") personagem.
  • Um personagem de backspace.
  • \n um personagem newline (linefeed).
  • Um carriage return character.
  • \t um carácter tab.
  • \Z ASCII 26 (Ctrl+Z ). Ver nota a seguir ao quadro.
  • \\ um carácter backslash (\).
  • \% um carácter %.
  • \_ um carácter _.
Agora, enquanto os % e _ caracteres precisa ser escapada, a fim de evitar a injeção de indesejados curingas em declarações, e enquanto o ' (plicas), \ (barra invertida), e " (aspas duplas), todos precisam ser encerradas a fim de evitar a injeção de SQL arbitrária - poderia ter qualquer um desses outros caracteres de escape levam directamente a uma vulnerabilidade de injecção de SQL que de outra forma não estariam presentes? Alguém tem exemplos reais de tal façanha?

Vamos assumir que estamos a construir a nossa pergunta:
SELECT * FROM users WHERE username='$user'

existe algum valor para $user onde o único escape de caracteres literais são \b (backspace), \0 (NUL), \n (newline), \r (alimentação de linha) \t (guia) ou \Z (Ctrl+Z) que permite a injeção de SQL arbitrários para esta consulta?

Author: Yves M., 2013-01-17

2 answers

Considerando as linhas abaixo de mysql_real_escape_string () manual:

O MySQL requer apenas que a barra invertida e o carácter de aspas usado para citar o texto da consulta sejam escapados. o mysql_real_ escape_string () cita os outros caracteres para os tornar mais fáceis de ler nos ficheiros de Registo.

A injecção de SQL em MySQL não deve ser possível com estes caracteres especiais sozinhos.: \b \0 \n \r \t \Z .

No entanto, o manual de Literatura de texto indica o seguinte, mas as razões especificadas (ou não ) não estão relacionadas com a injecção de SQL:

Se quiser inserir dados binários numa coluna de texto (como uma coluna BLOB), deverá representar certos caracteres por sequências de escape. A barra invertida ( " \ " ) e o carácter de citação usado para citar o texto devem ser escapados. Em certos ambientes de clientes, também pode ser necessário escapar NUL ou controlar + Z. o mysql cliente trunca cadeias de caracteres cotadas que contêm caracteres NUL se não escaparem, e o controlo+Z pode ser tomado para o fim do ficheiro no Windows se não for escapado.

Além disso , num teste simples , independentemente do tempo, os caracteres especiais acima indicados escaparam ou não, o MySQL deu os mesmos resultados . Em outras palavras, MySQL nem se importou:

$query_sql = "SELECT * FROM `user` WHERE user = '$user'";

A consulta acima funcionou de forma semelhante para versões não-escapadas e evadidas dos caracteres acima listados como se coloca abaixo:

$user = chr(8);     // Back Space
$user = chr(0);     // Null char
$user = chr(13);    // Carriage Return
$user = chr(9);     // Horizontal Tab
$user = chr(26);    // Substitute
$user = chr(92) .chr(8);    // Escaped Back Space
$user = chr(92) .chr(0);    // Escaped Null char
$user = chr(92) .chr(13);   // Escaped Carriage Return
$user = chr(92) .chr(9);    // Escaped Horizontal Tab
$user = chr(92) .chr(26);   // Escaped Substitute

Tabela de ensaios e dados utilizados no teste simples:

-- Table Structure

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(10) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

-- Table Data

INSERT INTO `user` ( `user` ) VALUES
( char( '8' ) ),
( char( '0' ) ),
( char( '10' ) ),
( char( '13' ) ),
( char( '9' ) ),
( char( '26' ) );
 3
Author: Uours, 2013-10-26 13:18:51
Não existem tais personagens. Há duas afirmações erradas na sua pergunta que o levam a confundir:
    Todos sabemos que devemos usar ... as regras de substituição apropriadas para evitar a injeção de sql em nossas aplicações.
Isto é uma afirmação errada. Não é Substituição, Mas formatação . É essencial. As substituições não protegem contra injecções, enquanto a formatação o faz. Note que cada parte distinta da consulta requeira diferente formatação que é inútil para qualquer outra parte. Existe, por exemplo, um outro carácter, essencial para a protecção contra a injecção - um backtick (`). Mas não a listou porque não tem nada a ver com literais de cordas.
  1. O '(citação única), \ (barra invertida) e " (aspas duplas) todos precisam de ser escapados para evitar a injecção
Esta afirmação está muito errada. escapar não previne injecções! Estes caracteres precisam ser escapados a fim de formatar strings e não tem absolutamente nada a ver com injeções. Embora seja verdade que a parte da consulta formatada corretamente é invulnerável contra a injeção. Mas a verdade é - você tem que formatar partes da consulta dinâmica apenas por causa dela, para seguir regras de sintaxe - não por causa de quaisquer injeções. E você terá sua consulta impenetrável como consequência.

Agora podes ver porque é que a tua última declaração,

Porquê tudo destes outros personagens são vulneráveis o suficiente para serem escapados através de mysql_real_escape_string, já que não é imediatamente óbvio para mim.

Foi erradamente colocado:
É as regras de formatação de string requerem estes caracteres, não qualquer "vulnerabilidade". Alguns deles são escapados apenas por conveniência, alguns por legibilidade, alguns por razões óbvias de escapar de um delimitador. Só isso.

Para responder a perguntas recentes de comentários:

Quero uma resposta para isto, pois O mysql_ real_ escape_string do PHP também não cita estes literais.

De novo: embora na mente do utilizador médio de PHP {[[0]} esteja fortemente ligado a qualquer injecção de sustos, na realidade não está. nunca existem personagens "perigosos". Nem um único. Existem alguns personagens de serviço com significado especial. Eles têm que ser escapados em algumas circunstâncias, depende do contexto.

Assim, não há ligação entre os personagens escapados por isto. função, e qualquer"perigo". No momento em que você começa a pensar que o propósito de {[[0]} é escapar de personagens "perigosos", você está realmente se tornando em perigo. Enquanto estiver a usar esta função apenas para escapar a cadeias de caracteres (e fazê - lo incondicionalmente) - poderá considerar-se seguro (claro, se não se esquecer de formatar todos os outros literais também, usando as respectivas regras de formatação) {[[6]}

Quero saber se o carácter " % " pode levar a algo mais do que extra resulta numa cláusula semelhante.

Não.
 4
Author: Your Common Sense, 2013-10-26 09:38:11