使用预准备语句的变量列名
我想知道是否有任何方法可以使用准备好的语句指定返回的列名称。
我正在使用 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");
我得到这种类型的语句(在执行之前打印)。
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'
正如所讨论的,我知道我不能对表名执行此操作 此处,但想知道是否有某种方法可以做到这一点列名称。
如果没有,那么我只需尝试确保清理输入,这样就不会导致 SQL 注入漏洞。
I was wondering if there was any way to specify returned column names using prepared statements.
I am using MySQL and Java.
When I try it:
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");
I get this type of statement (printing right before execution).
SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
I would, however, like to see:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
I know that I cannot do this for table names, as discussed
here, but was wondering if there was some way to do it for column names.
If there is not, then I will just have to try and make sure that I sanitize the input so it doesn't lead to SQL injection vulnerabilities.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这表明数据库设计不好。用户不需要知道列名。创建一个真实的数据库列来保存这些“列名称”并沿其存储数据。
无论如何,不,您不能将列名称设置为
PreparedStatement
值。您只能将列值设置为PreparedStatement
值。如果您想继续朝此方向操作,则需要清理列名称(以避免SQL 注入)并自己连接/构建 SQL 字符串。引用单独的列名称并使用
String#replace()
转义列名称中的相同引号。This indicates a bad DB design. The user shouldn't need to know about the column names. Create a real DB column which holds those "column names" and store the data along it instead.
And any way, no, you cannot set column names as
PreparedStatement
values. You can only set column values asPreparedStatement
valuesIf you'd like to continue in this direction, you need to sanitize the column names (to avoid SQL Injection) and concatenate/build the SQL string yourself. Quote the separate column names and use
String#replace()
to escape the same quote inside the column name.准备允许的列名称白名单。使用“查询”在白名单中查找列名是否存在。如果不是,则拒绝查询。
Prepare a whitelist of allowed column names. Use the 'query' to look up in the whitelist to see if the column name is there. If not, reject the query.
对于使用 NodeJS (mysqljs/mysql) 的 MySQL 准备语句,您需要知道的是
?
用于值,但如果您需要转义列名、表名等,请使用??
相反。像这样的东西会起作用:
将值设置为
['id', 'name', 'address', 'user', 'id', 100]
For MySQL prepared statements with NodeJS (mysqljs/mysql), what you need to know is that
?
is for values, but if you need to escape column names, table names etc, use??
instead.Something like this will work:
Set values to
['id', 'name', 'address', 'user', 'id', 100]
我认为这种情况行不通,因为准备好的语句的全部目的是防止用户放入未转义的查询位 - 因此您总是会引用或转义文本。
如果您想安全地影响查询结构,则需要在 Java 中清理此输入。
I think this case can't work because the whole point of the prepared statement is to prevent the user from putting in unescaped query bits - so you're always going to have the text quoted or escaped.
You'll need to sanitize this input in Java if you want to affect the query structure safely.
利用Statement Interface的sql注入缺点作为优点。
前任:
Use sql injection disadvantage of Statement Interface as advantage.
Ex:
下面是java中的解决方案。
Below is the solution in java.