-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to force use of Extended Queries #3214
Add option to force use of Extended Queries #3214
Conversation
@brianc do you have any suggestions where tests could be added for this? |
Can you explain what the safety benefit is? I didn’t see anything stick out in gajus/slonik#595 (especially) or gajus/slonik#601. |
I believe the benefit is that you wouldn't be able to accidentally execute multiple statements. |
Right, how is that a benefit? Feels more like a false sense of security. Looking at gajus/slonik#595 again, I assume there was some user-provided- |
It provides a guarantee that only a single statement can be executed. At the moment, no one is stopping someone from doing: await client.query('SELECT 1; SELECT 2') ... and if that's intentional, that's great. However, if a library is explicitly designed to handle only single statements (such as Slonik), then this behavior is undesirable and can produce unexpected results and/or create security vulnerabilities. |
I don’t think this is necessarily a bad option to add, but it’d be nice to have concrete explanations of the motivations. What security vulnerabilities? Are unexpected results maybe better addressed by checking if the result is an array? |
Suppose someone had a query written this way (obviously, not something they should be doing it), then the ability to execute multiple statements at once is going to allow for a lot more harm than if it wasn't.
Slonik already does that, but that happens after the query is executed, so it does not entirely prevent the potential harm. |
This could work, but only if every query was wrapped in its own transaction. An extra transaction seems like it would be more overhead than forcing Extended Query protocol, but I haven't measured. |
Hey @charmander sorry fo the delay here - @alxndrsn contacted me via email about this - we're gonna try to use the security vulnerability section here I just turned on to discuss the details: As far as this PR - looks good to me, but I'd suggest writing a test for it. Something as simple as use |
+1 to adding something like this and the unintended multi-command execution prevention is a perfect example of why. The PGJDBC driver has something similar but rather than a boolean, it has a string property to pick which query mode to use. See Having it be a string rather gives someone in the future the option of forcing a "simple" mode or something else that comes up in the backend server (v.s., being stuck with a bunch of orthogonal boolean flags). Note that I'm not suggesting adding any handling for a "force simple" mode. Just replacing the boolean flag with There's a lot of funky stuff the PGJDBC driver does to try to normalize the query modes. Things like automatically splitting SQL statements separated by a So having separate modes to force the driver to operate in a particular way are fine, but there should never be anything more added as result of enabling them. Just change how things operate on the wire and if someone's app breaks, it's up to them to deal with the ramifications of the mode change. Also, there are some situations where you can't run in extended mode. IIRC, once you enable wal sender mode for the connection you can only send simple mode commands. It wouldn't be a problem for normal applications as that's an unusual situation, but it is a valid use case for use purely simple mode. |
@sehrope all that feedback is awesome - thank you! Yea I kinda like
haha yeah I am pretty firm on the "do not modify the users query text input at all under any circumstances, just pass it in and let it fly" - even sometimes I regret the type coercion on the input parameters...but some decisions from 14 years ago are too costly to break and too innocuous to worry about.
yeah we discussed several different approaches to this & this one is the one we came up with that is 100% backwards compatible and likely the least disruptive. For now we'll keep the query mode as |
Right, that suggestion was only in reference to the “correctness” part. Seems like it’s pretty much all about security. As far as security goes, I’m used to treating any SQL injection as equivalently fatal, but it looks like this might actually be a useful mitigation in the described situation. (Not that my not being able to find any way to escape the Anyway, yeah, this seems good to add as an option with a nice, descriptive enumerated value. |
Nice! Thanks @charmander - tomorrow I'll do either an addon to this PR or replacement one to add the string based option. The original author is out and AFK for a couple days, so I'll just drive it home w/ documentation & tests as well. |
Found a little time (¬: I've updated the PR with a test, and to change the boolean to a string, but the test is currently failing with the native bindings. |
I can pull down your branch & take a look at it here a bit l8r today. Weird its not throwing an error. |
Could this be the cause? |
yah that's it - should be an easy fix, I'll just need to do a PR and minor version bump over there. I should probably pull that lib into this monorepo as it rarely (never?) changes by itself. |
Is there a chance of this getting released without waiting until |
gonna move pg-native over here today if i can swing it...working on it now. had to upgrade some stuff in node-libpq for it to build on my machine (node v22) |
Heyo! Got it merged - will do a release here in a few min. |
Thank you |
In some circumstances, e.g. gajus/slonik#595, gajus/slonik#601, it can add safety to force use of the Extended Query protocol.