Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果需要,在Python中防止连接字符串污染攻击_Python_Security_Sqlalchemy_Pymongo_Sql Injection - Fatal编程技术网

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

如果需要,在Python中防止连接字符串污染攻击,python,security,sqlalchemy,pymongo,sql-injection,Python,Security,Sqlalchemy,Pymongo,Sql Injection,我想在向数据库传递用户的用户ID和密码时返回预定义查询的结果 查询是常量,因此不是基本的SQL注入场景 但是,允许用户指定将.format()-ted到连接字符串中的用户名和密码是否会造成任何漏洞 (我发现它确实如此——我主要对sqlalchemy.create_engine和pymongo.MongoClient感兴趣,但对任何常见的数据存储和python模块都感兴趣。) 如果需要,我应该如何修改下面的示例来清理输入 from sqlalchemy import create_engine #

我想在向数据库传递用户的用户ID和密码时返回预定义查询的结果

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

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

(我发现它确实如此——我主要对
sqlalchemy.create_engine
pymongo.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格式。 假设我注入以下值:

用户名:user

密码: password@malicious.server.com:5432/acme\u db

password@malicious.server.com:5432/acme\u db#

结果会怎样

postgresql://user:password@恶意的.server.com:5432/acme\u db?@postgres.acme.com:5432/acme\u db

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

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

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