Validar certas palavras em um arquivo

Olá PessoALL,

Negócio é o seguinte…o usuario irá selecionar um arquivo no sistema e o meu sistema terá que validar se o arquivo possui certas palavras …

Um exemplo disso é se o cara selecionar um arquivo sql… terei q validar se o arquivo para que o arquivo nao contenha … drop , create … algo assim…

Alguem tem ideia de como faço essa validação ???

Obrigadooo galeraaa;

Uma forma simples mas um pouco rigorosa demais* é simplesmente ler o arquivo linha por linha, e validar contra uma expressão regular que bata com essas palavras.

Uma forma mais correta, mas bem mais trabalhosa, é fazer um parser SQL adaptado ao banco que você vai usar (porque normalmente as coisas que são perigosas dependem do banco que você usa).

O mais simples é fazer com que esse tal arquivo seja executado por um usuário especial, que não tenha nenhum direito de fazer coisas indevidas (por exemplo, ele só pode fazer select mas não pode usar DDL, ou seja, drop, truncate table e outras coisas que só os administradores do banco de dados poderiam fazer.)

  • Pode dar falsos positivos e pior, falsos negativos; por exemplo, se houver alguma dessas palavras-chave dentro de strings literais ("update cliente set name = ‘Drops Dulcora’) - esse é o falso positivo,
    ou se houver na sua versão do SQL uma forma de montar SQL dinâmico - aí o cara poderia fazer algo como “call execsql (‘dr’ + ‘op’ + ’ ’ + ‘all tables’)” ou coisa parecida, onde a palavra ‘drop’ foi montada dinamicamente) - esse é o falso negativo.

vc pode fazer assim:

[code]
public void leitura() throws IOException{
FileReader reader = new FileReader(“seu arquivo”);
BufferedReader leitor = new BufferedReader(reader);
String texto = “Uma lista de palavras que devo validar no texto”;
leitor.readLine();
String linha = null;
while ((linha = leitor.readLine()) != null) {
if(existePalavra(linha, texto)){
//faz alguma coisa
}
}
leitor.close();
}

public static boolean existePalavra(String param, String texto) {
	return texto.indexOf(param) != -1; 
}[/code]

[quote=thingol]Uma forma simples mas um pouco rigorosa demais* é simplesmente ler o arquivo linha por linha, e validar contra uma expressão regular que bata com essas palavras.

Uma forma mais correta, mas bem mais trabalhosa, é fazer um parser SQL adaptado ao banco que você vai usar (porque normalmente as coisas que são perigosas dependem do banco que você usa).

O mais simples é fazer com que esse tal arquivo seja executado por um usuário especial, que não tenha nenhum direito de fazer coisas indevidas (por exemplo, ele só pode fazer select mas não pode usar DDL, ou seja, drop, truncate table e outras coisas que só os administradores do banco de dados poderiam fazer.)

  • Pode dar falsos positivos e pior, falsos negativos; por exemplo, se houver alguma dessas palavras-chave dentro de strings literais ("update cliente set name = ‘Drops Dulcora’) - esse é o falso positivo,
    ou se houver na sua versão do SQL uma forma de montar SQL dinâmico - aí o cara poderia fazer algo como “call execsql (‘dr’ + ‘op’ + ’ ’ + ‘all tables’)” ou coisa parecida, onde a palavra ‘drop’ foi montada dinamicamente) - esse é o falso negativo.
    [/quote]

Obrigado pelas sugestoes …

Com relação aos falso positivo eu havia pensado pois mais simples ainda pode existir uma coluna created_by que seja campo de um select. Mas se eu verificar 'drop ’ - drop espaço … eu eliminiria o falso positivo.

Se eu fosse fazer esse parse de SQL por onde começaria … ???

Acredito que ter um usuario que execute somente comandos DML seja interessante … vou avaliar …

Obrigado thingol sempre com respostas rapidas, sugestivas e muito boas !

[quote=avsouza]vc pode fazer assim:

[code]
public void leitura() throws IOException{
FileReader reader = new FileReader(“seu arquivo”);
BufferedReader leitor = new BufferedReader(reader);
String texto = “Uma lista de palavras que devo validar no texto”;
leitor.readLine();
String linha = null;
while ((linha = leitor.readLine()) != null) {
if(existePalavra(linha, texto)){
//faz alguma coisa
}
}
leitor.close();
}

public static boolean existePalavra(String param, String texto) {
	return texto.indexOf(param) != -1; 
}[/code][/quote]

obrigado avosuza … vou teste seu codigo … qq coisa falo novamente com vc !!!

e viva Timão … eheheheheh

Pois é, olhando no help da classe Pattern, achei o padrão “\b” que serve para marcar o início ou o fim de uma palavra. Veja como funciona:

import java.util.regex.*;
import java.util.*;
import java.io.*;

class TestePattern {
    Pattern pat = Pattern.compile ("\\b(delete|drop|truncate|create)\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    public TestePattern () {}
    private String[] linhas = {
         "select * from tabela where cliente = 'drops dulcora'",
         "select created_by from tabela_tabelas",
         "truncate table abc",
         "select * from teste",
         "DELETE FROM TESTE"
    };
    public void teste() {
	for (String linha : linhas) {
            Matcher mat = pat.matcher (linha);
            if (mat.find ()) {
                System.out.println ("Contém a palavra proibida '" + mat.group() + "' em " + linha);
            } else {
                System.out.println ("Não achou nenhuma palavra proibida:" + linha);
            }
        }        
    }
    public static void main(String[] args) {
	(new TestePattern()).teste();
    }
}

EDIT - agora mostro até qual foi a palavra proibida (não mostre isso para o usuário, mas você pode pôr isso no seu log.)

[quote=thingol]Pois é, olhando no help da classe Pattern, achei o padrão “\b” que serve para marcar o início ou o fim de uma palavra. Veja como funciona:

import java.util.regex.*;
import java.util.*;
import java.io.*;

class TestePattern {
    Pattern pat = Pattern.compile ("\\b(delete|drop|truncate|create)\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    public TestePattern () {}
    private String[] linhas = {
         "select * from tabela where cliente = 'drops dulcora'",
         "select created_by from tabela_tabelas",
         "truncate table abc",
         "select * from teste",
         "DELETE FROM TESTE"
    };
    public void teste() {
	for (String linha : linhas) {
            Matcher mat = pat.matcher (linha);
            if (mat.find ()) {
                System.out.println ("Contém a palavra proibida '" + mat.group() + "' em " + linha);
            } else {
                System.out.println ("Não achou nenhuma palavra proibida:" + linha);
            }
        }        
    }
    public static void main(String[] args) {
	(new TestePattern()).teste();
    }
}

EDIT - agora mostro até qual foi a palavra proibida (não mostre isso para o usuário, mas você pode pôr isso no seu log.)[/quote]

thingol perfeito cara … muuuuuuutissimo obrigado … funcionou direitinh o… agora vou melhorar para buscar as linhas do arquivo que o cara selecionar …

obrigado a todos que me ajudaram … !

[quote=gui_sv]

thingol perfeito cara … muuuuuuutissimo obrigado … funcionou direitinh o… agora vou melhorar para buscar as linhas do arquivo que o cara selecionar …

obrigado a todos que me ajudaram … ![/quote]

Acho ainda que está faltando filtrar também a palavra reservada “ALTER” e também outras palavras reservadas que fazem alterações em outras configurações dos SGBDs.

Inté.

[quote=KWill][quote=gui_sv]

thingol perfeito cara … muuuuuuutissimo obrigado … funcionou direitinh o… agora vou melhorar para buscar as linhas do arquivo que o cara selecionar …

obrigado a todos que me ajudaram … ![/quote]

Acho ainda que está faltando filtrar também a palavra reservada “ALTER” e também outras palavras reservadas que fazem alterações em outras configurações dos SGBDs.

Inté.[/quote]

iisso mesmo … o alter eu adicionei … estou pesquisando outros comando ddl … constraint coisa e tal

d qq forma obrigado !!!