Skip to content

fix: validate transaction behavior to prevent SQL injection in SQLite sessions (#5512)#5526

Open
guoyangzhen wants to merge 3 commits intodrizzle-team:mainfrom
guoyangzhen:fix-sql-js-behavior-injection
Open

fix: validate transaction behavior to prevent SQL injection in SQLite sessions (#5512)#5526
guoyangzhen wants to merge 3 commits intodrizzle-team:mainfrom
guoyangzhen:fix-sql-js-behavior-injection

Conversation

@guoyangzhen
Copy link
Copy Markdown

🔗 Linked issue

Closes #5512

📝 Description

The config.behavior field is directly interpolated into sql.raw() without validation in SQLite session files:

this.run(sql.raw(`begin${config?.behavior ? ' ' + config.behavior : ''}`));

If user input flows into SQLiteTransactionConfig.behavior, it goes straight into raw SQL. SQLite BEGIN only accepts DEFERRED, IMMEDIATE, or EXCLUSIVE — anything else should be rejected.

Changes

Added whitelist validation in all three affected files:

  • drizzle-orm/src/sql-js/session.ts
  • drizzle-orm/src/expo-sqlite/session.ts
  • drizzle-orm/src/d1/session.ts

Each file now has:

const VALID_TX_BEHAVIORS = new Set(['deferred', 'immediate', 'exclusive']);

function validateTxBehavior(behavior: string | undefined): string {
  if (behavior && !VALID_TX_BEHAVIORS.has(behavior)) {
    throw new Error(`Invalid transaction behavior: "${behavior}". Must be one of: ${[...VALID_TX_BEHAVIORS].join(', ')}`);
  }
  return behavior ? ` ${behavior}` : '';
}

The validated output is used instead of raw interpolation:

this.run(sql.raw(`begin${validateTxBehavior(config?.behavior)}`));

Why this matters

While behavior is typically a developer-controlled config value, defense-in-depth is important. A validation layer prevents:

  • Accidental typos causing cryptic SQLite errors
  • Potential SQL injection if user input ever reaches this field
  • Undefined behavior from invalid transaction modes

The throw provides a clear error message rather than letting invalid SQL reach the database.

@guoyangzhen
Copy link
Copy Markdown
Author

Hi, just checking in on this PR. Happy to make any changes if needed. Thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant