web-dev-qa-db-fra.com

Noms de colonne variables utilisant des instructions préparées

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.

32
KLee1

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.

32
BalusC

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.

15
wgl

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.

2
G__
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
}
1
Grbh Niti

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 ");
0
Syed Abdul Khaliq