-
-
Notifications
You must be signed in to change notification settings - Fork 61
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
What are the permitted ways to make prepared statement queries or inserts? Ie. To avoid SQL injection? Is it just JDBC? Postgres? #1829
Comments
I don't see any examples of anything that could protect against SQL injection there? My understanding is that to protect against SQL injection you need to prepare and finalize the query function the database will perform in terms of its operations and constraints (ie.
How does that work? I have read those Java snippets since a year ago and I still don't understand how they could be used. If you have:
How do you use the Java API? The only way I see is by the Rust server connecting to the Arcade server by JDBC. Which then again, means the only way to protect against SQL injection (which is really a critical thing we all need to do unless there is zero user written input) is by JDBC connection. And this is not commonly or clearly available. Why not at least Postgres too? Given there is more availability? It took me only a few hours (yeah, "only" 😬) to get Rust connected by Postgres. I was going to add it to the examples, but it now seems like a pointless method as it is not remotely safe. Or if we must do it by JDBC, can we get some better clarity on how? I see for example many JDBC drivers: https://www.codejava.net/java-se/jdbc/jdbc-driver-library-download I can wrap one into Rust, for example with this: https://lib.rs/crates/jni But I'm not sure what JDBC version I am supposed to be using. For something so critical, I don't think this is well explained. I don't get it. I used to think I just needed to come back to it later, and it would make sense eventually. But now I actually need it running. And now I have done HTTP requests in multiple languages (I posted several of the examples on the documentation), tonight I succeeded with Postgres requests. But I am still no closer. Any further thoughts? @lvca any thoughts as well? Thanks as always for any help. 👍 |
I don't think I can solve your problem(s), but here are some remarks that may hopefully help:
|
Our postgres driver implementation supports prepared statements. Look at: arcadedb/postgresw/src/main/java/com/arcadedb/postgres/PostgresNetworkExecutor.java Line 580 in 13ccc3e
@jonmdev have you tried using parameters with the Postgres driver? |
That was my original instinct as well. ie. Just do escaping and try to be safe. Probably you are right in many cases. But it seems like an game of Russian roulette. As I read more over the past few weeks, everything I have encountered has told me this approach is extremely dangerous. If you slip up or someone out-thinks you you can have a major data breach or the service could be wiped out. I am not so confident in myself in that manner. If your system requires allowing users to input text and then have that written into the database, the only certainly safe way everyone says is using prepared statements. For example, I asked ChatGPT something like if this was safe (eg. HTTP Request or Postgres Simple Query):
And it says over and over in different words same as every resource I see online including the official one above:
They suggest we need prepared statements such as:
Then they give examples of prepared (parameterized) queries like:
Even as I look at the API's for Postgres adapters they keep warning this constantly and every Stackoverflow thread I pull up says the same. So while it may not be so vulnerable as they say (based on your points), I think it is good enough for me now to read that enough that I am paranoid and do not wish to touch anything except by prepared/parameterized statements. Probably I suspect everyone should then just follow that approach as there is no harm and only safety and benefit. It is just then a matter of how we do it then to figure out, but I think it definitely ought to be the default approach to be safe. |
To my understanding this is not how parameters work, at least in ArcadeDB. A parameter is placed into the parameterized query or command as its type. For example |
That would be great @lvca. I am not sure how this would work, though. Because the documentation we have on Arcade says that Arcade only supports "simple" mode for Postgres. All the documentation I have on "simple postgres mode" suggests this does not permit parameterized/prepared statements but rather just plain string ones like HTTP. For example, the Postgres package I got working for simple mode with Rust looks like this in practice:
This package is the main one for Rust with >5 million downloads and is here: https://crates.io/crates/postgres You can see the documentation on Simple Queries here: https://docs.rs/postgres/latest/postgres/enum.SimpleQueryMessage.html?search=simplequery
So they are again warning us not to use this method as it only takes a string input. The prepared version (correct query method) is query, which does clearly allow parameters in the arguments, but this is then not "simple" mode. ChatGPT confirms this as well:
And their conclusion:
This then matches the Rust API. Thus if the Postgres system on your end allows parameterized queries, it does not require "simple" mode, or at least I believe these are two counteracting things. Thanks for any further thoughts. |
If this is a response to me: sorry, I was referring to the HTTP API here. |
Why prepared statements are needed
The documentation links to this practice document for SQL safety:
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
It states:
In other words, we absolutely need prepared statements, if users are writing their own inputs to our queries or inserts.
Postgres?
I thought this must be possible by Postgres connection as this allows prepared statements. I managed to get a Postgres connection working by Rust tonight. But then I came to understand, as per the documentation:
Simple query mode is no different than HTTP query. For example, in Rust with Postgres this is the same format of an HTTP Request (plain string, which is unsafe when you may have user written inputs):
Other practices like whitelisting input are not possible when users can type their own text inputs such as free entry text fields. Limiting characters to
a-z
,A-Z
,0-9
is also not possible when you have global users inputting every variety of unicode or emojis or punctuation.JDBC?
Is JDBC then the only way to perform prepared statements with Arcade? If so I think this should be better documented in the documentation.
Say from a Rust or Elixir server, which is interfacing to Arcade installed and running on a separate Ubuntu server - I can get a JDBC system working under my Rust server. Is that then my only choice to connect and query/insert to Arcade from there safely?
Whatever the answer, I think the options for prepared statements should be more clearly enumerated in the documentation, given how critical this is.
Are the options (whatever they are) ever likely to change as well? Thanks for any thoughts or clarification.
The text was updated successfully, but these errors were encountered: