fix(worker): contain workspace paths against symlinks
This commit is contained in:
@@ -7,6 +7,7 @@ import type { Id } from '@spoon/backend/convex/_generated/dataModel.js';
|
||||
import { api } from '@spoon/backend/convex/_generated/api.js';
|
||||
|
||||
import { env } from './env';
|
||||
import { assertContainedRealPath } from './path-containment';
|
||||
import { runExecInContainer } from './runtime/docker';
|
||||
|
||||
const client = new ConvexHttpClient(env.convexUrl);
|
||||
@@ -31,16 +32,6 @@ export const fetchUserEnvironment = async (
|
||||
|
||||
const shellQuote = (value: string) => `'${value.replaceAll("'", "'\\''")}'`;
|
||||
|
||||
// Keep a written path inside the home directory.
|
||||
const safeHomeJoin = (homeDir: string, relPath: string) => {
|
||||
const target = path.resolve(homeDir, relPath);
|
||||
const root = path.resolve(homeDir);
|
||||
if (target !== root && !target.startsWith(`${root}${path.sep}`)) {
|
||||
throw new Error(`Refusing to write dotfile outside home: ${relPath}`);
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
/**
|
||||
* Materializes the persistent per-user home: a `.bash_profile` so login shells
|
||||
* load `~/.bashrc`; (when configured and changed) a clone of the public dotfiles
|
||||
@@ -111,7 +102,9 @@ export const materializeUserHome = async (args: {
|
||||
|
||||
// Editable overlay tree (wins over the repo/setup output).
|
||||
for (const file of userEnv.files) {
|
||||
const target = safeHomeJoin(homeDir, file.path);
|
||||
const target = await assertContainedRealPath(homeDir, file.path, {
|
||||
forWrite: true,
|
||||
});
|
||||
await mkdir(path.dirname(target), { recursive: true });
|
||||
await writeFile(target, file.content);
|
||||
if (file.isExecutable) await chmod(target, 0o755);
|
||||
|
||||
Reference in New Issue
Block a user