mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 18:04:32 +00:00
Security: use crypto.randomBytes for temp file names (#20654)
Replace Math.random() with crypto.randomBytes() for generating temporary file names. Math.random() is predictable and can enable TOCTOU race conditions. Also set mode 0o600 on TTS temp files. Co-authored-by: sirishacyd <sirishacyd@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,8 @@ async function pruneIfNeeded(filePath: string, opts: { maxBytes: number; keepLin
|
|||||||
.map((l) => l.trim())
|
.map((l) => l.trim())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
const kept = lines.slice(Math.max(0, lines.length - opts.keepLines));
|
const kept = lines.slice(Math.max(0, lines.length - opts.keepLines));
|
||||||
const tmp = `${filePath}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
|
const { randomBytes } = await import("node:crypto");
|
||||||
|
const tmp = `${filePath}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
|
||||||
await fs.writeFile(tmp, `${kept.join("\n")}\n`, "utf-8");
|
await fs.writeFile(tmp, `${kept.join("\n")}\n`, "utf-8");
|
||||||
await fs.rename(tmp, filePath);
|
await fs.rename(tmp, filePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ export async function loadCronStore(storePath: string): Promise<CronStoreFile> {
|
|||||||
|
|
||||||
export async function saveCronStore(storePath: string, store: CronStoreFile) {
|
export async function saveCronStore(storePath: string, store: CronStoreFile) {
|
||||||
await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
|
await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
|
||||||
const tmp = `${storePath}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
|
const { randomBytes } = await import("node:crypto");
|
||||||
|
const tmp = `${storePath}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
|
||||||
const json = JSON.stringify(store, null, 2);
|
const json = JSON.stringify(store, null, 2);
|
||||||
await fs.promises.writeFile(tmp, json, "utf-8");
|
await fs.promises.writeFile(tmp, json, "utf-8");
|
||||||
await fs.promises.rename(tmp, storePath);
|
await fs.promises.rename(tmp, storePath);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { randomBytes } from "node:crypto";
|
||||||
import {
|
import {
|
||||||
existsSync,
|
existsSync,
|
||||||
mkdirSync,
|
mkdirSync,
|
||||||
@@ -382,8 +383,8 @@ function readPrefs(prefsPath: string): TtsUserPrefs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function atomicWriteFileSync(filePath: string, content: string): void {
|
function atomicWriteFileSync(filePath: string, content: string): void {
|
||||||
const tmpPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
const tmpPath = `${filePath}.tmp.${Date.now()}.${randomBytes(8).toString("hex")}`;
|
||||||
writeFileSync(tmpPath, content);
|
writeFileSync(tmpPath, content, { mode: 0o600 });
|
||||||
try {
|
try {
|
||||||
renameSync(tmpPath, filePath);
|
renameSync(tmpPath, filePath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user