Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If BeyondTrust had just used it as part of a postgres query string, the escape function would have been sufficient.

That's completely false. The following (pseudo code because working with C strings is verbose and beside the point) with nothing to do with psql should be fine:

  PQexec(conn, "SELECT * FROM user WHERE nickname = '" + PQescapeString(user_input) + "';")
but thanks to the vulnerable PQescapeString(), the following user_input

  "\xc0'; DROP TABLE user"
would fuck it up. That's just the failed escape function leading to a classic SQL injection. Using psql makes it worse because psql can execute additional non-SQL commands, but this escape function is not "fine" at all with or without psql.

> With parameterized queries, the escaping and the query parsing are done in the same place

Again, wrong. For parametrized queries, params don't go through serialization because they don't need to hit the parser, there's no "escaping" whatsoever.



> but thanks to the vulnerable PQescapeString(), the following user_input would fuck it up

Nope. To quote: https://www.rapid7.com/blog/post/2025/02/13/cve-2025-1094-po...

> Because of how PostgreSQL string escaping routines handle invalid UTF-8 characters, in combination with how invalid byte sequences within the invalid UTF-8 characters are processed by psql

If you just pass it to postgres over a normal query, postgres will reject an invalid byte sequence in the query with an error, refuse to even parse the query, and thus you won't get a SQL injection. It's just that psql didn't hard-error on invalid utf-8, even though postgres did.

That's why the escape function was suitable for postgres, both the escape function and postgres's query parser assume invalid byte sequences are, you know, invalid.

> For parametrized queries, params don't go through serialization because they don't need to hit the parser, there's no "escaping" whatsoever.

You're right of course, I used imprecise language that everyone understands, and you're choosing to read critically in order to be combative.

You don't have to be so combative.


Sure, the blog post didn't mention PQexec would reject it, so I assumed it would be accepted. Turns out it's a narrowly dodged bullet, I'm wrong on that. But having to chain two vulnerabilities together to own the system doesn't make either vulnerability less of a vulnerability. The escape function was wrong, period, another level of defense helped in this case, but "the documentation for the postgres escape function didn't say it escaped input for psql" is a bullshit excuse (it definitely didn't achieve the documented goal of "escaping special characters so that they cannot cause any harm"), putting "CVE" in quotes and blaming it all on the user is wrong.

> I used imprecise language that everyone understands, and you're choosing to read critically in order to be combative.

No, your "imprecise language" is a fundamental and quite dangerous misunderstanding that could easily lead to more vulnerabilities like this one ("PQexecParams = PQexec + PQescapeString, amiright? I'll just use the latter"). Maybe you didn't misunderstand yourself, maybe you did, but it's 100% misleading for readers not familiar with db internals.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: