From 56659b8c0aa9d232bdc330f5d799fac215c1c70b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:37:43 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITIC?= =?UTF-8?q?AL]=20Fix=20SQL=20injection=20in=20mobile=20commands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ovasylenko <3797513+ovasylenko@users.noreply.github.com> --- orch8-storage/src/postgres/mobile_sync.rs | 20 ++++++++------------ orch8-storage/src/sqlite/mod.rs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/orch8-storage/src/postgres/mobile_sync.rs b/orch8-storage/src/postgres/mobile_sync.rs index 31b48e8c..c43f08c2 100644 --- a/orch8-storage/src/postgres/mobile_sync.rs +++ b/orch8-storage/src/postgres/mobile_sync.rs @@ -571,20 +571,16 @@ impl crate::MobileSyncStore for PostgresStorage { if command_ids.is_empty() { return Ok(0); } - let placeholders: Vec = command_ids - .iter() - .enumerate() - .map(|(i, _)| format!("${}", i + 2)) - .collect(); - let sql = format!( - "UPDATE mobile_commands SET acked_at = now() WHERE device_id = $1 AND id IN ({})", - placeholders.join(",") - ); - let mut query = sqlx::query(&sql).bind(device_id); + let mut qb = sqlx::QueryBuilder::new("UPDATE mobile_commands SET acked_at = now() WHERE device_id = "); + qb.push_bind(device_id); + qb.push(" AND id IN ("); + let mut separated = qb.separated(", "); for id in command_ids { - query = query.bind(id); + separated.push_bind(id); } - let result = query + separated.push_unseparated(")"); + + let result = qb.build() .execute(&self.pool) .await .map_err(|e| StorageError::Query(e.to_string()))?; diff --git a/orch8-storage/src/sqlite/mod.rs b/orch8-storage/src/sqlite/mod.rs index d09fc9c3..93063f99 100644 --- a/orch8-storage/src/sqlite/mod.rs +++ b/orch8-storage/src/sqlite/mod.rs @@ -2617,16 +2617,16 @@ impl crate::MobileSyncStore for SqliteStorage { if command_ids.is_empty() { return Ok(0); } - let placeholders: Vec<&str> = command_ids.iter().map(|_| "?").collect(); - let sql = format!( - "UPDATE mobile_commands SET acked_at = datetime('now') WHERE device_id = ? AND id IN ({})", - placeholders.join(",") - ); - let mut query = sqlx::query(&sql).bind(device_id); + let mut qb = sqlx::QueryBuilder::new("UPDATE mobile_commands SET acked_at = datetime('now') WHERE device_id = "); + qb.push_bind(device_id); + qb.push(" AND id IN ("); + let mut separated = qb.separated(", "); for id in command_ids { - query = query.bind(id); + separated.push_bind(id); } - let result = query + separated.push_unseparated(")"); + + let result = qb.build() .execute(&self.pool) .await .map_err(|e| StorageError::Query(e.to_string()))?; From 653a447a23ef9f0c1d54cbe5fa45451559031404 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:47:12 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITIC?= =?UTF-8?q?AL]=20Fix=20SQL=20injection=20in=20mobile=20commands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ovasylenko <3797513+ovasylenko@users.noreply.github.com> --- orch8-api/src/instances.rs | 2 +- orch8-storage/src/postgres/mobile_sync.rs | 7 +++++-- orch8-storage/src/sqlite/mod.rs | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/orch8-api/src/instances.rs b/orch8-api/src/instances.rs index 5deb4e0c..1b492fd9 100644 --- a/orch8-api/src/instances.rs +++ b/orch8-api/src/instances.rs @@ -29,12 +29,12 @@ pub(crate) use bulk::{ __path_bulk_reschedule, __path_bulk_update_state, __path_list_dlq, bulk_reschedule, bulk_update_state, list_dlq, }; +pub use checkpoints::{PruneCheckpointsRequest, SaveCheckpointRequest}; pub(crate) use checkpoints::{ __path_get_latest_checkpoint, __path_list_checkpoints, __path_prune_checkpoints, __path_save_checkpoint, get_latest_checkpoint, list_checkpoints, prune_checkpoints, save_checkpoint, }; -pub use checkpoints::{PruneCheckpointsRequest, SaveCheckpointRequest}; pub use inject::InjectBlocksRequest; pub(crate) use inject::{__path_inject_blocks, inject_blocks}; pub(crate) use lifecycle::{ diff --git a/orch8-storage/src/postgres/mobile_sync.rs b/orch8-storage/src/postgres/mobile_sync.rs index c43f08c2..4cc05497 100644 --- a/orch8-storage/src/postgres/mobile_sync.rs +++ b/orch8-storage/src/postgres/mobile_sync.rs @@ -571,7 +571,9 @@ impl crate::MobileSyncStore for PostgresStorage { if command_ids.is_empty() { return Ok(0); } - let mut qb = sqlx::QueryBuilder::new("UPDATE mobile_commands SET acked_at = now() WHERE device_id = "); + let mut qb = sqlx::QueryBuilder::new( + "UPDATE mobile_commands SET acked_at = now() WHERE device_id = ", + ); qb.push_bind(device_id); qb.push(" AND id IN ("); let mut separated = qb.separated(", "); @@ -580,7 +582,8 @@ impl crate::MobileSyncStore for PostgresStorage { } separated.push_unseparated(")"); - let result = qb.build() + let result = qb + .build() .execute(&self.pool) .await .map_err(|e| StorageError::Query(e.to_string()))?; diff --git a/orch8-storage/src/sqlite/mod.rs b/orch8-storage/src/sqlite/mod.rs index 93063f99..19e65146 100644 --- a/orch8-storage/src/sqlite/mod.rs +++ b/orch8-storage/src/sqlite/mod.rs @@ -2617,7 +2617,9 @@ impl crate::MobileSyncStore for SqliteStorage { if command_ids.is_empty() { return Ok(0); } - let mut qb = sqlx::QueryBuilder::new("UPDATE mobile_commands SET acked_at = datetime('now') WHERE device_id = "); + let mut qb = sqlx::QueryBuilder::new( + "UPDATE mobile_commands SET acked_at = datetime('now') WHERE device_id = ", + ); qb.push_bind(device_id); qb.push(" AND id IN ("); let mut separated = qb.separated(", "); @@ -2626,7 +2628,8 @@ impl crate::MobileSyncStore for SqliteStorage { } separated.push_unseparated(")"); - let result = qb.build() + let result = qb + .build() .execute(&self.pool) .await .map_err(|e| StorageError::Query(e.to_string()))?; From 07278aa1c4bce2c896154aaee2c19c94261a8655 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:58:39 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITIC?= =?UTF-8?q?AL]=20Fix=20SQL=20injection=20in=20mobile=20commands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ovasylenko <3797513+ovasylenko@users.noreply.github.com> From b0c5fab4b5455975458ff1770351b93145af82cb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2026 20:44:29 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITIC?= =?UTF-8?q?AL]=20Fix=20SQL=20injection=20in=20mobile=20commands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ovasylenko <3797513+ovasylenko@users.noreply.github.com>