mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-12 19:51:00 +05:00
fix: harden rclone environment and credential redaction
This commit is contained in:
parent
5ab6b0701d
commit
27140c93d2
@ -2,6 +2,7 @@ import {
|
||||
getSafeRcloneErrorMessage,
|
||||
redactRcloneCredentials,
|
||||
} from "@dokploy/server/utils/backups/redact";
|
||||
import { quote } from "shell-quote";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("redactRcloneCredentials (#4621)", () => {
|
||||
@ -84,4 +85,15 @@ describe("redactRcloneCredentials (#4621)", () => {
|
||||
}
|
||||
expect(safe.match(/\[REDACTED\]/g)?.length).toBe(5);
|
||||
});
|
||||
it("should fully redact shell-quote output with embedded quotes and whitespace", () => {
|
||||
const secret = "PART_A' PART_B\" $PART_C;\\PART_D";
|
||||
const cmd = `rclone lsf --s3-secret-access-key=${quote([secret])} --s3-region=us-east-1 :s3:bucket`;
|
||||
const redacted = redactRcloneCredentials(cmd);
|
||||
|
||||
for (const fragment of ["PART_A", "PART_B", "PART_C", "PART_D"]) {
|
||||
expect(redacted).not.toContain(fragment);
|
||||
}
|
||||
expect(redacted).toContain('--s3-secret-access-key="[REDACTED]"');
|
||||
expect(redacted).toContain("--s3-region=us-east-1");
|
||||
});
|
||||
});
|
||||
|
||||
@ -407,4 +407,21 @@ describe("FTP TLS certificate verification", () => {
|
||||
}).success,
|
||||
).toBe(true);
|
||||
});
|
||||
test("forces certificate verification on after user flags", async () => {
|
||||
const result = await getRclonePathAndFlags(
|
||||
destination({
|
||||
provider: RCLONE_DESTINATION_PROVIDERS.FTP,
|
||||
endpoint: "storage.example.com",
|
||||
accessKey: "backup-user",
|
||||
secretAccessKey: "",
|
||||
region: "",
|
||||
bucket: "backups",
|
||||
additionalFlags: ["--ftp-explicit-tls"],
|
||||
}),
|
||||
);
|
||||
expect(result.flags.slice(-2)).toEqual([
|
||||
"--ftp-no-check-certificate=false",
|
||||
"--no-check-certificate=false",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
*/
|
||||
export const redactRcloneCredentials = (command: string): string => {
|
||||
return command.replace(
|
||||
/(--(?:s3-access-key-id|s3-secret-access-key|ftp-pass|sftp-pass|sftp-key-file-pass)=)(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|[^\s]+)/g,
|
||||
/(--(?:s3-access-key-id|s3-secret-access-key|ftp-pass|sftp-pass|sftp-key-file-pass)=)(?:(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\\[^\r\n]|[^\s"'\\])+)/g,
|
||||
'$1"[REDACTED]"',
|
||||
);
|
||||
};
|
||||
|
||||
@ -197,6 +197,14 @@ export const getRclonePathAndFlags = async (
|
||||
flags.push(`--${backend}-pass=${quote([obscuredPassword])}`);
|
||||
}
|
||||
flags.push(...additionalFlags);
|
||||
if (provider === RCLONE_DESTINATION_PROVIDERS.FTP) {
|
||||
// CLI options override RCLONE_* environment defaults. Keep TLS
|
||||
// certificate verification enabled on the execution host.
|
||||
flags.push(
|
||||
"--ftp-no-check-certificate=false",
|
||||
"--no-check-certificate=false",
|
||||
);
|
||||
}
|
||||
return {
|
||||
flags,
|
||||
path: `:${backend}:${joinRclonePath(destination.bucket, path)}`,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user