Observação: este é um post convidado de Brant Burnett de Software CenterEdgeA empresa desenvolve POS e software especializado para os setores de parques de diversões, lazer e entretenimento.

Visão geral

O N1QL é uma nova ferramenta incrivelmente poderosa que ajudará a levar os bancos de dados NoSQL a um grupo maior de desenvolvedores com uma curva de aprendizado muito menor. Isso ajudará os desenvolvedores a criar aplicativos avançados, robustos e de alto desempenho com mais rapidez e facilidade do que nunca. Porém, com qualquer nova tecnologia, a área de superfície para os hackers atacarem é inerentemente maior.

A injeção de SQL é uma falha de segurança bem conhecida, comumente encontrada em aplicativos baseados em SQL, e tem sido muito bem documentada ao longo dos anos. Então, como o N1QL se compara ao SQL em termos de segurança? O N1QL também é vulnerável a ataques de injeção? Em caso afirmativo, como os desenvolvedores podem evitar essas armadilhas?

Uma análise da injeção de SQL

A injeção de SQL é uma forma de injeção de código em que o usuário final pode adicionar código malicioso às consultas SQL que estão sendo executadas pelo seu aplicativo. Um exemplo simples é esta consulta:

Se o desenvolvedor não tomar medidas para proteger seu aplicativo, o usuário poderá incluir texto malicioso no campo userName. Por exemplo:

Essa consulta resulta da inserção pelo usuário de "' OR '1'='1". Agora, a consulta retornará todos os usuários do sistema para o usuário mal-intencionado.

Para permitir alterações mais poderosas na consulta, o usuário mal-intencionado também pode usar comentários para excluir parte da consulta do desenvolvedor. Ampliação do exemplo anterior:

Pode ser injetado com:

Como o SQL ignorará todo o texto após "-", a restrição de que o grupo deve ser 5 foi removida da consulta. Mais uma vez, todos os usuários do sistema são retornados para o usuário mal-intencionado.

O usuário também pode combinar os comentários com comandos em lote para alterar os dados em seu banco de dados:

Como isso afeta o N1QL?

Após alguns experimentos, o N1QL é de fato mais resistente a ataques de injeção do que o SQL tradicional. Por exemplo, o N1QL não suporta atualmente o agrupamento de vários comandos. Portanto, não há equivalente aos ataques em lote que permitem modificações maliciosas de dados em SQL. Por exemplo, este ataque de injeção, que poderia funcionar em SQL, é rejeitado como sintaxe inválida:

No entanto, ainda há opções para um usuário mal-intencionado realizar um ataque. Sem proteção, esses ataques podem resultar na permissão de acesso a dados protegidos ou na negação de serviço porque as consultas alteradas usam muito poder de processamento no cluster do Couchbase.

Além disso, alguns recursos, como batching, certamente poderão ser adicionados em uma versão futura do N1QL. Portanto, se os desenvolvedores não protegerem a entrada do usuário em suas consultas, a modificação de dados poderá se tornar um problema no futuro.

Modificações da cláusula Where

Assim como na injeção de SQL, a injeção de N1QL permite a alteração da cláusula WHERE. Por exemplo:

Pode se tornar:

Devido às regras de precedência de operador para os operadores AND e OR, esse ataque pode até funcionar se houver cláusulas adicionais:

Ainda retorna todos os usuários quando se torna:

Comentários N1QL

O sistema de comentários do N1QL usa blocos de comentários no estilo C (/* comment */) em vez de usar "-" para comentar o restante da linha. Isso protege o N1QL de alguns dos ataques de injeção mais avançados. Como o N1QL exige um comentário de fechamento */, os invasores não podem comentar partes de sua consulta sem causar um erro de sintaxe.

Observe, no entanto, que isso depende de o desenvolvedor não deixar comentários em sua consulta. Se houver um comentário no texto da consulta, o usuário agora tem um bloco de comentários de fechamento para usar a seu favor:

Pode ser injetado com "OR 1=1 /*":

Como no exemplo do SQL, a restrição de grupo agora foi removida da consulta.

Injeção de identificador N1QL

O modelo de documento sem esquema do Couchbase cria, na verdade, uma nova área de ataque interessante. Ao trabalhar com SQL, é muito raro incluir a entrada do usuário em qualquer lugar, exceto na cláusula WHERE ou ORDER BY da sua consulta. Isso ocorre porque os nomes das tabelas e colunas são bem conhecidos e não mudam.

A falta de um esquema para os documentos do Couchbase, no entanto, significa que os desenvolvedores podem ficar tentados a permitir que o usuário controle quais campos estão sendo selecionados no documento.

Após a injeção, torna-se:

Agora, o invasor tem acesso aos dados de um documento de senha relacionado que não estava no documento do usuário especificado pelo desenvolvedor.

Como proteger seu aplicativo

Felizmente, é tão fácil proteger seu aplicativo contra ataques de injeção N1QL quanto contra ataques de injeção SQL. Aqui estão algumas diretrizes que facilitam a segurança. Os exemplos estão em C#, mas os conceitos se aplicam igualmente a qualquer outra linguagem.

  1. Melhores práticas: Em vez de inserir a entrada do usuário diretamente na consulta, use parâmetros nomeados ou posicionais como proteção. Dessa forma, a entrada do usuário nunca é adicionada diretamente à sua consulta, fornecendo proteção 100% contra todos os ataques de injeção.

    Deveria ser:
  2. Prática recomendada #2: Use uma construção de linguagem fortemente tipada, como POCOs .Net ou POJOs Java, que geram o texto da consulta. Por exemplo, a biblioteca Linq2Couchbase (https://github.com/couchbaselabs/Linq2Couchbase) lida com o escape adequado ao gerar N1QL a partir de consultas LINQ.
  3. Se você inserir cadeias de caracteres de entrada do usuário na sua consulta, sempre escape das aspas. Substitua qualquer instância de uma aspa simples (') por duas aspas simples (").

    Deveria ser:
  4. Ao inserir identificadores de entrada do usuário em sua consulta, sempre escape o identificador com ticks (). Em seguida, substitua qualquer instância de um tique na entrada por dois tiques (`). Observe que não há um parâmetro nomeado equivalente para identificadores, portanto, escapar é o identificador é a melhor solução.

    Deveria ser:
  5. Se você implementar as outras regras, também estará protegido contra ataques baseados em comentários. No entanto, uma política secundária contra comentários em consultas que contenham entradas do usuário pode oferecer proteção adicional caso um desenvolvedor esqueça as outras regras. Em vez disso, basta colocar todos os comentários no código do aplicativo em vez de na própria consulta.

    Deveria ser:

Para ver exemplos desses ataques e seus métodos de proteção no C#, consulte este repositório do GitHub: https://github.com/brantburnett/N1QlInjection. Observe que você precisará do Couchbase instalado localmente e com o beer-sample instalado para executar os testes.

Conclusão

Embora o N1QL seja vulnerável a ataques de injeção, essa vulnerabilidade não é pior do que as vulnerabilidades bem conhecidas do SQL. Além disso, é muito fácil para os desenvolvedores se protegerem contra ataques de injeção. Portanto, o N1QL oferece uma excelente plataforma para o desenvolvimento de aplicativos seguros usando os bancos de dados NoSQL do Couchbase.

Autor

Postado por Jeff Morris, engenheiro de software sênior, Couchbase

Jeff Morris é engenheiro de software sênior da Couchbase. Antes de ingressar na Couchbase, Jeff passou seis anos na Source Interlink como arquiteto da Web corporativa. Jeff é responsável pelo desenvolvimento dos SDKs do Couchbase e pela integração com o N1QL (linguagem de consulta).

Deixar uma resposta