34
loading...
This website collects cookies to deliver better user experience
sqlalchemy
sqlalchemy
to prevent SQL injection leads.py
to figure out its usage. It acts as an api route "/leads" that serves data or creates new data. query = text(
"""
SELECT
{columns}
FROM lead_tag lt
JOIN leads l on l.id = lt.lead_id
JOIN tags t on t.id = lt.tag_id
WHERE to_tsvector(l.company_name) @@ to_tsquery('{search}')
AND lt.tag_id = :tag_id
ORDER BY ts_rank(to_tsvector(company_name), '{search}')
LIMIT :limit
OFFSET :offset
""".format(
columns=",".join("l." + f for f in DEFAULT_LEAD_FIELDS),
search=search,
)
)
sqlalchemy
which can turn this query into object and protect our server from injection. sqlalchemy
expressions, I tried to change as little as possible by working around with the existing code res = connection.execute(query, **query_args)
with db.get_connection() as connection:
res = connection.execute(query, **query_args)
response_body = []
count = 0
for row in res:
# TODO: handle potential errors if the user chooses a field not in the row
lead = {field: getattr(row, field) for field in include}
if drop_null:
lead = {k: v for (k, v) in lead.items() if v is not None}
response_body.append(lead)
count += 1
return {
"count": count,
"query": {
"page": page,
"perpage": perpage,
},
"leads": response_body,
}, 200
search
interpolation into bound parameters similar to LIMIT
and OFFSET
.query = text(
"""
SELECT
{columns}
FROM lead_tag lt
JOIN leads l on l.id = lt.lead_id
JOIN tags t on t.id = lt.tag_id
WHERE to_tsvector(l.company_name) @@ to_tsquery(:search)
AND lt.tag_id = :tag_id
ORDER BY ts_rank(to_tsvector(company_name), :search)
LIMIT :limit
OFFSET :offset
""".format(
columns=",".join("l." + f for f in DEFAULT_LEAD_FIELDS),
)
)
query_args = {
"limit": limit,
"offset": offset,
"tag_id": tag_id,
"search": search,
}
execute
method with its arguments query_args
, if injection occurs, it will auto-escape.