Skip to content

Instantly share code, notes, and snippets.

@themsleeves
Last active July 16, 2018 14:32
Show Gist options
  • Save themsleeves/3774bdbdf77e6f065da58a6143859631 to your computer and use it in GitHub Desktop.
Save themsleeves/3774bdbdf77e6f065da58a6143859631 to your computer and use it in GitHub Desktop.
SQL Injections control toolkit
package dcSGDB.controles;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import dcSGDB.controles.bean.BeanRequete;
import dcSGDB.controles.enumeration.TypeStatement;
import dcSGDB.controles.strategy.AbstractInfosStrategy;
import net.sf.jsqlparser.parser.CCJSqlParser;
import net.sf.jsqlparser.statement.Statement;
/**
* Classe abstraite qui doit etre etendue dans les classes de controle type SQL
* Elle contient un certain nombre de comportements, de preparations utiles lors de controles sur requetes SQL
* Entre autres elle fourni : un parseur de requete (JSQLParser), les informations disponibles avec l'objet BeanRequete
* et effectue egalement un controle de premier niveau sur l'instruction principale (voir dcSGDB.controles.enumeration.TypeStatement)
* @author xcampano
*
*/
public abstract class AbstractCtrlSQL extends AbstractControles {
private StringBuilder strBldr = new StringBuilder();
// Instance du parseur de requetes
protected CCJSqlParser SQLParser = null;
// Objet contenant les information de la requete
protected BeanRequete beanReq;
/**
* Constructeur pour tout controle de type SQL
* @param infos Objet InfoControle passant de classe en classe
*/
public AbstractCtrlSQL(InfosControle infos) {
super(infos);
beanReq = (BeanRequete)infos.getObj();
SQLParser = beanReq.getSQLParser();
if (SQLParser==null) {
SQLParser = new CCJSqlParser(new StringReader(beanReq.getRequete()));
beanReq.setSQLParser(SQLParser);
}
}
/**
* Methode d'initialisation de l'objet requete principal via des strategies (voir SelectInfosStrategy pour ex.)
* Elle effectue en meme temps un controle sur l'instruction principale
* @param stmt : instruction non typee qui doit etre interpretee
* @return Statement le type d'instruction du parseur (SELECT, INSERT, ...)
*/
protected Statement getStatementObj(Statement stmt) {
strBldr.setLength(0);
AbstractInfosStrategy tmpStmt = null;
// Enumeration contenant la liste des instructions et leurs eventuelles strategies
TypeStatement type = TypeStatement.getEnum(stmt);
beanReq.setTypeStmt(type);
String mess = type.getMess();
if (mess.length()>0) {// message present si pas de strategie pour l'instruction
strBldr.append(type.getMess());
return null;
}else {
// Recuperation strategie correspondante à l'instruction
tmpStmt = type.getInfosStrat();
// Execution et initialisation via la strategie
return tmpStmt.createStatementObj(stmt, beanReq);
}
}
public void execute() throws NoSuchMethodException, Exception {
if (isOk()) {
Statement mainStatement = beanReq.getMainStatement();
if (mainStatement == null) {
List<Statement> stmtFromList = new ArrayList<Statement>();
stmtFromList.addAll(SQLParser.Statements().getStatements());
// Memorisation liste d'instructions brute
beanReq.setStmtFromList(stmtFromList);
if (stmtFromList.size()==1) {
mainStatement = getStatementObj(stmtFromList.get(0));
if (mainStatement == null) {
// Instruction non autorisée
infos.getControle().setMessage(strBldr.toString());
}else{
beanReq.setMainStatement(mainStatement);
}
}
}
}
}
}
package dcSGDB.controles;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import dcSGDB.exceptionKekahaGenerique;
import dcSGDB.facadeServices;
import dcSGDB.controles.bean.BeanRequete;
import dcSGDB.controles.bean.Controle;
import dcSGDB.controles.commun.CommunCtrl;
import dcSGDB.controles.oracle.OracleCtrl;
import dcSGDB.controles.sqlserver.SqlServerCtrl;
/**
* Classe outils pour les controles.
* @author xcampano
*
*/
public class OutilsControle {
/**
* Creer la definition des controles.
*
* @param classes Le classes
* @return the list< class<? extends abstract controles>>
*/
public static List<Class<? extends AbstractControles>> creerDefinition(Class<? extends AbstractControles> ... classes) {
List<Class<? extends AbstractControles>> liste = new ArrayList<Class<? extends AbstractControles>>();
for(Class<? extends AbstractControles> classe:classes){
liste.add(classe);
}
return liste;
}
/**
* Controle des injections : Point d'entree des controles sur le contenu de la requete SQL
* @param typeSGBD : chaine type de moteur BDD utilise
* @param cursorSQL : chaine requete SQL
* @return le message d'erreur s'il existe sinon chaine vide
* @throws exceptionKekahaGenerique
*/
public static String ctrlInjection(String typeSGBD, String cursorSQL) throws exceptionKekahaGenerique {
String ret = "";
try {
SuiteControle ctrlSuite = new SuiteControle();
BeanRequete mainBeanReq = new BeanRequete(cursorSQL);
// Controles communs
Controle ctrl = CtrlSuiteFacade.execute(ctrlSuite, CommunCtrl.getControles(), mainBeanReq);
if (ctrl.estOk()) {
// Controles specifiques SGBD pour liste des tables...
if ((typeSGBD).equals(facadeServices.getInstance().SGBD_ORACLE)) { //***** ORACLE *****
ctrl = CtrlSuiteFacade.execute(ctrlSuite, OracleCtrl.getControles(), mainBeanReq);
}else if ((typeSGBD).equals(facadeServices.getInstance().SGBD_MSSQLSERVER)) { //***** SQL Server *****
ctrl = CtrlSuiteFacade.execute(ctrlSuite, SqlServerCtrl.getControles(), mainBeanReq);
}
}
if (!ctrl.estOk()) {// Rejet de la requete principale
ret = ctrl.getMessage();
}else {// Suite des controles...
ret = ctrlInjectionSuite(mainBeanReq);
}
} catch (Exception e) {
throw new exceptionKekahaGenerique("Erreur dans ctrlInjection... " + e.getMessage(), exceptionKekahaGenerique.errSGBDdown);
}
return ret;
}
/**
* Suite des controles injections : traitement recursif de controles communs...
* Utilisation pour traitement des requetes imbriquees (detectees et memorisees dans les strategies)
* @param beanReq : BeanRequete contenant les infos d'une requete SQL
* @return le message d'erreur s'il existe sinon chaine vide
* @throws Exception
*/
public static String ctrlInjectionSuite(BeanRequete beanReq) throws Exception {
String ret="";
if (beanReq.getSubStatements()!=null) {
ListIterator<BeanRequete> iterator = beanReq.getSubStatements().listIterator();
while (iterator.hasNext()) {
BeanRequete subBeanReq = iterator.next();
subBeanReq.setParent();
Controle subCtrl = CtrlFacade.execute(CommunCtrl.getControles(), subBeanReq);
if (!subCtrl.estOk()) {// Rejet de la requete
ret = subCtrl.getMessage();
break;
}else {// Relance du controle pour recusivite
ret = ctrlInjectionSuite(subBeanReq);
}
}
if (ret.length()==0) {
beanReq.clearSubStatements();
}
}
return ret;
}
/**
* Verification si chaine est de type entier
* @param str : chaine a tester
* @return vrai si entier
*/
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment