SQL注入- Python - MySQL

g6baxovj  于 2023-10-15  发布在  Mysql
关注(0)|答案(2)|浏览(99)

基本上,我试图在下面的代码中找到探索SQL注入漏洞的方法。代码还有另一个层,表示层,它要求用户输入board_name。Table_name是一个内部变量,用户无法控制它。

def find_board_by_name(cls, connector, board_name, table_name: str):
        query = "SELECT * FROM {} WHERE name = '{}'".format(table_name,board_name.title())
        print(query)
        try:
            connector.mycursor.execute(query)
            res = connector.mycursor.fetchone()
            if res:
                return res[1]
            return None
        except Exception as e:
            raise e

尝试:
1-board_name为:“或”1“=”1
它的工作,程序返回给我我的第一个项目在表上(它不应该,因为我没有提供任何名称)
2-已尝试将board_name设置为:';删除Table BoardGames;它没有工作,mysql.connector.errors.InterfaceError:在执行多个语句时使用multi=True是向我提出的。
所以我的问题是“mysql.connector”是保护我免受大多数SQL注入?因为我没有将代码中的“multi”标记设置为True?你能告诉我其他方法来探索这段代码中的漏洞吗?除了1和2。
我想我知道如何解决SQL注入问题:**“connector.mycursor.execute(query,values)"**可能就可以完成这项工作。但是,我试图更好地了解什么样的SQL漏洞,我会与这个原始代码没有这个修复。

z3yyvxxp

z3yyvxxp1#

SQL注入并不总是恶意的。它可能会导致一个简单的错误,而不是删除所有的学生记录。
例如,如果您网站的某个合法用户名为“O 'Reilly”,那么您的代码格式将有一个不平衡的引号,这将是一个语法错误:

SELECT * FROM tablename WHERE name = 'O'Reilly'
                                       ^ wtf

使用参数可以避免此类问题。查询参数不仅仅是一种快速插值变量的方法。它们要么转义动态内容中的特殊字符(默认情况下Python会这样做),要么完全成熟的参数将值与SQL查询分开,直到SQL服务器解析它之后。所以没有特殊字符会导致语法错误。
但是表名和其他标识符不能是参数。您只能使用参数来代替SQL值,就像您的示例中引用的字符串一样。
你说用户不能控制表名变量。很好,但还不够。
如果项目中的另一个程序员在调用您的find_board_by_name()函数时不小心,无意中传递了不安全的内容作为表名,该怎么办?请注意,不安全的内容不仅仅是用户输入。
如果表名是SQL中的保留关键字怎么办?

SELECT * FROM order WHERE name = ?
              ^ syntax error

如果表名包含空格或标点符号怎么办?还有其他风险。
您应该对函数进行编码,使其不信任其调用方。对于SQL值,当然要使用参数。对于其他动态元素(如表名),您必须将变量插入SQL字符串,但您可以采取防御措施:

  • 使用allowlist验证表名是否是合法的已知表名。
  • 在SQL中用反引号分隔表名,以防它是保留字或不是简单的标识符。
legit_table_names = Set(['table1', 'table2', 'table3'])
if table_name not in legit_table_names:
  return error # pseudocode

query = f"SELECT * FROM {table_name} WHERE name = %s"

(我更喜欢f-strings而不是现代Python中的format()

khbbv19g

khbbv19g2#

即使允许执行多个语句,SELECT语句中的SQL注入也允许攻击者监视数据。
假设tablename有4列,注入' UNION SELECT name, birthday, identity_nr, credit_card_nr FROM customers WHERE '1'='1将允许攻击者从另一个表中窃取凭据。

相关问题