mirror of https://github.com/openclaw/openclaw.git
fix: harden state dir permissions during onboard
This commit is contained in:
parent
ebed3bbde1
commit
7e3787517f
|
|
@ -164,6 +164,32 @@ function hashConfigRaw(raw: string | null): string {
|
|||
.digest("hex");
|
||||
}
|
||||
|
||||
async function tightenStateDirPermissionsIfNeeded(params: {
|
||||
configPath: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
homedir: () => string;
|
||||
fsModule: typeof fs;
|
||||
}): Promise<void> {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const stateDir = resolveStateDir(params.env, params.homedir);
|
||||
const configDir = path.dirname(params.configPath);
|
||||
if (path.resolve(configDir) !== path.resolve(stateDir)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stat = await params.fsModule.promises.stat(configDir);
|
||||
const mode = stat.mode & 0o777;
|
||||
if ((mode & 0o077) === 0) {
|
||||
return;
|
||||
}
|
||||
await params.fsModule.promises.chmod(configDir, 0o700);
|
||||
} catch {
|
||||
// Best-effort hardening only; callers still need the config write to proceed.
|
||||
}
|
||||
}
|
||||
|
||||
function formatConfigValidationFailure(pathLabel: string, issueMessage: string): string {
|
||||
const match = issueMessage.match(OPEN_DM_POLICY_ALLOW_FROM_RE);
|
||||
const policyPath = match?.groups?.policyPath?.trim();
|
||||
|
|
@ -1136,6 +1162,12 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||
|
||||
const dir = path.dirname(configPath);
|
||||
await deps.fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
||||
await tightenStateDirPermissionsIfNeeded({
|
||||
configPath,
|
||||
env: deps.env,
|
||||
homedir: deps.homedir,
|
||||
fsModule: deps.fs,
|
||||
});
|
||||
const outputConfigBase =
|
||||
envRefMap && changedPaths
|
||||
? (restoreEnvRefsFromMap(cfgToWrite, "", envRefMap, changedPaths) as OpenClawConfig)
|
||||
|
|
|
|||
|
|
@ -142,6 +142,28 @@ describe("config io write", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"tightens world-writable state dir when writing the default config",
|
||||
async () => {
|
||||
await withSuiteHome(async (home) => {
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
await fs.mkdir(stateDir, { recursive: true, mode: 0o777 });
|
||||
await fs.chmod(stateDir, 0o777);
|
||||
|
||||
const io = createConfigIO({
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
homedir: () => home,
|
||||
logger: silentLogger,
|
||||
});
|
||||
|
||||
await io.writeConfigFile({ gateway: { mode: "local" } });
|
||||
|
||||
const stat = await fs.stat(stateDir);
|
||||
expect(stat.mode & 0o777).toBe(0o700);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it('shows actionable guidance for dmPolicy="open" without wildcard allowFrom', async () => {
|
||||
await withSuiteHome(async (home) => {
|
||||
const io = createConfigIO({
|
||||
|
|
|
|||
Loading…
Reference in New Issue