fix(security): resolve all HIGH/MEDIUM/LOW audit findings
Rust fixes (HIGH): - symbols.rs: path validation (reject near-root, 50K file limit, symlink filter) - memory.rs: FTS5 query quoting (prevent operator injection), 1000 fragment cap, content length limit, transaction wrapping - budget.rs: atomic check-and-reserve via transaction, input validation, index on budget_log - export.rs: safe UTF-8 truncation via chars().take() - git_context.rs: reject paths starting with '-' (flag injection) - branch_policy.rs: action validation (block|warn only), path validation Rust fixes (MEDIUM): - export.rs: named column access (positional→named) - budget.rs: named column access, negative value guards Svelte fixes: - AccountSwitcher: 2-step confirmation before account switch - ProjectMemory: expand/collapse content, 2-step delete confirm, tags split fix - CodeIntelligence: min 2-char symbol query, CodeSymbol rename, aria-labels - BudgetManager: 10M upper bound, aria-label on input, named constants - SessionExporter: timeout cleanup on destroy, aria-live feedback - AnalyticsDashboard: SVG aria-label, removed unused import, named constant
This commit is contained in:
parent
0324f813e2
commit
738574b9f0
13 changed files with 280 additions and 91 deletions
|
|
@ -35,7 +35,7 @@ fn ensure_tables(conn: &rusqlite::Connection) -> Result<(), String> {
|
|||
|
||||
// Seed default policies if table is empty
|
||||
let count: i64 = conn.query_row(
|
||||
"SELECT COUNT(*) FROM pro_branch_policies", [], |row| row.get(0)
|
||||
"SELECT COUNT(*) AS cnt FROM pro_branch_policies", [], |row| row.get("cnt")
|
||||
).unwrap_or(0);
|
||||
|
||||
if count == 0 {
|
||||
|
|
@ -62,6 +62,9 @@ fn glob_match(pattern: &str, value: &str) -> bool {
|
|||
}
|
||||
|
||||
fn get_current_branch(project_path: &str) -> Result<String, String> {
|
||||
if project_path.starts_with('-') {
|
||||
return Err("Invalid project path: cannot start with '-'".into());
|
||||
}
|
||||
let output = Command::new("git")
|
||||
.args(["-C", project_path, "branch", "--show-current"])
|
||||
.output()
|
||||
|
|
@ -87,10 +90,10 @@ pub fn pro_branch_check(project_path: String) -> Result<PolicyDecision, String>
|
|||
|
||||
let policies: Vec<BranchPolicy> = stmt.query_map([], |row| {
|
||||
Ok(BranchPolicy {
|
||||
id: row.get(0)?,
|
||||
pattern: row.get(1)?,
|
||||
action: row.get(2)?,
|
||||
reason: row.get(3)?,
|
||||
id: row.get("id")?,
|
||||
pattern: row.get("pattern")?,
|
||||
action: row.get("action")?,
|
||||
reason: row.get("reason")?,
|
||||
})
|
||||
}).map_err(|e| format!("Query failed: {e}"))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
|
|
@ -127,10 +130,10 @@ pub fn pro_branch_policy_list() -> Result<Vec<BranchPolicy>, String> {
|
|||
|
||||
let rows = stmt.query_map([], |row| {
|
||||
Ok(BranchPolicy {
|
||||
id: row.get(0)?,
|
||||
pattern: row.get(1)?,
|
||||
action: row.get(2)?,
|
||||
reason: row.get(3)?,
|
||||
id: row.get("id")?,
|
||||
pattern: row.get("pattern")?,
|
||||
action: row.get("action")?,
|
||||
reason: row.get("reason")?,
|
||||
})
|
||||
}).map_err(|e| format!("Query failed: {e}"))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
|
|
@ -144,6 +147,9 @@ pub fn pro_branch_policy_add(pattern: String, action: Option<String>, reason: Op
|
|||
let conn = super::open_sessions_db()?;
|
||||
ensure_tables(&conn)?;
|
||||
let act = action.unwrap_or_else(|| "block".into());
|
||||
if !["block", "warn"].contains(&act.as_str()) {
|
||||
return Err(format!("Invalid action '{}': must be 'block' or 'warn'", act));
|
||||
}
|
||||
let rsn = reason.unwrap_or_default();
|
||||
conn.execute(
|
||||
"INSERT INTO pro_branch_policies (pattern, action, reason) VALUES (?1, ?2, ?3)",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue