> On 24 Jun 2021, at 08:30, Scott Arciszewski <sc...@paragonie.com> wrote: > > On Wed, Jun 23, 2021, 9:23 PM Bruce Weirdan <weir...@gmail.com > <mailto:weir...@gmail.com>> wrote: > >> On Thu, Jun 24, 2021 at 3:41 AM Scott Arciszewski <sc...@paragonie.com> >> wrote: >>> The failure condition of this query is >>> "return all rows from the table already being queried", not "return >>> arbitrary data the attacker selects from any table that the >>> application can read". >> >> Imagine that was a DELETE rather than SELECT and the failure condition >> becomes 'the table is emptied'. >> It may have less disastrous consequences (depending on how good your >> backup / restore procedures are) compared to arbitrary reads you >> demonstrated, but it is still, quite clearly, a glaring security hole >> caused by user input in SQL query - AKA SQL injection in layman's >> terms. >> >>> it differs from Injection vulnerabilities in one >>> fundamental way: The attacker cannot change the structure of the SQL >>> query being executed. >> >> I would say replacing a column name with value is changing the >> structure of SQL query, and, basically, in exactly the way you >> describe SQL injection: confusing the code (column name) with data. >> >> I wholeheartedly welcome this RFC as it was originally proposed: >> is_literal() doing exactly what it says on the tin, without any >> security claims. But it has gone far from there real quick and now >> people can't even name the thing. >> >> >> -- >> Best regards, >> Bruce Weirdan mailto: >> weir...@gmail.com > > > > We can agree that it is a bug. We don't agree on the definition of SQL > injection. > > Changing a column name to a number (which prepared statements shouldn't > allow in the first place) is a bug. This changes the effect of the command, > but the *structure* of the query remains unchanged.
Hi Scott, I wrote that example where an integer could be dangerous. So firstly - just to clarify, because some replies seemed to be confused on the topic, as was literally mentioned in the original comment, it is definitely not correct behaviour - it’s a developer mistake that might work some of the time, and thus go unnoticed in testing. If you can show me a developer who’s never inadvertently passed the wrong parameter in some condition, I’ll show you an imaginary developer. Additionally - pointing out that this is a "developer error” doesn’t help your case. Using non-parameterised queries should already be a “developer error” for anyone who can walk and breathe at the same time - and yet that usage is being actively encouraged if this function supports integers. I’ve still seen zero responses about legitimate reasons this needs to support integers - giving people a shitty way to build an IN() clause is not legitimate. Parameterisation exists, and works. I don’t even understand why you mentioned prepared statements (I guess you meant using parameterised queries?) - the column name inherently can’t be parameterised - hence having to use a string substitution in the query. That part was weird and confusing, but not as odd as your claim that altering the query, so that it causes the where clause to become moot, is not an SQL Injection? REALLY? That’s your claim? I did a little research, and it turns out Wikipedia (https://en.wikipedia.org/wiki/SQL_injection#Technical_implementations <https://en.wikipedia.org/wiki/SQL_injection>), Cloudflare (https://www.cloudflare.com/en-au/learning/security/threats/sql-injection/ <https://www.cloudflare.com/en-au/learning/security/threats/sql-injection/>), and OWASP (https://owasp.org/www-community/attacks/SQL_Injection#example-2 <https://owasp.org/www-community/attacks/SQL_Injection>) all have examples with a `1=1` type query manipulation. Do you want to write and tell them that they’re all wrong, or should I ask them to call you? Also, while researching the specifics of what is considered an “SQL Injection” I came across an article, that talks specifically about the dangers of allowing user input (i.e. the thing `is_trusted` is meant to prevent) as a column or table identifier. It’s from this little organisation, you may have heard of them: “Paragon Initiative” (https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide <https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide>). I would absolutely make use of a function that tells me if the string given is in fact from something controlled by the developer. But once that same string can also include input from the request or the environment or whatever by nature of integers, the function becomes useless for the stated purpose. Cheers Stephen