You use libraries with safe apis that make it easy to do the right thing and hard to do the wrong thing. Often this means you generate some sort of data structure which gets serialized into html by a library as a last step (e.g. React, but there are lots of other examples).
If you're always using safe apis, its really easy to verify that you dont do the wrong thing (e.g. via static analysis, or even grep. Browsers are even now suporting trusted types to dynamically verify this at runtime)
I remember back in the days when SQL injections were a big thing. I was a newb and had no idea what I was doing, but I was using a scheme library that created the queries by something akin to format strings (or was it something like quasiquoted s-expressions? It is almost 20 years ago). Anyway, it did the right thing: it escaped everything.
The result? The website of my little diablo 2 clan was the only one in my group of friends that did not get hacked. Due to me using an obscure library that did the right thing in a language nobody liked. It wasn't any victory of mine. Had I used PHP I would have been just as pwned as my friends.
>Had I used PHP I would have been just as pwned as my friends.
This is a myth, the issue is if you learn by Google instead of using something like a book. All languages and libraries (that I used) allow you to run raw sql if you need and all books/good learning materials when introducing SQL will explain how to do the correct thing with escaping parameters or even nicer using bound paramters.
That was the thing I was trying to convey: what was offered for me was a safe API. The things all the PHP tutorials of 2001 taught was "glue strings together and it will do what you want".
That was the knowledge offered for us 13 years olds wanting to write a discussion board for our game groups. I think it is a lovely example of "the simple thing should be the safe thing, and if you need more there should be ample warning". That was not the case of PHP 4.0.
Anecdote: the Swedish PHP book (I recall there being only one) that most of us got taught the string building approach without any escaping. The oldest things I can find Googling now are from 2007 and are almost all safe, either through PDO or a safe mysqli interface.
But this is not a language issue but some educational problem, it depends on luck if you land on some bad book or tutorial. If the language offers performance it must give me access to unsafe stuff like run raw SQL.
Of course. I am trying to find it now, but I recently used a sqlite library where, barring bugs in escaping, there were no way to execute SQL queries in the "simple API" with strings that were not compile time constants. A dynamically generated string would be refused with a clear error message pointing to the correct part of the manual.
The raw queries were hidden in a sqlite3/DANGEROUS library. Despite doing things like stepping queries, bypassing the statement cache or mucking around and changing parameterized queries I didn't have to touch the DANGEROUS API.
The problem is most libraries/frameworks also has just outputting option and those are valid for a lot of use case (system generated id and such). I guess one option is never allowing any call to that even if you know it's valid.
The trouble comes is in an existing code base if you know 95% of those use are valid but to pass the check you know have to migrate that all and do QA.
It depends a lot on the library I guess, does it make it easier to do the right thing or not.
If you're always using safe apis, its really easy to verify that you dont do the wrong thing (e.g. via static analysis, or even grep. Browsers are even now suporting trusted types to dynamically verify this at runtime)