【发布时间】:2021-04-14 17:18:22
【问题描述】:
我创建了一个名为 test 的测试数据库,其中有一个名为 testTable 的表,其中包含一个自动增量 id 值和一个采用 varchar(30) 的名称字段。
PREPARE 语句查询(其中 4 个)在复制到 phpmyadmin 时执行良好,但我收到错误 ???? 2021-01-08 18:26:53,022 (MainThread) [ERROR] (1064, "您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册以获取在 'SET 附近使用的正确语法\n @name = 'fred';\nEXECUTE\n 语句 USING @name;\nDEALLOCATE\nPREPARE\n ' 在第 5 行")
测试代码:
import pymysql
import logging
class TestClass():
def __init__(self):
# mysqlconnections
self.mySQLHostName = "localhost"
self.mySQLHostPort = 3306
self.mySQLuserName = "userName"
self.mySQLpassword = "pass"
self.MySQLauthchandb = "mysql"
def QueryMYSQL (self, query):
try:
#logging.info("QueryMYSQL : " + str( query)) # Uncomment to print all mysql queries sent
conn = pymysql.connect(host=self.mySQLHostName, port=self.mySQLHostPort, user=self.mySQLuserName, passwd=self.mySQLpassword, db=self.MySQLauthchandb, charset='utf8')
conn.autocommit(True)
cursor = conn.cursor()
if cursor:
returnSuccess = cursor.execute(query)
if cursor:
returnValue = cursor.fetchall()
#logging.info ("return value : " + str(returnValue)) # Uncomment to print all returned mysql queries
if cursor:
cursor.close()
if conn:
conn.close()
return returnValue
except Exception as e:
logging.error("Problem in ConnectTomySQL")
logging.error(query)
logging.error(e)
return False
# Default error logging log file location:
logging.basicConfig(format='%(asctime)s (%(threadName)-10s) [%(levelname)s] %(message)s', filename= 'ERROR.log',filemode = "w", level=logging.DEBUG)
logging.info("Logging Started")
test = TestClass()
result = test.QueryMYSQL("Describe test.testTable")
print(result)
query = """
PREPARE
statement
FROM
'INSERT INTO test.testTable (id, name) VALUES (NULL , ?)';
SET
@name = 'fred';
EXECUTE
statement USING @name;
DEALLOCATE
PREPARE
statement;
"""
result = test.QueryMYSQL(query)
print(result)
我假设这是一个库问题而不是 mysql 问题?我正在尝试使用准备好的语句来防止来自用户输入的代码注入,因为我知道这种准备好的语句是最好的方法,而不是尝试预先过滤用户输入并遗漏一些东西。
我在 github 上问过这个问题,但其中一位作者(甲烷 Inada Naoki)回答说:
========
当存在查询注入漏洞时,攻击者可以使用多语句。所以默认是关闭的。
as I understand this prepared statements are the best way
你完全错了。您使用准备好的语句根本不能保护您免受 SQL 注入。如果启用多语句,您的“准备语句”可能会受到 SQL 注入的攻击。
但我不是免费的技术支持,也不是免费的老师。 OSS 维护者不是。请不要在这里问。
他关闭了这个问题。
他说的对吗?
我正在阅读 Robin Nixon 的作者书,“Learning PHP, MySQL and JavaScript” O'Reilly 第 5 版。他似乎被误解了,我在第 260 页的使用占位符部分引用了“让我介绍与 MySQL 交互的最佳和推荐方式,这在安全性方面几乎是防弹的”。他错了吗?
因为我买这本书是为了改进我的安全实践,现在我不确定什么是正确的。
【问题讨论】:
-
这可能暗示了准备好的语句仿真,但我不熟悉相关 Python 驱动程序的内部结构。如果您在驱动程序级别使用占位符值,没有仿真,您应该没问题。如果涉及仿真,则该实现中可能存在错误或限制。
-
我认为这里的问题是您没有指定导致问题的
DELIMITER。我根本不信任这个 MySQL 代码。您正在连接并运行一条语句。这是非常低效的,即使是最琐碎的用例也无法扩展。
标签: python mysql security pymysql