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

Enable load_extension() function? #1065

Open
davidkaufman opened this issue Sep 12, 2023 · 3 comments
Open

Enable load_extension() function? #1065

davidkaufman opened this issue Sep 12, 2023 · 3 comments

Comments

@davidkaufman
Copy link

Hi!

I am loading sqlite extensions at connection time using the db.loadExtension() API but would rather use the SQL load_extension() function to load them at runtime.

As the SQLite docs above say say, allowing users to call this function in SQL is disabled by default, as it opens up a potential SQL injection vulnerability. Is there a way to call this sqlite C-API function below to re-enable it for use through better-sqlite3?

https://www.sqlite.org/c3ref/enable_load_extension.html

int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
So as not to open security holes in older applications that are unprepared to deal with extension loading, and as a means of disabling extension loading while evaluating user-entered SQL, the following API is provided to turn the sqlite3_load_extension() mechanism on and off.

Extension loading is off by default. Call the sqlite3_enable_load_extension() routine with onoff==1 to turn extension loading on

Thanks in advance!

@Prinzhorn
Copy link
Contributor

I am loading sqlite extensions at connection time using the db.loadExtension() API but would rather use the SQL load_extension() function to load them at runtime.

db.loadExtension() literally calls load_extension()

NODE_METHOD(JS_loadExtension) {
Database* db = Unwrap<Database>(info.This());
v8::Local<v8::String> entryPoint;
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> filename);
if (info.Length() > 1) { REQUIRE_ARGUMENT_STRING(second, entryPoint); }
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
char* error;
int status = sqlite3_load_extension(
db->db_handle,
*v8::String::Utf8Value(isolate, filename),
entryPoint.IsEmpty() ? NULL : *v8::String::Utf8Value(isolate, entryPoint),
&error
);
if (status != SQLITE_OK) {
ThrowSqliteError(db->addon, error, status);
}
sqlite3_free(error);
}

SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION is also set (else db.loadExtension() wouldn't work)

int status = sqlite3_db_config(db_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);

I'm confused what you actually want, maybe you can give a code example of the new API that you are suggesting? What exactly are you missing that you cannot do right now?

@davidkaufman
Copy link
Author

davidkaufman commented Sep 12, 2023

Hi @Prinzhorn thanks for the reply!

What I meant was I'd like to allow our users to load any extension (at any time) by calling the SQL function from within a sql query, e.g.:

SELECT load_extension('./re.so'); 

currently, issuing a sql query that calls this function results in the error:

- SqliteError: not authorized

To allow the use the load_extension() inside a SQL command the docs linked above say you have to:

Call the sqlite3_enable_load_extension() routine with onoff==1

so apparently better-sqlite3 isn't passing that onoff parameter, which defaults to 0

@Prinzhorn
Copy link
Contributor

Oh, thanks for clarifying, I didn't pay enough attention. Makes sense that you could optionally enable that for a Database instance.

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

No branches or pull requests

3 participants