Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 8 additions & 1 deletion src/workerd/api/sql.c++
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "actor-state.h"

#include <workerd/io/io-context.h>
#include <workerd/util/sentry.h>

#include <strings.h>

namespace workerd::api {

Expand Down Expand Up @@ -135,7 +138,11 @@ double SqlStorage::getDatabaseSize(jsg::Lock& js) {
}

bool SqlStorage::isAllowedName(kj::StringPtr name) const {
return !name.startsWith("_cf_");
if (name.startsWith("_cf_")) return false;
if (name.size() >= 4 && strncasecmp(name.begin(), "_cf_", 4) == 0) {
LOG_WARNING_PERIODICALLY("SQL identifier matches reserved _cf_ prefix case-insensitively");
}
return true;
}

bool SqlStorage::isAllowedTrigger(kj::StringPtr name) const {
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/tests/sql-test-tail.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const test = {
return acc;
}, {});
assert.deepStrictEqual(reduced, {
durable_object_storage_exec: 268,
durable_object_storage_exec: 272,
durable_object_storage_ingest: 1030,
durable_object_storage_getDatabaseSize: 3,
durable_object_storage_put: 18,
Expand Down
9 changes: 9 additions & 0 deletions src/workerd/api/tests/sql-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,15 @@ async function test(state) {
/access to _cf_KV.key is prohibited/
);

// Exercise logging for future _cf_ prefix restrictions (VULN-129365).
// Mixed-case _cf_ prefix triggers a warning log but is currently allowed.
sql.exec('CREATE TABLE _CF_log_test (name TEXT)');
sql.exec('DROP TABLE _CF_log_test');
// FTS5 virtual table with mixed-case _CF_ prefix triggers a warning log but is currently
// allowed. (Lowercase _cf_ already fails indirectly because FTS5 shadow tables are blocked.)
sql.exec('CREATE VIRTUAL TABLE _CF_fts_log_test USING fts5(content)');
sql.exec('DROP TABLE _CF_fts_log_test');

// Some pragmas are completely not allowed
assert.throws(
() => sql.exec('PRAGMA hard_heap_limit = 1024'),
Expand Down
4 changes: 4 additions & 0 deletions src/workerd/util/sqlite.c++
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,10 @@ bool SqliteDatabase::isAuthorized(int actionCode,
KJ_IF_SOME(moduleName, param2) {
if (strcasecmp(moduleName.begin(), "fts5") == 0 ||
strcasecmp(moduleName.begin(), "fts5vocab") == 0) {
auto& tableName = KJ_ASSERT_NONNULL(param1);
if (tableName.size() >= 4 && strncasecmp(tableName.begin(), "_cf_", 4) == 0) {
LOG_WARNING_PERIODICALLY("FTS5 virtual table uses reserved _cf_ prefix");
}
return true;
}
}
Expand Down
Loading