Files
mem0/integrations/openclaw/skill-loader.test.ts
T

71 lines
2.4 KiB
TypeScript

/**
* Tests for path traversal prevention in skill-loader.
*/
import { describe, it, expect } from "vitest";
import { safePath, loadSkill } from "./skill-loader.ts";
// ---------------------------------------------------------------------------
// safePath — path containment
// ---------------------------------------------------------------------------
describe("safePath", () => {
it("rejects parent directory traversal", () => {
expect(safePath("../../etc/passwd")).toBeNull();
});
it("rejects deep traversal", () => {
expect(safePath("../../../etc/shadow")).toBeNull();
});
it("rejects traversal in nested segment", () => {
expect(safePath("valid", "../../etc")).toBeNull();
});
it("rejects bare '..' as segment", () => {
expect(safePath("..")).toBeNull();
});
it("accepts valid skill paths", () => {
expect(safePath("memory-triage", "SKILL.md")).not.toBeNull();
});
it("accepts valid domain overlay paths", () => {
expect(safePath("memory-triage", "domains", "companion.md")).not.toBeNull();
});
it("returns null for empty segments that resolve to skills root with subpath escape", () => {
// path.resolve("skills", "", "../../etc") still escapes
expect(safePath("", "../../etc")).toBeNull();
});
it("rejects traversal disguised with valid prefix", () => {
expect(safePath("memory-triage/../../etc/passwd")).toBeNull();
});
});
// ---------------------------------------------------------------------------
// loadSkill — integration tests for traversal prevention
// ---------------------------------------------------------------------------
describe("loadSkill path traversal", () => {
it("returns null for traversal skillName", () => {
expect(loadSkill("../../etc/passwd")).toBeNull();
});
it("returns null for deep traversal skillName", () => {
expect(loadSkill("../../../..")).toBeNull();
});
it("loads a valid skill", () => {
const result = loadSkill("memory-triage");
expect(result).not.toBeNull();
expect(result?.prompt).toBeTruthy();
});
it("blocks domain traversal while loading valid skill", () => {
// Valid skill name, malicious domain — should load skill but skip the overlay
const result = loadSkill("memory-triage", { domain: "../../etc/passwd" });
// Should still succeed (skill itself is valid), domain overlay is just skipped
expect(result).not.toBeNull();
expect(result?.prompt).toBeTruthy();
});
});