簡體   English   中英

Flask-sqlalchemy + pymssql防止從存儲過程參數中進行SQL注入

[英]Flask-sqlalchemy + pymssql prevent SQL injections from Stored Procedure params

我的下一條路線非常好:

@home_app.route('/<id>', methods=['GET', 'POST'])
def home(id):
    query = "DECLARE @return_value int, @EXIST bit EXEC @return_value = [dbo].[SP_CHECK_ID] @ID = N'" + id +"', @EXIST = @EXIST OUTPUT SELECT @EXIST as N'@EXIST'"
    result = db.session.execute(query, bind=db.get_engine(app, 'second_db'))
    exist = []
    for row in result:
        exist.append(row['@EXIST'])
    return "Exist? " + str(row['@EXIST'])

問題在於,由於該參數,它可能容易受到SQL注入的攻擊。 為了解決這個問題,我嘗試了:

query = """
        DECLARE @return_value int, @EXIST bit
        EXEC @return_value = [dbo].[SP_CHECK_ID] @ID = N':id',
        @EXIST = @EXIST OUTPUT
        SELECT @EXIST as N'@EXIST'
        """
result = db.session.execute(query, {'id': id}, bind=db.get_engine(app, 'second_db'))

但我得到一個錯誤:

sqlalchemy.exc.ProgrammingError: (pymssql.ProgrammingError) (102, b"Incorrect syntax near '179'.DB-Lib error message 20018, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n") [SQL: "DECLARE @return_value int, @EXIST bit EXEC @return_value = [dbo].[SP_CHECK_ID] @ID = N'%(id)s', @EXIST = @EXIST OUTPUT SELECT @EXIST as N'@EXIST'"] [parameters: {'id': '179'}]

我嘗試了其他方法:

query = """
        DECLARE @return_value int, @EXIST bit
        EXEC @return_value = [dbo].[SP_CHECK_ID] @ID = N'%s',
        @EXIST = @EXIST OUTPUT
        SELECT @EXIST as N'@EXIST'
        """
result = db.session.execute(query, id, bind=db.get_engine(app, 'second_db'))

但是我得到了:

AttributeError: 'list' object has no attribute 'keys'

我也嘗試過

from sqlalchemy.sql import text
query = text(...)

和使用? 而不是%s,但出現了相同的錯誤。

使用占位符的好處之一是,您不需要-也不應該-手動引用。 所以當你包括

""" ... N':id' ... """

在您的查詢中可能呈現為

""" ... N''179'' ... """

等等,具體取決於您的參數的類型等。然后,解決方法是刪除引號,並讓SQLAlchemy / DB-API驅動程序處理所有這些:

query = """
        DECLARE @return_value int, @EXIST bit
        EXEC @return_value = [dbo].[SP_CHECK_ID] @ID = :id,
        @EXIST = @EXIST OUTPUT
        SELECT @EXIST as N'@EXIST'
        """
result = db.session.execute(
    query, {'id': id},
    bind=db.get_engine(app, 'second_db'))

命名的占位符樣式是由text()構造提供的與后端無關的SQLAlchemy抽象。 如果您省略了Session.execute() ,它將隱式包裝文本SQL。 %s? 等是DP-API專用的占位符樣式。 pymssql似乎使用百分比樣式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM