如果需要,防止Python中的连接字符串污染攻击



当为数据库传递用户的userid和密码时,我希望返回预定义查询的结果。

查询是常量,因此不是基本的SQL注入场景。

但是,允许用户指定将被.format()写入连接字符串的用户名和密码是否会造成任何漏洞?

(我发现一个消息来源表明它确实如此——我主要对sqlalchemy.create_enginepymongo.MongoClient感兴趣,但对任何常见的数据存储和python模块都感兴趣。(

如果需要,我应该如何修改下面的例子来净化输入?

from sqlalchemy import create_engine # requires module: psycopg2
import urllib.parse
import pandas as pd
import getpass
CONSTANT_QUERY_STRING = "SELECT * FROM table1;"
DB_URI = 'postgresql://{db_user}:{db_password}@postgres.acme.com:5432/acme_db'
class DbConnector:
def __init__(self, db_uri, db_user, db_password):
self.uri = db_uri.format(db_user=db_user, db_password=urllib.parse.quote_plus(db_password))
def get_data(self, query):
engine = create_engine(self.uri)
df = pd.read_sql_query(query, con=engine)
engine.dispose()
return df
if __name__ == "__main__":
userid = input('User: ')
password = getpass.getpass('Password for {}:'.format(userid))
df = DbConnector(DB_URI,userid,password).get_data(CONSTANT_QUERY_STRING)
if df:
print("Here's your data!")
print(df)

与任何类型的注入一样,这取决于攻击者能够注入的特殊字符和可接受的URI格式。假设我注入以下值:

用户名:用户

密码:password@malicious.server.com:5432/acme_db?

password@malicious.server.com:5432/acme_db#

结果会是什么?

postgresql://user:password@恶意的.server.com:5432/ame_db@postgres.acme.com.5432/acme_db

postgresql://user:password@恶意的.server.com:5432/acme_db#@postgres.acme.com:5432/acme_db

您的应用程序将连接到另一个数据库,行为可能会被完全修改。我不知道这些URI格式是否会被接受,但问题是:为什么要冒险

你知道什么是有效的用户名和密码结构,只需验证它并编码你允许的特殊字符(如果你想在密码中允许任何字符(。URI编码可能会完成这项工作。

相关内容

  • 没有找到相关文章