我正在创建一个游戏服务器使用的函数。这个服务器使用插件。我有这些函数使用SQLite数据库,沿着APSW检索由另一个函数存储的项目。我有3个问题。
问题一:我一直收到错误“SQLError:near“?":syntax error”由于我的语句中包含多个?
,因此很难找到错误的确切位置。
问题二:我知道SQL注入,但是这些函数只接受脚本运行者的输入,而他唯一会破坏的东西是他自己的。即使如此,有没有一个简单的方法来使这个SQL注入证明?
问题三:有什么办法能使这个功能更有效吗?
下面是它现在的样子:
def readdb(self,entry,column,returncolumn = "id,matbefore,matafter,name,date"):
self.memwrite
if isinstance(entry, int) or isinstance(entry, str):
statement = 'SELECT {0} FROM main WHERE {1} IN {2}'.format(returncolumn,column,entry)
self.memcursor.execute(statement)
blockinfo = self.memcursor.fetchall()
return(blockinfo)
if isinstance(entry, tuple) or isinstance(entry, list):
statement = '''SELECT {0} FROM main WHERE {1} IN (%s)'''.format(returncolumn,column)
self.memcursor.execute(statement % ("?," * len(entry))[:-1], entry)
blockinfo = self.memcursor.fetchall()
return(blockinfo
2条答案
按热度按时间anhgbhbe1#
这很有趣(请继续阅读,了解原因)。
第一条语句实际上使用了
sqlite3
-模块的值绑定机制(我假设这就是您使用的)。因此,*
(默认列)被转义,使语句无效。这是SQL注入证明,您自己的代码尝试注入SQL(现在看到有趣的地方了吗?)第二次使用Pythons字符串替换来构建查询字符串时,这不是SQL注入证明。
ztigrdn82#
使用名称来获取更多信息性的错误消息。例如,我故意在下面的语句中省略了一个逗号:
现在有了名字:
如果您有很多绑定,我建议您切换到命名绑定样式,并传递绑定本身的字典。
您只能对值使用绑定,而不能对列名或表名使用绑定。有几种可能的方法。尽管SQLite支持任意列名/表名,您可以要求它们仅为ASCII字母数字文本。如果您希望限制较少,则需要用引号括起名称。请使用方括号括起包含双引号的名称,并使用双引号括起包含方括号的名称。一个名字不能两者兼得。
这是使用授权者机制的替代方法。请参阅Connection.setauthorizer了解API和一个示例。简单地说,回调函数是用将要执行的操作调用的,例如,您可以拒绝任何写入数据库的操作。
在效率方面,你可以根据调用者使用结果的方式来改进。2游标是非常便宜的。3没有必要一次又一次地重复使用同一个游标,这样做可能会导致细微的错误。4 SQLite只在你请求的时候才得到结果的下一行。5通过使用fetchall,你可以坚持建立一个所有结果的列表。如果列表很大,或者你可能中途停止,那么只需要返回
db.cursor().execute("... query ...")
,调用者应该使用你的函数进行迭代:如果我是你,我会完全抛弃这个readdb函数,因为它没有添加任何值,而是直接编写查询:
你的编码风格表明你对Python还是个新手。我强烈建议你查找迭代器和生成器。这是一种简单得多的编码风格,可以根据需要生成和使用结果。
顺便说一句,这个SQL创建了一个表,表名为零长度,列名为双引号和分号。SQLite功能很好,但不要这样做:-)但它对测试很有用。
披露:我是APSW作者