Skip to content
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

Basic support for prepared statements in postgres, sqlite3 and mysql. #99

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

fcr--
Copy link

@fcr-- fcr-- commented Nov 22, 2018

With this modification we can enjoy the security benefits of having
prepared-statement-alike additional parameters. To do this, the
additional parameters should be passed after the statement in the
execute method.

This means that a new prepared statement will be created on each
execute call, so don't expect a huge performance increase. This is
done for safety reasons.

fcr-- added 4 commits May 31, 2018 02:24
With this modification we can enjoy the security benefits of having
prepared-statement-alike additional parameters.  To do this, the
additional parameters should be passed after the statement in the
execute method.

This means that a new prepared statement will be created on each
execute call, so don't expect big a performance increase.

Maybe in a distant future a LRU cache of prepared statements could be
added.
As in SQLite3, we now support prepared-statements-alike passing of
optional parameters by using the PQexecParams function, and since adding
support for binary types is not an easy task, any argument is converted
to a string before being sent and converted back to the expected type by
PostgreSQL... in any case this is better than nothing.

You may want to use a cast ``::type'' if it's not inferred. Example:

> db = require'luasql.postgres'.postgres():connect('')
> assert(db:execute('create table t(a int)'))
> assert(db:execute('insert into t values($1)', 17))
> res = assert(db:execute('select $1+$2::int, a from t where a>$1', 3, 4))
> =res:fetch()
7	17
  Since sqlite3_bind_text is binary safe, binding as text can be done
  without worries.
@fcr--
Copy link
Author

fcr-- commented Nov 23, 2018

MySQL support is on the way, but it requires way more changes since the methods for row access are all different. Done!

  This eliminates the need for escaping parameters, since now they
  can be specified as additional arguments to execute.
@fcr-- fcr-- changed the title Basic support for prepared statements in postgres and sqlite3. Basic support for prepared statements in postgres, sqlite3 and mysql. Nov 23, 2018
@blumf
Copy link
Contributor

blumf commented Nov 23, 2018

This is great news, I'll have a look at getting the ODBC and Firebird drivers working with the non-table parameters style soon.

Do you have any plans to expose prepared statements? It's very useful when doing batch work.

  This function can be used by all the drivers simplifying
  the logic, requiring only to implement conn:prepare(sql)
  and stmt:execute(...).
@fcr--
Copy link
Author

fcr-- commented Nov 24, 2018

@blumf Yes, I'm currently implementing those changes into the mysql drivers. Others will follow!
Btw, I've just added a generic luasql_conn_execute function that could be used for all the drivers.

@lionkor
Copy link

lionkor commented Nov 30, 2022

I don't wanna be annoying, but is this ever getting merged? Do you need help merging it?

@eggdropsoap
Copy link

I too am wondering if this will ever be merged! In late 2014 I was working on a lightweight blogging engine written in lua, when I discovered during coding of the comment form that luasql would make the engine vulnerable to SQL injections. SQL injections are a fatal security flaw for a blogging engine, so I shelved the project.

I just came back to the project today, thinking of resurrecting it, but prepared statements are still unsupported. Using lua + MySQL for anything that involves untrusted input really needs this feature.

@Lort533
Copy link

Lort533 commented Apr 19, 2023

I too am wondering if this will ever be merged! In late 2014 I was working on a lightweight blogging engine written in lua, when I discovered during coding of the comment form that luasql would make the engine vulnerable to SQL injections. SQL injections are a fatal security flaw for a blogging engine, so I shelved the project.

I just came back to the project today, thinking of resurrecting it, but prepared statements are still unsupported. Using lua + MySQL for anything that involves untrusted input really needs this feature.

Perhaps make a function that acts like prepare (fake prepare), finish your project in development environment only and if prepared statements ever come, you will change this one function only (or find and replace in all files).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants