security: fix query expansion issues from PR review
All checks were successful
Test / rust-fmt-check (pull_request) Successful in 12s
Test / frontend-typecheck (pull_request) Successful in 1m11s
Test / frontend-tests (pull_request) Successful in 1m16s
PR Review Automation / review (pull_request) Successful in 3m0s
Test / rust-clippy (pull_request) Successful in 3m50s
Test / rust-tests (pull_request) Successful in 5m0s

- Use MAX_EXPANDED_QUERIES constant in confluence_search.rs instead of hardcoded 3
- Improve escape_wiql() to escape more dangerous characters: ", \, (, ), ~, *, ?, ;, =
- Fix logging to show expanded_query instead of search_url in confluence_search.rs

All tests pass (142/142), cargo fmt and clippy pass.
This commit is contained in:
Shaun Arman 2026-04-14 20:07:59 -05:00
parent 5b45c6c418
commit 708e1e9c18
2 changed files with 14 additions and 2 deletions

View File

@ -5,6 +5,15 @@ const MAX_EXPANDED_QUERIES: usize = 3;
fn escape_wiql(s: &str) -> String { fn escape_wiql(s: &str) -> String {
s.replace('\'', "''") s.replace('\'', "''")
.replace('"', "\\\"")
.replace('\\', "\\\\")
.replace('(', "\\(")
.replace(')', "\\)")
.replace('~', "\\~")
.replace('*', "\\*")
.replace('?', "\\?")
.replace(';', "\\;")
.replace('=', "\\=")
} }
/// Search Azure DevOps Wiki for content matching the query /// Search Azure DevOps Wiki for content matching the query

View File

@ -57,7 +57,10 @@ pub async fn search_confluence(
urlencoding::encode(&safe_query) urlencoding::encode(&safe_query)
); );
tracing::info!("Searching Confluence with expanded query: {}", search_url); tracing::info!(
"Searching Confluence with expanded query: {}",
expanded_query
);
let resp = client let resp = client
.get(&search_url) .get(&search_url)
@ -80,7 +83,7 @@ pub async fn search_confluence(
.map_err(|e| format!("Failed to parse Confluence search response: {e}"))?; .map_err(|e| format!("Failed to parse Confluence search response: {e}"))?;
if let Some(results_array) = json["results"].as_array() { if let Some(results_array) = json["results"].as_array() {
for item in results_array.iter().take(3) { for item in results_array.iter().take(MAX_EXPANDED_QUERIES) {
let title = item["title"].as_str().unwrap_or("Untitled").to_string(); let title = item["title"].as_str().unwrap_or("Untitled").to_string();
let id = item["content"]["id"].as_str(); let id = item["content"]["id"].as_str();