An obligatory addendum from 2020:
Dealing with characters was proven to be inefficient and obsoleted
You must use prepared statements and forget about escaping, "dangerous characters" or any of that business.
Using parameterized queries is considered the only proper way to protect from SQL injections, for the reasons provided in the original answer below:
Which characters are actually capable of causing SQL injection in mysql
There are no such characters.
It isn't "characters" that cause the SQL injections, but improper formatting. Any character, depending on the circumstances, could be either "dangerous" or absolutely harmless. Limiting your protection to some subset is a dangerous delusion that will actually lead to SQL injection sooner or later.
There are two wrong statements in your question leading to confusion:
- We all know that we should use ... the appropriate replacement rules in order to prevent SQL injection in our applications.
This statement is wrong. Not replacement but formatting. The difference is essential. Replacement alone does not protect from injection attacks, while formatting does. Note that every distinct part of the query requires different formatting, which in turn is useless for any other part. Say there is another character, essential for injection protection - a backtick (`), but you didn't list it because it has nothing to do with string literals.
- the ' (single quote), \ (backslash), and " (double quote) all need to be escaped in order to prevent injection
That's a gravely wrong statement. Escaping does not prevent injection attacks. These characters need to be escaped in order to format strings and has absolutely nothing to do with injection attacks. While it is true that a properly formatted query part is invulnerable, the truth is - you have to format dynamic queries anyway, following syntax rules, not because of injection attacks. Your query will be invulnerable to attacks as a side effect.
Now you can see why your last statement:
why all of these other characters are vulnerable enough to be escaped via mysql_real_escape_string, as it is not immediately obvious to me.
is wrongly put:
It is string formatting rules require these characters, not whatever "vulnerability". Some of them are escaped just for convenience, some for readability, some for the obvious reason of escaping a delimiter. That's all.
To answer recent questions from comments:
I really want an answer to this, as PHP's mysql_real_escape_string does not quote these literals either.
Again: although in the mind of average PHP users mysql_real_escape_string() is strongly connected to whatever scary injection attack, in reality it isn't. There are no "dangerous" characters. Not a single one. There are some service characters with special meaning. They have to be escaped in some circumstances, depending on the context.
Thus, there is no connection between characters escaped by this function, and whatever "danger". The moment you start thinking that the purpose of mysql_real_escape_string() is to escape "dangerous" characters, you are indeed putting yourself in danger. While as long as you are using this function only to escape strings (and doing it unconditionally) - you may consider yourself safe (of course if you don't forget to format all other literals too, using their respective formatting rules)
I want to know if the "%" character can lead to anything more than extra results in a LIKE clause.
No.