fix(security): SQL injection in Python/JS clients + bare except + session leak
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled

- Fix SQL injection vulnerabilities in chat_history.py, langchain_store.py,
  rag_pipeline.py, baradb_langchain.js by switching to parameterized queries
- Replace dangerous bare except: with except CatchableError:/ValueError:
  in llm.nim, embed.nim, cypher.nim, mcp/server.nim, executor.nim
- Fix session variable leak in MCP handleVectorSearch/handleSchemaInspect
- Build: 0 errors, all tests pass
This commit is contained in:
2026-05-17 16:58:05 +03:00
parent c95bc4cd44
commit 1e38e29f25
9 changed files with 227 additions and 109 deletions
+9 -9
View File
@@ -1214,7 +1214,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
let textCol = evalExpr(expr.irFuncArgs[2], row, ctx)
let queryText = evalExpr(expr.irFuncArgs[3], row, ctx)
let queryVec = evalExpr(expr.irFuncArgs[4], row, ctx)
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except: 10
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except ValueError: 10
let results = doHybridSearch(ctx, table, vecCol, textCol, queryText, queryVec, k)
var parts: seq[string] = @[]
for (id, score) in results:
@@ -1227,7 +1227,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
let textCol = evalExpr(expr.irFuncArgs[2], row, ctx)
let queryText = evalExpr(expr.irFuncArgs[3], row, ctx)
let queryVec = evalExpr(expr.irFuncArgs[4], row, ctx)
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except: 10
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except ValueError: 10
let results = doHybridSearch(ctx, table, vecCol, textCol, queryText, queryVec, k)
var ids: seq[string] = @[]
for (id, score) in results:
@@ -1240,7 +1240,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
let textCol = evalExpr(expr.irFuncArgs[2], row, ctx)
let queryText = evalExpr(expr.irFuncArgs[3], row, ctx)
let queryVec = evalExpr(expr.irFuncArgs[4], row, ctx)
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except: 10
let k = try: parseInt(evalExpr(expr.irFuncArgs[5], row, ctx)) except ValueError: 10
let filterCol = evalExpr(expr.irFuncArgs[6], row, ctx)
let filterVal = evalExpr(expr.irFuncArgs[7], row, ctx)
let results = doHybridSearchFiltered(ctx, table, vecCol, textCol, queryText, queryVec, k, filterCol, filterVal)
@@ -1260,7 +1260,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
let queryTerms = queryText.toLower().splitWhitespace()
for elem in arr:
var score = 0.0
try: score = parseFloat(elem["score"].getStr()) except: discard
try: score = parseFloat(elem["score"].getStr()) except ValueError: discard
# Simple term overlap boost
for term in queryTerms:
if term.len > 2:
@@ -1274,16 +1274,16 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
for (elem, _) in boosted:
outArr.add(elem)
return $(%* outArr)
except:
except CatchableError:
return resultsJson
of "chunk":
if expr.irFuncArgs.len < 1: return "[]"
let text = evalExpr(expr.irFuncArgs[0], row, ctx)
let maxSize = if expr.irFuncArgs.len >= 2:
try: parseInt(evalExpr(expr.irFuncArgs[1], row, ctx)) except: 1024
try: parseInt(evalExpr(expr.irFuncArgs[1], row, ctx)) except ValueError: 1024
else: 1024
let overlap = if expr.irFuncArgs.len >= 3:
try: parseInt(evalExpr(expr.irFuncArgs[2], row, ctx)) except: 128
try: parseInt(evalExpr(expr.irFuncArgs[2], row, ctx)) except ValueError: 128
else: 128
let cfg = chunkmod.ChunkConfig(maxChunkSize: maxSize, chunkOverlap: overlap,
strategy: chunkmod.csRecursive, minChunkSize: 64)
@@ -1426,7 +1426,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
if expr.irFuncArgs.len < 1: return "[]"
let graphName = evalExpr(expr.irFuncArgs[0], row, ctx)
let dims = if expr.irFuncArgs.len >= 2:
try: parseInt(evalExpr(expr.irFuncArgs[1], row, ctx)) except: 64
try: parseInt(evalExpr(expr.irFuncArgs[1], row, ctx)) except ValueError: 64
else: 64
if graphName notin ctx.graphs:
return "[]"
@@ -1514,7 +1514,7 @@ proc evalExpr*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContext =
var nodeId: int64 = 0
if expr.irFuncArgs.len > 0:
try: nodeId = parseInt(evalExpr(expr.irFuncArgs[0], row, ctx))
except: nodeId = 0
except ValueError: nodeId = 0
nodeId = nodeId and 0x3FF # 10 bits
let ts = int64(epochTime() * 1000) and 0x1FFFFFFFFFF # 41 bits
var snowSeq = int64(getMonoTime().ticks() and 0xFFF) # 12 bits from monotonic