使用预准备语句的可变列名称
我想知道是否有指定使用准备语句返回的列名称。
我正在使用MySQL和Java。
当我尝试它时:
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");
我得到这种types的声明(执行之前打印)。
SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
不过我想看看:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
我知道,我不能这样做表名,正如这里所讨论的,但是想知道是否有某种方法可以对列名进行操作。
如果没有,那么我将不得不尝试确保我对input进行清理,以免导致SQL注入漏洞。
这表明一个不好的数据库devise。 用户不需要知道列名。 创build一个真正的数据库列,其中包含这些“列名”,并存储在它的数据。
不pipe怎样,不可以将列名称设置为PreparedStatement
值。 您只能将列值设置为PreparedStatement
值
如果你想继续这个方向,你需要清理列名并自己连接/构buildSQLstring。 引用单独的列名称,并使用String#replace()
来转义列名内的相同引号。
准备允许列名称的白名单。 使用“查询”在白名单中查找列名是否存在。 如果不是,则拒绝查询。
我认为这种情况是行不通的,因为准备好的语句的整个目的是为了防止用户input非转义的查询位 – 所以你总是要引用或转义文本。
如果要安全地影响查询结构,则需要使用Java对input进行清理。
使用SQL注入语句接口的缺点作为优势。 例如:
st=conn.createStatement(); String columnName="name"; rs=st.executeQuery("select "+ columnName+" from ad_org ");
下面是java中的解决scheme。
String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
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 }