mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-22 14:25:24 +02:00
fix(security): redact SSH private key from server read responses
findServerById eagerly loads the sshKey relation (needed for server-side SSH operations) including the plaintext privateKey. server.one and server.remove returned that record to the client, exposing the private key to any member with server:read regardless of canAccessToSSHKeys. Adds redactServerSshKey() in the server service and applies it to the server.one and server.remove responses. No client feature consumes the private key (the SSH key management UI uses the dedicated sshKey router), and server-side callers keep using findServerById directly, so behaviour is unchanged. Closes GHSA-w9cp-jqfw-4xj9
This commit is contained in:
43
apps/dokploy/__test__/server/server-sshkey-redaction.test.ts
Normal file
43
apps/dokploy/__test__/server/server-sshkey-redaction.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { redactServerSshKey } from "@dokploy/server/services/server";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("redactServerSshKey (server SSH private key disclosure guard)", () => {
|
||||
it("blanks the private key while keeping the rest of the ssh key intact", () => {
|
||||
const server = {
|
||||
serverId: "srv-1",
|
||||
name: "prod",
|
||||
sshKey: {
|
||||
sshKeyId: "key-1",
|
||||
publicKey: "ssh-ed25519 AAAA...",
|
||||
privateKey: "-----BEGIN OPENSSH PRIVATE KEY-----\nsecret\n",
|
||||
},
|
||||
};
|
||||
|
||||
const redacted = redactServerSshKey(server);
|
||||
|
||||
expect(redacted.sshKey.privateKey).toBe("");
|
||||
// Non-secret fields and the surrounding record must survive untouched.
|
||||
expect(redacted.sshKey.publicKey).toBe("ssh-ed25519 AAAA...");
|
||||
expect(redacted.serverId).toBe("srv-1");
|
||||
expect(redacted.name).toBe("prod");
|
||||
});
|
||||
|
||||
it("does not mutate the original record", () => {
|
||||
const server = {
|
||||
serverId: "srv-1",
|
||||
sshKey: { privateKey: "top-secret" },
|
||||
};
|
||||
redactServerSshKey(server);
|
||||
expect(server.sshKey.privateKey).toBe("top-secret");
|
||||
});
|
||||
|
||||
it("is a no-op when the server has no ssh key", () => {
|
||||
const server = { serverId: "srv-2", sshKey: null };
|
||||
expect(redactServerSshKey(server)).toEqual(server);
|
||||
});
|
||||
|
||||
it("handles a record without an sshKey property at all", () => {
|
||||
const server = { serverId: "srv-3" };
|
||||
expect(redactServerSshKey(server)).toEqual(server);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user