Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
sqlite: restrict valid authz code
  • Loading branch information
araujogui committed Sep 23, 2025
commit 27148962813326ab84772a7355fafe593a1868b3
18 changes: 12 additions & 6 deletions src/node_sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ int DatabaseSync::AuthorizerCallback(void* user_data,

if (try_catch.HasCaught()) {
// If there's an exception in the callback, deny the operation
// TODO: Rethrow exepction
// TODO: Rethrow exception
Comment thread
araujogui marked this conversation as resolved.
Outdated
return SQLITE_DENY;
}

Expand All @@ -1939,13 +1939,19 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
return SQLITE_DENY;
}

if (result->IsNumber()) {
double num_result = result.As<Number>()->Value();
return static_cast<int>(num_result);
if (!result->IsNumber()) {
return SQLITE_DENY;
}

double num_result = result.As<Number>()->Value();
int int_result = static_cast<int>(num_result);
Comment thread
araujogui marked this conversation as resolved.
Outdated

if (int_result == SQLITE_OK || int_result == SQLITE_DENY ||
int_result == SQLITE_IGNORE) {
return int_result;
}

// Default to OK if the result isn't a number
return SQLITE_OK;
return SQLITE_DENY;
}

StatementSync::StatementSync(Environment* env,
Expand Down
35 changes: 28 additions & 7 deletions test/parallel/test-sqlite-authz.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,34 @@ suite('DatabaseSync.prototype.setAuthorizer()', () => {
});
});

it('blocks operations when authorizer returns NaN', () => {
const db = new DatabaseSync(':memory:');
db.setAuthorizer(() => {
return '1';
});

assert.throws(() => {
db.exec('SELECT 1');
}, {
code: 'ERR_SQLITE_ERROR',
message: /not authorized/
});
});

it('blocks operations when authorizer returns a invalid code', () => {
const db = new DatabaseSync(':memory:');
db.setAuthorizer(() => {
return 3;
});

assert.throws(() => {
db.exec('SELECT 1');
}, {
code: 'ERR_SQLITE_ERROR',
message: /not authorized/
});
});

it('clears authorizer when set to null', (t) => {
const authorizer = t.mock.fn(() => constants.SQLITE_OK);
const db = new DatabaseSync(':memory:');
Expand Down Expand Up @@ -155,11 +183,4 @@ suite('DatabaseSync.prototype.setAuthorizer()', () => {
message: /The "callback" argument must be a function/
});
});

it('accepts null as valid input for clearing authorizer', () => {
const db = new DatabaseSync(':memory:');

// does not throw
db.setAuthorizer(null);
});
});
Loading