mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-21 13:55:33 +02:00
test(security): fix type error in shell-quote op assertion
This commit is contained in:
@@ -54,19 +54,23 @@ describe("cloneGitRepository command (customGitUrl path)", () => {
|
||||
type: "application",
|
||||
});
|
||||
|
||||
// A malicious substring, once escaped, must survive parsing as inert literal
|
||||
// text and never as an executable command/operator. `parse()` turns command
|
||||
// substitution and control operators into { op } objects, so we assert the
|
||||
// injected marker only ever shows up inside a plain string token.
|
||||
const markerLeaksAsShellSyntax = (command: string, marker: string) => {
|
||||
const tokens = parse(command);
|
||||
return tokens.some(
|
||||
(t) => typeof t !== "string" && JSON.stringify(t).includes(marker),
|
||||
);
|
||||
};
|
||||
|
||||
it("does not let a malicious customGitUrl inject shell operators", async () => {
|
||||
const command = await buildClone(
|
||||
"https://github.com/o/r.git$(touch /tmp/pwned)",
|
||||
"main",
|
||||
);
|
||||
const tokens = parse(command);
|
||||
// No token in the generated command may be a shell operator carrying the
|
||||
// injected substitution (e.g. { op: "$(" }). The payload must appear only
|
||||
// as inert literal text.
|
||||
const hasCommandSubstitution = tokens.some(
|
||||
(t) => typeof t === "object" && "op" in t && t.op === "$(",
|
||||
);
|
||||
expect(hasCommandSubstitution).toBe(false);
|
||||
expect(markerLeaksAsShellSyntax(command, "touch")).toBe(false);
|
||||
expect(command).toContain("git clone");
|
||||
});
|
||||
|
||||
@@ -75,18 +79,9 @@ describe("cloneGitRepository command (customGitUrl path)", () => {
|
||||
"https://github.com/o/r.git",
|
||||
"main; touch /tmp/pwned",
|
||||
);
|
||||
const tokens = parse(command);
|
||||
const hasSemicolonOperator = tokens.some(
|
||||
(t) => typeof t === "object" && "op" in t && t.op === ";",
|
||||
);
|
||||
// The clone builder itself joins statements with ";", so at least the
|
||||
// structural ones exist — but the branch payload's ";" must NOT surface
|
||||
// as an extra operator that would run `touch`.
|
||||
const semicolonOps = tokens.filter(
|
||||
(t) => typeof t === "object" && "op" in t && t.op === ";",
|
||||
).length;
|
||||
expect(hasSemicolonOperator).toBe(true);
|
||||
// The branch is a single quoted token, so it contributes no new ";" op.
|
||||
// The branch is a single quoted token, so its ";" contributes no extra
|
||||
// operator and `touch` never becomes a runnable statement.
|
||||
expect(markerLeaksAsShellSyntax(command, "touch")).toBe(false);
|
||||
expect(command).not.toContain("touch /tmp/pwned;");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user