Tudo o que vi nos ataques de injeção de SQL parece sugerir que consultas parametrizadas, principalmente as de procedimentos armazenados, são a única maneira de se proteger contra esses ataques. Enquanto eu trabalhava (na Idade das Trevas), os procedimentos armazenados eram vistos como uma prática ruim, principalmente porque eram vistos como menos sustentáveis; menos testável; altamente acoplado; e bloqueou um sistema em um fornecedor; ( esta pergunta cobre alguns outros motivos).
Embora quando eu estivesse trabalhando, os projetos praticamente não tivessem consciência da possibilidade de tais ataques; várias regras foram adotadas para proteger o banco de dados contra corrupção de vários tipos. Essas regras podem ser resumidas como:
- Nenhum cliente / aplicativo teve acesso direto às tabelas do banco de dados.
- Todos os acessos a todas as tabelas eram através de visualizações (e todas as atualizações nas tabelas base eram feitas através de gatilhos).
- Todos os itens de dados tinham um domínio especificado.
- Nenhum item de dados podia ser anulável - isso tinha implicações que os DBAs rangiam os dentes de vez em quando; mas foi aplicado.
- As funções e permissões foram configuradas adequadamente - por exemplo, uma função restrita para fornecer apenas às visualizações o direito de alterar os dados.
Portanto, um conjunto de regras (aplicadas) como essa (embora não necessariamente esse conjunto em particular) seja uma alternativa apropriada para consultas parametrizadas na prevenção de ataques de injeção de SQL? Se não, por que não? Um banco de dados pode ser protegido contra esses ataques por medidas específicas do banco de dados (apenas)?
EDITAR
A ênfase da pergunta mudou um pouco, à luz das respostas iniciais recebidas. Pergunta base inalterada.
EDIT2
A abordagem de confiar em consultas paramaterizadas parece ser apenas um passo periférico na defesa contra ataques a sistemas. Parece-me que as defesas mais fundamentais são desejáveis e podem tornar a confiança nessas consultas desnecessária ou menos crítica, mesmo para se defender especificamente contra ataques de injeção.
A abordagem implícita na minha pergunta foi baseada em "blindar" o banco de dados e eu não tinha idéia se era uma opção viável. Pesquisas posteriores sugeriram que existem tais abordagens. Encontrei as seguintes fontes que fornecem alguns ponteiros para esse tipo de abordagem:
http://database-programmer.blogspot.com
http://thehelsinkideclaration.blogspot.com
Os principais recursos que tirei dessas fontes são:
- Um extenso dicionário de dados, combinado com um extenso dicionário de dados de segurança
- Geração de gatilhos, consultas e restrições do dicionário de dados
- Minimize o código e maximize os dados
Embora as respostas que recebi até o momento sejam muito úteis e apontem dificuldades decorrentes da desconsideração de consultas paramaterizadas, em última análise, elas não respondem às minhas perguntas originais (agora enfatizadas em negrito).
fonte
Respostas:
Os procs armazenados não protegem automaticamente contra a injeção. E isso
O uso de consultas parametrizadas o protegerá contra a injeção, estejam eles em procs ou não.
fonte
Não, porque eles infligem uma penalidade pesada aos desenvolvedores. Um detalhamento por item:
Use funções. Os clientes só devem poder acessar o banco de dados por meio de uma função restrita que tenha acesso SELECT, INSERT, UPDATE e DELETE às tabelas (e linhas, sempre que possível) às quais ele precisa acessar. Se você deseja garantir que nenhum cliente possa enviar spam ou excluir todas as entradas, use uma API para modificação de dados.
Isso pode variar de insignificante a um enorme custo de desempenho, dependendo da eficiência das visualizações. É uma complexidade desnecessária que atrasa o desenvolvimento. Use funções.
Pode ser muito trabalhoso manter e provavelmente deve ser normalizado em uma tabela separada.
Isso é completamente errado. Se os desenvolvedores não puderem lidar com
NULL
s, você terá grandes problemas.Você não precisa de procedimentos armazenados, basta usar consultas parametrizadas com uma função que escapa aos argumentos, como pg_query_params . Obviamente, se seu banco de dados for gravável mundialmente ou se a função de cliente tiver acesso total a tudo, você estará ferrado. Alguém só precisa entender o que o cliente está fazendo e, em seguida, preparar um cliente em cinco minutos que destrói (ou pior, envenena) seu banco de dados.
fonte
Não tenho certeza de que suas regras o protejam completamente.
O primeiro problema é que você declara que elas são aplicadas, mas, além de ter uma sobrecarga significativa, nunca vi uma aplicação perfeita.
Em segundo lugar, minha leitura deles é que regras como essas podem tornar as coisas mais difíceis de explorar, mas não as impedem. Por exemplo, não ter acesso direto às tabelas não muda muito se as visualizações permitirem o acesso aos mesmos dados. Se o cliente precisar fazer algo, uma visualização precisará facilitar isso e se a visualização facilitar, a mesma funcionalidade / dados poderão ser utilizados por um invasor.
Lembre-se também de que não se trata apenas de atualizar ou excluir dados. Parte da vulnerabilidade com a injeção de SQL é a coleta de informações e, para isso, você não se importa se os dados foram passados de volta pela exibição vCustomers ou pela tabela Customers subjacente. Você pode ter se protegido de algumas fraquezas, mas não todas. Da mesma forma, se as atualizações puderem ser feitas pelo cliente, mesmo que através de gatilhos, o SQL poderá ser gravado para disparar os gatilhos e fazer atualizações.
(Em termos de todas as atualizações feitas por meio de gatilhos, vou dizer duas coisas: (1) quando li isso, fiquei com um pouco de enjoo na boca e (b) você não gosta de Procedimentos armazenados, porque eles ' re "menos manutenível; menos testável; altamente acoplado; e bloqueou um sistema em um fornecedor", mas você usa gatilhos sobre os quais basicamente podem ser ditas as mesmas coisas.)
Tudo o que você precisa é de um buraco que permita a execução de instruções SQL (e não vejo nenhuma dessas regras impedindo isso) e o invasor está dentro. Eles podem estar encontrando um banco de dados muito pouco intuitivo por trás deles, mas se eles determinarem apenas diminua a velocidade em vez de impedi-los).
A outra coisa aqui é que você também está adicionando complexidade e (assim como a sobrecarga que cria), a complexidade tende a levar a buracos que podem ser explorados.
Não estou dizendo que esse conjunto de regras não possa ser criado - mais por que você se incomodaria? Eles parecem mais pesados e menos confiáveis do que apenas seguir os métodos amplamente aceitos de impedir esse tipo de ataque.
fonte