feat(security): gate public-registry plugin installs + sandbox the runner unit
Supply chain: resolvePackage() used to pass any punktfunk-plugin-* or foreign-scope name straight to bun add — a typo or a squatted look-alike on npmjs.org would install operator-privileged code. Only the @punktfunk scope (pinned to the Gitea registry by the bunfig scope map) resolves by default now; anything else throws with an explanation unless --allow-public-registry is passed, and even then installs print a loud warning. Removal never gates — uninstalling stays safe regardless of origin. systemd (user unit): free hardening for well-behaved plugins — NoNewPrivileges, PrivateTmp, ProtectSystem=strict with ReadWritePaths=%h (plugin state and download dirs under $HOME keep working), and RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6. Plugins writing outside $HOME, and distros that restrict unprivileged user namespaces for user units, are handled via a documented systemctl --user edit drop-in. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,12 +37,28 @@ describe("resolvePackage", () => {
|
||||
expect(resolvePackage("rom-manager")).toBe("@punktfunk/plugin-rom-manager");
|
||||
});
|
||||
|
||||
test("passes through scoped, unscoped-convention, and pathed names verbatim", () => {
|
||||
test("passes @punktfunk-scoped names through verbatim (our registry, no gate)", () => {
|
||||
expect(resolvePackage("@punktfunk/plugin-playnite")).toBe(
|
||||
"@punktfunk/plugin-playnite",
|
||||
);
|
||||
expect(resolvePackage("@someone/plugin-x")).toBe("@someone/plugin-x");
|
||||
expect(resolvePackage("punktfunk-plugin-custom")).toBe("punktfunk-plugin-custom");
|
||||
});
|
||||
|
||||
test("refuses public-registry names without allowPublicRegistry", () => {
|
||||
expect(() => resolvePackage("punktfunk-plugin-custom")).toThrow(
|
||||
/public/i,
|
||||
);
|
||||
expect(() => resolvePackage("@someone/plugin-x")).toThrow(/public/i);
|
||||
expect(() => resolvePackage("some/registry-path")).toThrow(/public/i);
|
||||
});
|
||||
|
||||
test("passes public-registry names through with allowPublicRegistry", () => {
|
||||
const allow = { allowPublicRegistry: true };
|
||||
expect(resolvePackage("punktfunk-plugin-custom", allow)).toBe(
|
||||
"punktfunk-plugin-custom",
|
||||
);
|
||||
expect(resolvePackage("@someone/plugin-x", allow)).toBe(
|
||||
"@someone/plugin-x",
|
||||
);
|
||||
});
|
||||
|
||||
test("trims and rejects empty", () => {
|
||||
|
||||
Reference in New Issue
Block a user