fix(memory-ruvector): address code review security and robustness issues
- Add Cypher injection protection: validate relationship type is alphanumeric - Fix metadata type coercion: use nullish coalescing for optional fields - Add pattern centroid validation: skip malformed patterns in boosting - Add debug logging to silent catches for better troubleshooting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b0b54d0fcd
commit
a5a42ed3e2
@ -283,15 +283,15 @@ export class RuvectorDatabase implements RuvectorDB {
|
||||
.map((r) => ({
|
||||
document: {
|
||||
id: r.id,
|
||||
content: r.metadata.content as string,
|
||||
content: (r.metadata.content as string | undefined) ?? "",
|
||||
vector: [], // Don't return vector to save memory
|
||||
direction: r.metadata.direction as "inbound" | "outbound",
|
||||
channel: r.metadata.channel as string,
|
||||
direction: (r.metadata.direction as "inbound" | "outbound" | undefined) ?? "inbound",
|
||||
channel: (r.metadata.channel as string | undefined) ?? "",
|
||||
user: r.metadata.user as string | undefined,
|
||||
conversationId: r.metadata.conversationId as string | undefined,
|
||||
sessionKey: r.metadata.sessionKey as string | undefined,
|
||||
agentId: r.metadata.agentId as string | undefined,
|
||||
timestamp: r.metadata.timestamp as number,
|
||||
timestamp: (r.metadata.timestamp as number | undefined) ?? Date.now(),
|
||||
metadata: r.metadata,
|
||||
},
|
||||
score: r.score,
|
||||
@ -457,6 +457,11 @@ export class RuvectorDatabase implements RuvectorDB {
|
||||
return this.findRelatedInMemory(id, relationship, depth);
|
||||
}
|
||||
|
||||
// Validate relationship to prevent Cypher injection (allow alphanumeric and underscore only)
|
||||
if (relationship && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(relationship)) {
|
||||
throw new Error(`ruvector: invalid relationship type "${relationship}" - must be alphanumeric`);
|
||||
}
|
||||
|
||||
// Use Cypher to find related nodes with their properties
|
||||
const cypherQuery = relationship
|
||||
? `MATCH (a)-[r:${relationship}*1..${depth}]->(b:Message) WHERE a.id = $id RETURN DISTINCT b`
|
||||
|
||||
@ -592,8 +592,10 @@ function registerLocalMode(api: ClawdbotPluginApi, config: RuvectorConfig): void
|
||||
source: "graph",
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// Skip graph expansion errors
|
||||
} catch (err) {
|
||||
// Skip graph expansion errors but log for debugging
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
api.logger.debug?.(`ruvector_recall: graph expansion failed: ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,8 +774,10 @@ function registerLocalMode(api: ClawdbotPluginApi, config: RuvectorConfig): void
|
||||
try {
|
||||
const created = await graphDb.linkMessages(id, targetId, "RELATED_TO");
|
||||
if (created) edgesCreated++;
|
||||
} catch {
|
||||
// Skip failed edges
|
||||
} catch (err) {
|
||||
// Skip failed edges but log for debugging
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
api.logger.debug?.(`ruvector_learn: failed to create edge to ${targetId}: ${msg}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1294,8 +1298,14 @@ function rerankWithPatterns(
|
||||
for (const pattern of similarPatterns) {
|
||||
// Pattern centroid contains [query, result], extract result portion
|
||||
const dim = queryVector.length;
|
||||
// Validate centroid has expected structure before slicing
|
||||
if (pattern.centroid.length < dim * 2) {
|
||||
continue; // Skip malformed pattern
|
||||
}
|
||||
const patternResultCentroid = pattern.centroid.slice(dim, dim * 2);
|
||||
|
||||
// result.document.vector is intentionally [] to save memory, so pattern boosting
|
||||
// only works when vectors are available (e.g., from graph expansion with vectors)
|
||||
if (patternResultCentroid.length > 0 && result.document.vector.length > 0) {
|
||||
const similarity = cosineSimilarity(result.document.vector, patternResultCentroid);
|
||||
patternBoost += similarity * pattern.avgQuality * boostFactor;
|
||||
|
||||
@ -603,8 +603,10 @@ export function createRuvectorRecallTool(options: CreateRuvectorRecallToolOption
|
||||
relationship,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// Skip entries that can't be fetched
|
||||
} catch (err) {
|
||||
// Skip entries that can't be fetched but log for debugging
|
||||
const errMsg = err instanceof Error ? err.message : String(err);
|
||||
api.logger.debug?.(`ruvector_recall: failed to fetch graph entry ${id}: ${errMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user