Python sqite3用户定义查询(选择表)

Python sqite3用户定义查询(选择表),python,python-2.7,sqlite,sql-injection,Python,Python 2.7,Sqlite,Sql Injection,我有一个uni任务,我正在实现一个数据库,用户可以通过网页与之交互。目标是在给定一些标准的情况下搜索书籍。这是一个更大项目中的一个模块 我想让用户能够选择他们想要的标准和顺序,但以下似乎不起作用: cursor.execute("SELECT * FROM Books WHERE ? REGEXP ? ORDER BY ? ?", [category, criteria, order, asc_desc]) 我不知道为什么,因为当我走的时候 cursor.execute("SELECT * F

我有一个uni任务,我正在实现一个数据库,用户可以通过网页与之交互。目标是在给定一些标准的情况下搜索书籍。这是一个更大项目中的一个模块

我想让用户能够选择他们想要的标准和顺序,但以下似乎不起作用:

cursor.execute("SELECT * FROM Books WHERE ? REGEXP ? ORDER BY ? ?", [category, criteria, order, asc_desc])
我不知道为什么,因为当我走的时候

cursor.execute("SELECT * FROM Books WHERE title REGEXP ? ORDER BY price ASC", [criteria])
我得到了全部结果。有没有办法不用注射就能解决这个问题


数据组织在一个表中,其中书的ISBN是主键,每行有许多列,如书的标题、作者、出版商等。应允许用户选择这些列中的任何一列并执行搜索。

一般来说,SQL引擎只支持值参数,而不支持表名、列名和,sqlite本身也是如此,Python的sqlite模块也是如此

这背后的基本原理部分是历史原因(传统笨拙的数据库API有显式的
bind
调用,其中必须说明绑定的列号和类型的值等),但主要是因为没有太多好的理由来参数化值

一方面,您不需要担心表名和列名的引号或类型转换。另一方面,一旦您开始让最终用户来源的文本指定一个表或列,就很难看出它们还会造成什么危害

此外,从性能的角度来看(如果您阅读-参见第3.0节-您会注意到他们将参数绑定作为性能问题而不是安全问题来关注),当给定不同的值时,数据库引擎可以重用准备好的优化查询计划,但当给定不同的列时则不能


那么,你能做些什么呢

动态生成SQL字符串是一种选择,但不是唯一的选择

首先,这种情况通常是数据模型损坏的迹象,需要进一步规范化。也许您应该有一个
BookMetadata
表,其中有许多行,每个行都有一个字段名,每个
Book
都有一个值


第二,如果您想要的东西在这个代码的概念上是规范化的,但实际上是非规范化的(或者是为了效率,或者是因为对于其他一些代码它不应该规范化)…函数非常适合这样做。一个包装器,您可以在
执行它时将参数传递给该函数。

引擎可能会引用
order
asc_desc
的值,结果是
order by'price''desc
,这与
order by price desc
不同。另外,在第二次查询中,您要在REGEXP中输入条件的值?但在第一个查询中,您将它放在第二个查询的“title”位置。这是故意的吗?选项2会不会冒注射攻击的风险<代码>从分类为REGEXP的书籍中选择*?ORD BY ORD ASCDESC
我可以看到一些令人讨厌的东西从这里冒出来。我传入的
create\u函数
需要对输入进行消毒,不是吗?@cjdb01:是的,
create\u函数
不会神奇地解决任何问题,它只是提供了一种方法,让您编写一个自定义解决方案,然后将其呈现给代码的其余部分,就像它是一个神奇的解决方案一样。@cjdb01:但我不理解您的示例。如果您唯一的参数是正则表达式,那么参数绑定已经为您解决了所有问题,无论是否有函数…@abarent我在原始问题(我现在将更新)中没有提到这一点,但我认为数据库已按照您建议的级别进行了标准化,因为每个ISBN(主键)只有一个条目。每行大约有10列,与标题、作者、出版商、价格等信息相关。我希望用户能够选择如何搜索,但不希望写出所有排列;这就是为什么我倾向于创建一个函数。如果你不同意并认为它可以进一步规范化,请让我知道,因为我的数据库知识已经有两年了,而且只有高中水平,在那里规范化得到了很好的概述。