Je me demandais s'il était de toute façon possible de spécifier les noms de colonne renvoyés à l'aide d'instructions préparées.
J'utilise MySQL et Java.
Quand je l'essaie:
String columnNames="d,e,f"; //Actually from the user...
String name = "some_table"; //From user...
String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//...
stmt = conn.prepareStatement(query);
stmt.setString(1, columnNames);
stmt.setString(2, "x");
Je reçois ce type de déclaration (impression juste avant l'exécution).
SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
J'aimerais voir cependant:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
Je sais que je ne peux pas faire cela pour les noms de table, comme discuté ici , mais je me demandais s'il y avait un moyen de le faire pour les noms de colonne.
S'il n'y en a pas, je devrai simplement essayer de m'assurer que je désinfecte l'entrée afin qu'elle ne mène pas à des vulnérabilités d'injection SQL.
Cela indique une mauvaise conception de la base de données. L'utilisateur ne devrait pas avoir besoin de connaître les noms de colonnes. Créez une colonne de base de données réelle contenant ces "noms de colonne" et stockez-y les données.
De toute façon, non, vous ne pouvez pas définir les noms de colonne en tant que valeurs PreparedStatement
. Vous ne pouvez définir la colonne values que comme valeurs PreparedStatement
Si vous souhaitez continuer dans cette direction, vous devez préciser le nom des colonnes et concaténer/créer la chaîne SQL vous-même. Citez les noms de colonne distincts et utilisez String#replace()
pour échapper à la même citation dans le nom de la colonne.
Préparez une liste blanche des noms de colonne autorisés. Utilisez la 'requête' pour rechercher dans la liste blanche si le nom de la colonne y figure. Sinon, rejetez la requête.
Je pense que ce cas ne peut pas fonctionner car l'objectif de la déclaration préparée est d'empêcher l'utilisateur d'insérer des bits de requête non échappés - afin que le texte soit toujours cité ou échappé.
Si vous souhaitez affecter la structure de la requête en toute sécurité, vous devrez supprimer cette entrée en Java.
public void MethodName(String strFieldName1, String strFieldName2, String strTableName)
{
//Code to connect with database
String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
st=conn.createStatement();
rs=st.executeQuery(strSQLQuery);
//rest code
}
Utilisez le désavantage par injection sql de Statement Interface comme avantage . Ex:
st=conn.createStatement();
String columnName="name";
rs=st.executeQuery("select "+ columnName+" from ad_org ");