概述
在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()