Fork me on GitHub
#sql
<
2021-12-04
>
slipset20:12:15

So, if one uses https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc/sql.clj#L31 and does (insert! conn "bobby-tables" map-from-evil-user) is there a way for that map to contain keys or values which would lead to sql-injection, ie, does next-jdbc perform any, some, sufficient sanitation of the map-from-evil-user?

slipset20:12:08

(or use prepared statements in a way that elimitates sql-injection all together)

seancorfield20:12:08

@slipset I just read over the code in next.jdbc.sql.builder and I think I could construct a hash map with keys that could lead to injection... So I guess we need an issue to get that fixed 😐

seancorfield20:12:22

The next.jdbc.sql ns constructs SQL strings, so that's where the danger comes in. If you don't use that ns, you're in control of the actual SQL.

slipset20:12:56

Ok, thanks!

Jakub HolĂ˝ (HolyJak)20:12:42

I guess I can leverage col-fn to make my own sanitizations, right? The question is, what can next.jdbc do? It cannot use prep.stmt. for the column names and I am not sure there is a cross-db safe way to ensure the strings are safe. Unless the sql standards specifies valid chars for names and all impls follow it.

seancorfield21:12:19

HoneySQL also has to deal with this so I can use the same approach.

seancorfield21:12:20

suspicious #";"]
    (when-not *allow-suspicious-entities*
      (when (re-find suspicious entity)
        (throw (ex-info (str "suspicious character found in entity: " entity)
                        {:disallowed suspicious}))))

seancorfield21:12:30

It probably ought to disallow ' and the various stropping characters (`[ ] "` and the backtick (MySQL).

slipset21:12:17

While we’re here. From reading the code, it seems like for-insert creates a prepared-statement kind’a sql-string, whereas the https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc/sql/builder.clj mentions “SQL string” and not prepared statement. I think it would be nice if the docstring mentioned that it’s a prepared statement being constructed?

seancorfield21:12:36

The docs do say "Under the hood, whenever you ask next.jdbc to execute some SQL (via plan, execute!, execute-one! or the "friendly" SQL functions) it calls prepare to create a java.sql.PreparedStatement, adds in the parameters you provide, and then calls .execute on it." but I guess I could make that clearer in the docstrings too.

seancorfield21:12:04

And those builders do create "SQL strings".

slipset21:12:10

Fair enough.

seancorfield21:12:25

The builders just return ["SQL string" param1 param2 ..] and the next.jdbc.sql functions take those and call execute! or execute-one! and those functions create PreparedStatement objects.

seancorfield21:12:02

(I guess those docstrings could be more specific about the use of PreparedStatements 🙂 )