fix(security): remediate unassigned CodeQL findings

- harden URL/request handling for composio and whatsapp integrations
- reduce cleartext logging exposure across providers/tools/gateway
- hash and constant-time compare gateway webhook secrets
- expand nested secret encryption coverage in config
- align feature aliases and add regression tests for security paths
- fix bubblewrap all-features test invocation surfaced during deep validation
This commit is contained in:
Chummy 2026-02-17 15:44:41 +08:00
parent f9d681063d
commit 1711f140be
14 changed files with 481 additions and 146 deletions

View file

@ -10,7 +10,7 @@ use uuid::Uuid;
/// happens in the gateway when Meta sends webhook events.
pub struct WhatsAppChannel {
access_token: String,
phone_number_id: String,
endpoint_id: String,
verify_token: String,
allowed_numbers: Vec<String>,
client: reqwest::Client,
@ -19,13 +19,13 @@ pub struct WhatsAppChannel {
impl WhatsAppChannel {
pub fn new(
access_token: String,
phone_number_id: String,
endpoint_id: String,
verify_token: String,
allowed_numbers: Vec<String>,
) -> Self {
Self {
access_token,
phone_number_id,
endpoint_id,
verify_token,
allowed_numbers,
client: reqwest::Client::new(),
@ -142,7 +142,7 @@ impl Channel for WhatsAppChannel {
// WhatsApp Cloud API: POST to /v18.0/{phone_number_id}/messages
let url = format!(
"https://graph.facebook.com/v18.0/{}/messages",
self.phone_number_id
self.endpoint_id
);
// Normalize recipient (remove leading + if present for API)
@ -162,7 +162,7 @@ impl Channel for WhatsAppChannel {
let resp = self
.client
.post(&url)
.header("Authorization", format!("Bearer {}", self.access_token))
.bearer_auth(&self.access_token)
.header("Content-Type", "application/json")
.json(&body)
.send()
@ -195,11 +195,11 @@ impl Channel for WhatsAppChannel {
async fn health_check(&self) -> bool {
// Check if we can reach the WhatsApp API
let url = format!("https://graph.facebook.com/v18.0/{}", self.phone_number_id);
let url = format!("https://graph.facebook.com/v18.0/{}", self.endpoint_id);
self.client
.get(&url)
.header("Authorization", format!("Bearer {}", self.access_token))
.bearer_auth(&self.access_token)
.send()
.await
.map(|r| r.status().is_success())