Search code examples
pythonsecuritysqlalchemysql-injectionaiohttp

Is SQL injection protection built into SQLAlchemy's ORM or Core?


I'm developing an aiohttp server application, and I just saw that apparently it isn't able to use SQLAlchemy's ORM layer. So, I was wondering: if my application will only be able to use SQLAlchemy's core, is it still protected against SQL injection attacks?

My code is the following:

async def add_sensor(db_engine, name):
    async with db_engine.acquire() as connection:
        query = model.Sensor.__table__.insert().values(name=name)
        await connection.execute(query)

A comment on the accepted answer in this related question makes me doubt:

you can still use execute() or other literal data that will NOT be escaped by SQLAlchemy.

So, with the execute() used in my code, does the above quote mean that my code is unsafe? And in general: is protection against SQL Injection only possible with the SQLAlchemy ORM layer, as with the Core layer you'll end up launching execute()?


Solution

  • in your example above i dont see any variable beeing supplied to the database query. Since there is no user supplied input there is also no Sql Injection possible.

    Even if there would be a user supplied value as long as you dont use handwritten sql statements with sqlalchemy and instead use the orm model approach (model.Sensor.__table__.select()) as can be seen in your example you are secure against Sql Injection.

    In the end its all about telling sqlalchemy explicitely what columns and tables should be used to select and insert data from/to and keeping that separate from the data that is beeing inserted or selected. Never combine the data string with the query string and always use sqlalchemy orm model objects to describe your query.

    Bad way (Sql Injectable):

    Session.execute("select * form users where name = %s" % request.GET['name'])
    

    Good way (Not Sql Injectable):

    Session.execute(model.users.__table__.select().where(model.users.name == request.GET['name']))