Skip to content

fix(webapp): escape realtime tags filter to prevent SQL injection (#3…#4129

Closed
Purvi09 wants to merge 1 commit into
triggerdotdev:mainfrom
Purvi09:fix/3739-realtime-tags-sql-injection
Closed

fix(webapp): escape realtime tags filter to prevent SQL injection (#3…#4129
Purvi09 wants to merge 1 commit into
triggerdotdev:mainfrom
Purvi09:fix/3739-realtime-tags-sql-injection

Conversation

@Purvi09

@Purvi09 Purvi09 commented Jul 3, 2026

Copy link
Copy Markdown

Closes #3739

✅ Checklist

  • I have followed every step in the contributing guide
  • The PR title follows the convention.
  • I ran and tested the code works

Testing

The realtime runs stream builds a SQL WHERE clause that is passed to Electric as the where search param. In streamRuns(), user-supplied tags were interpolated straight into a single-quoted SQL string literal with no escaping, so a tag containing a ' could break out of the literal and inject SQL (e.g. ?tags=test' OR '1'='1).

This PR escapes each tag by doubling embedded single quotes before it is wrapped in the literal, which is sufficient because Postgres runs with standard_conforming_strings on (the single quote is the only character that can terminate the literal). The other interpolated values in the same file (environment.id, runId, batchId, createdAt) are system-generated IDs/dates that cannot contain a quote, so they are not an injection vector.

Added a unit test (apps/webapp/test/realtimeClientEscapeSqlStringLiteral.test.ts) covering:

Run it with:

pnpm run test --filter webapp ./test/realtimeClientEscapeSqlStringLiteral.test.ts --run

Manual verification of the fix: with the escaped clause, ?tags=test' OR '1'='1 produces the literal 'test'' OR ''1''=''1', which Postgres reads as a single (nonexistent) tag name rather than executable SQL — the filter no longer breaks out.


Changelog

Escape single quotes in the user-supplied realtime tags filter so they cannot break out of the SQL string literal, closing a SQL injection vector in the /realtime/v1/runs stream.


Screenshots

N/A — server-side change, no UI.

💯

@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 48fd80b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/Purvi09/trigger.dev/new/fix/3739-realtime-tags-sql-injection?filename=.changeset/great-streets-change.md&value=---%0A%22webapp%22%3A%20patch%0A---%0A%0Afix(webapp)%3A%20escape%20realtime%20tags%20filter%20to%20prevent%20SQL%20injection%20(%233%E2%80%A6%0A)

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Hi @Purvi09, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions Bot closed this Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7de66bb7-3a38-4318-85f2-d20bd18d6332

📥 Commits

Reviewing files that changed from the base of the PR and between 0f349dd and 48fd80b.

📒 Files selected for processing (3)
  • .server-changes/fix-realtime-tags-sql-injection.md
  • apps/webapp/app/services/realtimeClient.server.ts
  • apps/webapp/test/realtimeClientEscapeSqlStringLiteral.test.ts

Walkthrough

This change addresses a SQL injection vulnerability in the realtime tags filter. A new exported function, escapeSqlStringLiteral, doubles single quotes in string values. RealtimeClient.streamRuns now escapes each user-supplied tag using this function before embedding it into the SQL where clause used to query Electric. A Vitest test suite validates the escaping behavior, including neutralization of a previously reported injection payload. A changelog entry documents the fix.

Changes

Area Change
SQL escaping Added escapeSqlStringLiteral helper function
Realtime tags filtering Applied escaping to tags before SQL interpolation in streamRuns
Tests Added test suite covering escaping behavior and injection payload
Changelog Added entry documenting the SQL injection fix

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant RealtimeClient
  participant escapeSqlStringLiteral
  participant SQLQuery

  Caller->>RealtimeClient: streamRuns(params.tags)
  RealtimeClient->>escapeSqlStringLiteral: escape each tag
  escapeSqlStringLiteral-->>RealtimeClient: escaped tag string
  RealtimeClient->>SQLQuery: build runTags where clause with escaped tags
Loading

Related issues: References issue #3739 (SQL injection payload used in tests).

Suggested labels: security, bug fix, webapp

Suggested reviewers: matt-aitken, ericallam

Poem

A quote came knocking, sly and bent,
Trying to break where clauses meant,
But doubled up, it lost its bite,
Escaped and tamed, all locked up tight.
A rabbit cheers this SQL fix delight! 🐇

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

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.

[Security/Medium]: SQL injection in realtime API via unescaped tags parameter

1 participant