概述
在Python后端開發中,有多庫提供了ORM接口能力,借助OO思想,數據庫中的表被映射為Python的類,類的對象代表數據表中的一行記錄,所有的DB操作都通過對象方法調用來實現,這些調用在底層被自動轉換成SQL語句,在轉換過程中,通常會采用parameter bind的方式保證生成的parameterized SQL不存在被注入的風險。
SQLAlchemy防注入原理
SQLAlchemy就是這樣一個具備ORM能力的DB操作Python庫,此外,該庫還支持開發者執行raw sql,並通過其提供的text對象實現params binding,從而防護SQL注入風險。
實例
使用flask搭建簡易api測試sql注入
使用原生sql未使用text對象
@app.route('/products',methods=['GET']) def products(): """ 原生sql接口 :return: """ val = request.args.get('val') sql = "SELECT * FROM goods WHERE price<={}".format(val) products = db.session.execute(sql).fetchall() return "產品列表為"+str(products)
正常訪問
sql注入成功拿到所有的
使用SQLAlchemy中text對象
@app.route('/products1',methods=['GET']) def products1(): """ text對象 :return: """ val = request.args.get('val') select_params_dict = { 'val':val } pre_sql = "SELECT * FROM goods WHERE price<=:val" bind_sql = text(pre_sql) products = db.session.execute(bind_sql,select_params_dict).fetchall() return "產品列表為"+str(products)
正常訪問
sql注入(未成功)
text對象的一些語法
like示例
select_params_dict = { 'name':"XXX" } pre_sql = """SELECT * FROM goods WHERE name LIKE '%' :name '%'""" bind_sql = text(pre_sql) products = db.session.execute(bind_sql,select_params_dict).fetchall()