上篇我们介绍了怎么使用Python注入SQL攻击,使用Python防止SQL注入攻击(上)这次我们将介绍怎么防止Python注入SQL攻击。有上一篇的铺垫,我们废话不多说,开搞。。。
制作安全查询参数
在上一篇中,我们看到了入侵者如何利用系统并通过使用 字符串获得管理权限。问题是,我们允许直接执行从客户端传递的值到数据库,却不执行任何类型的检查或验证,所以SQL注入就是依赖于这种类型的漏洞。
在数据库查询中使用用户输入时,可能存在SQL注入漏洞。防止PythonSQL注入的关键是确保该值是不是我们的意愿使用。在前面的示例中,我们打算username用作字符串。实际上,它被用作原始SQL语句。
为了防止入侵者将原始SQL注入字符串参数的位置,可以转义引号:
>>> # BAD EXAMPLE. DON'T DO THIS!>>> username = username.replace("'", "''")
这只是一个例子。在试图阻止Python SQL注入时,需要考虑许多特殊的字符和情况。还好,数据库适配器提供了内置的工具,可以通过使用查询参数来防止Python SQL注入。它们代替普通的字符串插值来组成一个带有参数的查询。
注意:不同的适配器、数据库和编程语言以不同的名称引用查询参数。常见的名称包括绑定变量、替换变量和替换变量。
现在我们对这个漏洞有了更好的理解,我们可以用查询参数代替字符串插值来重写函数了:
def is_admin(username: str) -> bool: with connection.cursor() as cursor: cursor.execute(""" SELECT admin FROM users WHERE username = %(username)s """, { 'username': username }) result = cursor.fetchone()
if result is None: # User does not exist return False
admin, = result return admin
在第9行,我们使用了一个命名参数username来指示用户名应该放在哪里。注意,参数username不再被单引号包围。