
On Sat, Feb 22, 2020 at 2:38 PM Bruce Leban <bruce@leban.us> wrote:
First, as to SQL specifically, writing literal SQL in code is a bad idea. It's easy to have bugs, especially sql injection. You should use an ORM at the very least a SQL builder. Instead of:
sf"select * from sometable where name = '{userName}'"
you would write something like:
sql.query(SomeTable).filter_by(name=userName).all()
I disagree with the blanket statement here. Writing literal SQL in code is fine - but you have to treat it *as* code. It is code. It is not something you blindly interpolate strings into. If it's just a constant string, with no interpolation whatsoever, then you're fine. If you're building it out of pieces that you maintain entire control over (for instance, having a list of column names, which you then join with commas and slap in there), then that's also fine. It's only when you put uncontrolled data into an SQL query that you have a problem. In your example: con.execute("select * from sometable where name = ?", (username,)) would be a perfectly safe way to work with a table using literal SQL queries, since there is no interpolation of user data.
And I believe the same thing applies to HTML and just about anything else that has a complicated enough syntax that this idea would be useful for.
Second, if I had a strong reason to do something like this, I'd want to use a function that enabled me to add run-time sanity checking (at least during development and testing phase):
_html_(f"This is a <b><i>{adverb} bad</b></i> example.")
and in production that function would just return the value untouched.
If you're going to do the validation, do it in production as well. That's where you're more likely to get attackers. But even better is, again, parameterization. ChrisA